xargs命令少为人知的细节 (Linux/Unix)
发布于 2010-04-29 11:20 阅读:61305 评论:0 标签: xargs

    与xargs命令最初相识是在发现一个磁盘满了,具体是在/var/spool/clientmqueue,主要原因是系统中有用户开启了crontab,而crontab中执行的程序有输出内容,输出内容会以邮件形式发给cron的用户,而sendmail没有启动所以就产生了这些文件。关于更详细的原理,可以参考我之前的文章:crontab命令的使用介绍及我的体会

    仅仅解决出现多文件的方法比较简单,在命令后加上“> /dev/null 2>&1”即可,表示程序员输出和运行错误都放到黑洞里面去,这样就不会产生文件了。

    如果是要解决删除多文件的问题,则进入这个文件夹,执行“ls | xargs rm -f ”即可。xargs可以从管道中循环读取文件,一次一次的把信息输送给后面的“rm -f”。

    请注意以上措辞:“一次一次的”,那么这个一次一次,是指“一个一个”还是“一批一批”呢?

    很杯具,当时不求甚解,未能深入学习xargs,误解为“一个一个”。

    最近在写一个程序时,需要处理一个文件中的行数据。平时都是使用php的fopen再fgets解决问题,但这次懒得套用这一套了,于是想使用管道把数据传送给php脚本。

    而php脚本也利用$argv这个数组来获取命令行输入的参数,那么很简单的,获取$argv[1],就可以了。如“php a.php b”,$argv[0]为文件名a.php,$argv[1]就是后面的参数b了。于是想当然的:cat uid.txt | xargs php a.php 。

    最终发现,uid.txt中有近4千行的数据,但是只处理了4行。那么,既然出现问题就边解决边学习吧!

    使用:cat uid.txt | xargs echo > file.out

    发现 file.out文件果然就是四行,但是每行都很长。。。。。

    如下,uid.txt内容为:(“......”表示很多行)

以下是引用片段:
1234567890
......
2234567890
......
3234567890
......
4234567890
......

    那么file.out的结果为:

以下是引用片段:
第一行:1234567890 ......
第二行:2234567890 ......
第三行:3234567890 ......
第四行:4234567890 ......

    所以,程序处理每一行的第一个了,剩下的全部被忽略。而我期望的结果是xargs每次给我一行。

    那么寻求man的帮助吧:

以下是引用片段:

       --max-chars=max-chars, -s max-chars
              Use at most max-chars characters per command line, including the command and initial-arguments and  the
              terminating nulls at the ends of the argument strings.  The default is 131072 characters, not including
              the size of the environment variables (which are provided for separately so that it doesn’t  matter  if
              your  environment variables take up more than 131072 bytes).  The operating system places limits on the
              values that you can usefully specify, and if you exceed these a warning  message  is  printed  and  the
              value actually used is set to the appropriate upper or lower limit. 

       --max-args=max-args, -n max-args
              Use  at  most  max-args  arguments per command line.  Fewer than max-args arguments will be used if the
              size (see the -s option) is exceeded, unless the -x option is given, in which case xargs will exit.

    首先看-s参数,它提示说每次的输出不能超过131072 bytes,从结果上看上去它每次都往最大的值释放数据。再看-n参数,提示我们可以使用这个参数指定每次从源文件中取几行数据,那么OK,搞定了!如下:cat uid.txt | xargs -n 1 php a.php。问题解决。

    更进一步的:

    1:其实每个系统对于参数列表的大小都有限制。比如ARG_MAX一般至少定义为4096 bytes。如果超过了ARG_MAX,将产生shell错误:Argument list too lang,这个问题可以用上面说的xargs命令解决问题。

    2:xargs的-s参数,根据实战的结果,貌似会在指定的值和真实数据中取得平衡,不会只依据-s指定的大小活生生的把源数据的一行撕裂成两行。

展开全文  
收起全文  
XML/RSS的CDATA区段 (扩展学习)
发布于 2010-04-16 16:58 阅读:103873 评论:0 标签: CDATA rss xml

    之前做RSS输出的程序时,用"<![CDATA[内容]]>"解决了description节点文章内容的老断点的问题。当时不甚其解,也没花时间弄明白它的原理。

    今天继续学习了一下XML的基础格式,豁然开朗。

    每种数据格式,如果要被广泛推广,被多种解析器能理解,必需要有其特定的格式,就如语法一般。

    虽然XML 和 HTML 为不同的目的而设计:

以下是引用片段:

XML 被设计为传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息,而 XML 旨在传输信息。

    但在语法上,两者有相似之处,HTML的标签都是放在“<”和“>”之间,XML也是如此。如在 XML 文档中放置了一个类似 "<" 字符,那么这个文档会产生一个错误,这是因为解析器会把它解释为新元素的开始。

    而一般文章的内容可能包含意想不到的特殊字符,尤其是技术博客。那么为了避免此类错误,XML要求我们把字符 "<" 替换为实体引用,如:

以下是代码片段:
<message>if salary &lt; 1000 then</message>


    而不是

以下是代码片段:
<message>if salary < 1000 then</message>

    那什么是实体引用呢,如下:

以下是引用片段:
在 XML 中有 5 个预定义的实体引用:
&lt; < 小于
&gt; > 大于
&amp; & 和号
&apos; ’ 单引号
&quot; " 双引号

    注释:严格地讲,在 XML 中仅有字符 "<"和"&" 是非法的。省略号、引号和大于号是合法的,但是把它们替换为实体引用是个好的习惯。

    所以在文章内容输出的时候,做一次htmlspecialchars处理是很有必要的。

    除了使用htmlspecialchars处理以外,XML还为我们提供了一个特殊的标签:CDATA 区段(CDATA section)中的文本会被解析器忽略。所谓被解析器忽略并不是舍弃内容,而是忽略中间的内容,不然中间的内容影响XML的格式。

    CDATA 区段开始于 "<![CDATA[",结束于 "]]>":

以下是代码片段:
<script>
<![CDATA[
function matchwo(a,b)
{
if (a < b && a < 0)
   {
   return 1
   }
else
   {
   return 0
   }
}
]]>
</script>


    在上面的例子中,在 CDATA 区段中的所有东西都会被解析器忽略。

    特别注意:

    1:CDATA 区段不能包含字符串 "]]>",所以,CDATA 区段的嵌套是不被允许的。
    2:同时也需要确保在 "]]>" 字符串中没有空格或折行。

    请参考:http://www.w3school.com.cn/xml/xml_cdata.asp

展开全文  
收起全文  
PHP类中变量的初始化只能是定值 (PHP心得)
发布于 2010-04-14 18:19 阅读:160504 评论:0 标签: Opcodes 初始化

    首先看代码:

以下是引用片段:
class test
{
        //private $_expire_time =  604800; // 604800 = 60 * 60 * 24 * 7
        private $_expire_time =  60 * 60 * 24 * 7;
        public function hehe()
        {
                echo $this->_expire_time;
        }
}
$a = new test;
$a->hehe();
?>
[root@sso115 append]# php test.php
PHP Parse error:  syntax error, unexpected ’*’, expecting ’,’ or ’;’ in /data1/f2r/append/test.php on line 5
Parse error: syntax error, unexpected ’*’, expecting ’,’ or ’;’ in /data1/f2r/append/test.php on line 5

    杯具了,这句话有语法错误:

以下是代码片段:
private $_expire_time =  60 * 60 * 24 * 7;

    那么,这是为什么呢?

    查看手中的手册,没发现有解释,查看官方文档:http://www.php.net/manual/en/language.oop5.properties.php,如下:

以下是引用片段:
Class member variables are called "properties". You may also see them referred to using other terms such as "attributes" or "fields", but for the purposes of this reference we will use "properties". They are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.

    如红色字体,翻译如下:

以下是引用片段:
    这个声明可能会包含初始化,当时这个初始化必须是一个定值,也就是说,这个定值必须在编译时就能确定,而不是依赖于php在运行时再确定值。

    呃,翻译的有点拗口。简而言之,就是说类里面变量的初始化不能是一个表达式,否则编译期间就编译不过去,产生不了Opcodes。

    手册中给出错误和正确的初始化的例子:

以下是代码片段:
class SimpleClass
{
   // invalid property declarations:
   public $var1 = ’hello ’ . ’world’;
   public $var2 = <<hello world
EOD;
   public $var3 = 1+2;
   public $var4 = self::myStaticMethod();
   public $var5 = $myVar;

   // valid property declarations:
   public $var6 = myConstant;
   public $var7 = array(true, false);

   // This is allowed only in PHP 5.3.0 and later.
   public $var8 = <<<’EOD’
hello world
EOD;
}
?>

    关于Opcodes和编译的过程,可以参考以下资料:

以下是引用片段:
深入理解PHP原理之Opcodes
http://www.laruence.com/2008/06/18/221.html

PHP编译缓存
http://www.allniu.com/2010/0108/3820.html

实现PHP的编译执行分离(separating compilation and execution)
http://www.phpchina.com/index.php?action-viewnews-itemid-34001

    说句题外话:

    据说,现在PHP官网没有提供中文文档入口,是因为中文文档没人维护的原因,杯具!:http://opensource.solidot.org/article.pl?sid=08/04/22/2359251

    不过随便进入文档任意语言页面,切换语言中选 "Other",还是可以进入中文文档的。

展开全文  
收起全文  
Linux find命令的速度 (Linux/Unix)
发布于 2010-04-13 17:13 阅读:93220 评论:0 标签: find ls 速度

    find命令很强大,但没有遇到大量文件时,没想到它是如此的高效,真有一种想干掉ls命令的感觉:

以下是引用片段:

[root@thor104 f2r]# time ls -l /data2/friendresult/*/*/*
bash: /bin/ls: Argument list too long
real    0m1.722s
user    0m1.645s
sys     0m0.075s

[root@thor104 f2r]# time find /data2/friendresult/ -type f > friendfile.txt
real    0m0.129s
user    0m0.048s
sys     0m0.081s

    里面大约有16288个文件。

    看来ls只能是作为一个日常的工具使用,只是find命令是基于什么样的原理才能怎么快呢?上网只找到一个不错的使用解说:《Linux Find 命令精通指南》。共享一下!

展开全文  
收起全文  
整型(int)数字溢出在程序和数据库设计中的考虑 (PHP心得)
发布于 2009-07-02 20:13 阅读:100691 评论:0 标签: 溢出

    在数据库设计和程序中需要考虑数字的范围,否则可能导致一些问题。主要是考虑溢出的问题,比如如果数据库中有一个整型的数字字段,里面的数据可能随着业务的增长而膨胀,而这个数字有可能会超出列属性的范围,也就是溢出,与此同时,程序中也需要处理这个日益庞大的数字,如果其中有运算、数字类型的逻辑比较等等,也可能导致某天就出现了异常。而这种错误又是难以发现的。

    以下试以整型(int)抛砖引玉:

    一:MySQL5

    以MySQL5版本为例,大多数管理员可能把自增数字、或者其它应用数字字段的列属性设置为int类型,int占用4个字节,而int又分为无符号型和有符号性。对于无符号型的范围是0 到 4294967295;有符号型的范围是-2147483648 到 2147483647。参考资料可见mysql手册:11.2. 数值类型.

    当要在一个数值列内保存一个超出该列允许范围的值时,MySQL的操作取决于此时有效的SQL模式。如果模式未设置,MySQL将值裁剪到范围的相应端点,并保存裁减好的值。但是,如果模式设置为traditional(“严格模式”),超出范围的值将被拒绝并提示错误,并且根据SQL标准插入会失败。请参见mysql手册5.3.2节:“SQL服务器模式”。

    如果INT列是UNSIGNED,列范围的大小相同,但其端点会变为到0和4294967295。如果你试图保存-9999999999和9999999999,以非严格模式保存到列中的值是0和4294967296。

    如果在浮点或定点列中分配的值超过指定(或默认)精度和标度规定的范围,MySQL以非严格模式保存表示范围相应端点的值。

    当MySQL没有工作在严格模式时,对于ALTER TABLE、LOAD DATA INFILE、UPDATE和多行INSERT语句,由于裁剪发生的转换将报告为警告。当MySQL工作在严格模式时,这些语句将失败,并且部分或全部值不会插入或更改,取决于是否表为事务表和其它因素。详情参见mysql手册5.3.2节:“SQL服务器模式”。

    二:php5:
 
    1:整型数的字长和平台有关,PHP 不支持无符号整数。
    2:如果给定的一个数超出了 integer 的范围,将会被解释为 float。同样如果执行的运算结果超出了 integer 范围,也会返回 float。如果在程序中有对数字类型做比较,可能会产生问题。
    3:可以查看PHP_INT_SIZE、PHP_INT_MAX,以确定整数的范围。
 
    以下列子可供参考:
 
    在32位服务器下:

以下是代码片段:
[shengting@localhost ~]$ php -r "echo PHP_INT_SIZE;"
4
[shengting@localhost ~]$ php -r "echo PHP_INT_MAX;"
2147483647
[shengting@localhost ~]$ php -r "var_dump(2147483647);"
int(2147483647)
[shengting@localhost ~]$ php -r "var_dump(2147483648);"
float(2147483648)
[shengting@localhost ~]$ php -r "var_dump(-2147483647);"
int(-2147483647)
[shengting@localhost ~]$ php -r "var_dump(-2147483648);"
float(-2147483648)
[shengting@localhost ~]$ php -r "var_dump(4294967295);"
float(4294967295)
[shengting@localhost ~]$ php -r "var_dump(4294967296);"
float(4294967296)


    在64位服务器下:
 

以下是代码片段:
[root@login shengting]# php -r "echo PHP_INT_SIZE;"
8
[root@login shengting]# php -r "echo PHP_INT_MAX;"
9223372036854775807
[root@login shengting]# php -r "var_dump(2147483647);"
int(2147483647)
[root@login shengting]# php -r "var_dump(2147483648);"
int(2147483648)
[root@login shengting]# php -r "var_dump(-2147483647);"
int(-2147483647)
[root@login shengting]# php -r "var_dump(-2147483648);"
int(-2147483648)
[root@login shengting]# php -r "var_dump(4294967295);"
int(4294967295)
[root@login shengting]# php -r "var_dump(4294967296);"
int(4294967296)

    三:C/C++
 
    对C/C++也存在有符号和无符号类型的问题。
 
    对于32位系统,如果使用有符号int、long来定义变量保存唯一号就可能出现溢出,并出现上述问题。

    对于64位系统,如果使用int来定义变量保存唯一号就可能出现溢出,并出现上述问题。
 
    可参考 http://www.ibm.com/developerworks/cn/linux/l-port64.html

展开全文  
收起全文  
利用find和sed批量替换文件内容 (Linux/Unix)
发布于 2009-06-12 23:49 阅读:164487 评论:0 标签: find sed

    这是这个连锁反应:发现apache的log没有分日期、分正误记录 --> 改为分日期、分正误记录log --> 观察错误log,发现有大量404错误 --> 需要修正程序,发现文件路径错误 --> 本机使用Dreamweaver替换路径,提交SVN --> 部署到服务器上时发现文件太多、且分散在子目录中

    怎么办?一个一个找一个一个上传?傻子才干!既然是在FreeBSD下,那就是用强大的命令行工具吧!实践中发现这个方法真的很实用,记录下来!

    需求:把本目录下,包括子目录下的文件,把所有含有“/adm/images/c.gif”的地方替换为“/Admin/Images/c.gif”。

    步骤:找出文件,找到地方,替换。

    寻找命令:找到文件(find,ls),找到地方(grep),替换(sed)。

    现在需要做的,就是组合起来。

    查找资料,有前辈告诫:“find 命令是所有 Linux 命令中最有用的一个,同时也是最混乱的一个”,顿时奔溃。

    还好,发现find命令有个叫“-exec”的,很是强大:find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' {} \;,注意{}和\;之间的空格。

    个人理解:-exec参数中的“{}”是该参数前命令产生的结果的一个变量。感觉类似管道的作用了。

    而且还可以有多个-exec参数,很是强大。基本上grep和sed都可以作为子命令在其中运行了。

    如此一来,可以使用以下命令列出需要替换的字符串所在的行了:

以下是代码片段:

find ./ -exec grep "/adm/images/c.gif" '{}' \;

    然后再使用一个-exec参数吧sed包含进来吧。

    sed 的工作方式:

以下是引用片段:

sed 实用工具按顺序逐行将文件读入到内存中。然后,它执行为该行指定的所有操作,并在完成请求的修改之后将该行放回到内存中,以将其转储至终端。完成了这一行上的所有操作之后,它读取文件的下一行,然后重复该过程直到它完成该文件。默认输出是将每一行的内容输出到屏幕上。在这里,开始涉及到两个重要的因素―首先,输出可以被重定向到另一文件中,以保存变化;第二,源文件(默认地)保持不被修改。sed 默认读取整个文件并对其中的每一行进行修改。不过,可以按需要将操作限制在指定的行上。

    注意后面提到的源文件不会修改,不过sed提供了-i参数,可以做到控制是否可以修改源文件。-i参数的描述,Linux和FreeBSD下不太一样,后来也发现Linux在命令的使用方便上的确是要强于FreeBSD的。分述如下:

以下是引用片段:

 FreeBSD 4.7-STABLE下:
     -i extension
             Edit files in-place, saving backups with the specified extension.
             If a zero-length extension is given, no backup will be saved.  It
             is not recommended to give a zero-length extension when in-place
             editing files, as you risk corruption or partial content in situ-
             ations where disk space is exhausted, etc.

Linux下:
       -i[SUFFIX], --in-place[=SUFFIX]
              edit files in place (makes backup if extension supplied)

    FreeBSD下说如果-i参数后面的后缀如果为0,则不产生备份文件,结果我试了好几次都没有搞定,不得已,使用了一个备份文件来存储源文件,然后修改源文件:

以下是代码片段:
find ./ -exec grep "/adm/images/c.gif" '{}' \; -exec sed -i .bak 's/\/adm\/images\/c.gif/\/Admin\/Images\/c.gif/g' {} \;

    比如下面的就不行,老提示错误,望知情者指教:

以下是代码片段:
find ./ -exec grep "/adm/images/c.gif" '{}' \; -exec sed -i 's/\/adm\/images\/c.gif/\/Admin\/Images\/c.gif/g' {} \;

    Linux下,可以不产生备份文件直接修改了:

以下是代码片段:
find ./ -exec grep "/adm/images/c.gif" '{}' \; -exec sed -i 's/\/adm\/images\/c.gif/\/Admin\/Images\/c.gif/g' {} \;

    当然,需要强调的是:备份还是很重要的!切记切记!

    本文环境如下:

以下是引用片段:
FreeBSD:
FreeBSD 4.7-STABLE

Linux:
[root@bsso Admin_bak]# cat /etc/issue
CentOS release 4.1 (Final)
Kernel \r on an \m
[root@bsso Admin_bak]# sed --version
GNU sed version 4.1.2
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,
to the extent permitted by law.

    另:
    1:FreeBSD下如何查看sed的版本呢?
    2:网上看见资料说,类似下面的语句应该是可以达到目的,当我在FreeBSD和Linux下都没有运行成功

以下是代码片段:
sed -i 's/\/adm\/images\/c.gif/\/Admin\/Images\/c.gif/g' `grep -rf "/adm/images/c.gif"`


    参考资料:

以下是引用片段:

Linux文件查找命令find,xargs详述
http://www.linuxsir.org/main/?q=node/137
Linux Find 命令精通指南
http://www.oracle.com/technology/global/cn/pub/articles/calish-find.html
使用 sed 编辑器
http://www.oracle.com/technology/global/cn/pub/articles/dulaney_sed.html
linux sed 批量替换多个文件中的字符串
http://www.admin99.net/read.php/108.htm

展开全文  
收起全文  
在北京混那可是奋斗的一生哇! (随便说说)
发布于 2009-05-19 23:43 阅读:37015 评论:0 标签: 奋斗
    看北京房价,有感,如题。
展开全文  
收起全文  
sort命令分析日志 (Linux/Unix)
发布于 2009-04-28 22:52 阅读:35793 评论:1 标签: cut sort uniq

    很久没有更新blog了,上来冒个泡。

    之前,常用cut,sort,uniq命令的组合分析程序的log,或者查看数据以便统计。例如:cut -d "|" -f 4 | sort | uniq -n -r。

    今天遇到一个问题,需要查看多个用户的操作记录。数据第一列可顺利的按照时间排序,然而用户名在中间,既然是log,那源数据便可能是多个用户的交叉记录了。比如:

以下是引用片段:
time0 | userA | action
time1 | userB | action
time2 | userC | action
time3 | userA | action
time4 | userC | action
time5 | userB | action
time6 | userC | action
time7 | userB | action

    很显然,我们希望的顺序是:

以下是引用片段:
time0 | userA | action
time3 | userA | action
time1 | userB | action
time5 | userB | action
time7 | userB | action
time2 | userC | action
time4 | userC | action
time6 | userC | action

    我们既想按照中间的数据的排序又要保持数据的完整性!也许可以用其他的命令实现这个,但我更倾向于使用常用的命令搞定复杂的事情。

    其实sort命令是可以实现这个的。sort的-t选项可以实现cut的-d功能,再利用+m -n参数可以实现cut的-f的功能,只是,sort的这个+m -n是从0开始计数的。+m -n是指从第m个字段开始,到第n个字段排序,其中包含第m个但不包含第n个。比如:sort -t "|" +1 -2 filename 就可以得到我们想要的结果了。

    sort的功能是排序,应用起来会有很多种排序的方式,可以用指定的参数来控制:

    - d 按字典顺序排序,比较时仅字母、数字、空格和制表符有意义。这个选项对 uniq -d 后的结果尤为有用。
    - f 将小写字母与大写字母同等对待。也就是忽略大小写。
    - I 忽略非打印字符。
    - M 作为月份比较:“JAN”<“FEB”
    - r 按逆序输出排序结果。这个可与 -d 同时使用,实现数字从大到小的排列

    还有一个很实用的功能,如果你想把一个过滤后的文件内容重新写入到原文件,那么- o 参数可以达到这个要求,但是效率呢?嗯,是个问题,看取舍了!毕竟这种情况重定向是不行的。

    - o 输出文件 将排序输出写到输出文件中而不是标准输出,如果输出文件是输入文件之一,sort先将该文件的内容写入一个临时文件,然后再排序和写输出结果。

    很多系统实用小工具就是用这种常用名字组建的,嗯哼。

展开全文  
收起全文  
在招行专业版查看信用卡信息 (随便说说)
发布于 2009-03-31 14:41 阅读:16678 评论:0 标签: 信用卡 招行

    晕菜,想在招行专业版上信用卡的信息,看了专业版给的提示,提示我要么去柜台,要么先自动关联自动还款的一卡通。不想关联自动还款,于是去柜台,结果一进门就被工作人员忽悠到打招行信用卡800电话,然后被接线生很温柔地忽悠说招行专业版的客户服务里面就可以搞定。Y的,一群骗子。

    最后通过招行的网站客服搞定了事情,没办法,还是得先关联自动还款的一卡通。下面是网上客服的解释。

    招行网上客服的效率还是不错的,于是想想天朝的备案什么时候也能有这个效率呢?!从事互联网,还是这个备案的单位轻松啊。

------------------------ 喜欢忽悠的分割线 ------------------------

    您可以通过大众版或者电话办理。

    请您登录信用卡网上银行www.8008205555.com,点击“系统登录”输入身份证件号码、查询密码和附加码就能登录网上银行,然后在“还款管理”的下拉框中选择“自动还款设置”即可设置自动还款功能。向您说明一下:到期还款日前一天24点之前申请,当期自动还款才能生效,生效后即会从您一卡通上扣除本期帐款。需提醒您,您只能关联本人的一卡通,且一卡通证件号码、证件类型需与信用卡的一致,同时自扣当日勿往信用卡内存款,以免引起重复扣款。

    或请您致电客服热线800-820-5555,手机用户拨打021-38784800或者4008205555,在语音中选择“1”中文服务后,选择“1”持卡人服务,选择“1”帐务查询与还款,选择“2”自动还款,再选择“1”申请自动还款,即可开通一卡通自动扣款功能。

    绑定后就可以在“专业版管理”--“证书关联信用卡操作”,把信用卡关联到专业版了。

展开全文  
收起全文  
估算Apache所需要的内存 (Linux/Unix)
发布于 2009-03-25 19:21 阅读:29967 评论:2 标签: apache 内存

    精确的计算所需要的内存是很困难的,为了尽可能的精确,需要观察类似线上环境下观察服务器的负载和进程。毕竟如果不同的服务器配置和装的模块是有差异的,只有查看自己才可靠,所谓核心的东西要掌握在自己手里大概如此。。。。

    一个简单可靠的法子是,在压力测试时,找到httpd进程,查看一个进程使用了多少的内存,然后看看总的进程,即可估算一下。

    比如:
    ps aux | grep httpd
    查看每个httpd进程使用了多少内存,数字在第四列,格式为百分之几。

    ps aux | grep httpd | wc -l
    得到一共有多少进程,记得结果要减1,因为grep httpd也在结果中。

    free
    查看服务器内存总量,单位为K

    然后就可以估算了。比如一个进程占2%的内存,有27个httpd,总内存为4148424。那就是:
php -r "echo 0.002*4148424*26/1024;"
    结果为210.66215625M内存,这个只仅仅是为apache分配的。还得给其它服务留出足够空余的内存。而且考虑高峰期可能会比平时大12倍,这个时候仅仅考虑Apache就够了,嘿嘿。曾经出现过因磁盘IO过高导致服务器崩溃的场景。

    如果怎么算都不能让服务器有空余的内存,就得考虑限制最大进程数了。使用MaxClient指令可以用来限制。

    以上说得有误之处,还请各位指点!

展开全文  
收起全文