不一样的思想~~ http://shop34712791.taobao.com MSN:wins0910@hotmail.com

发布新日志

  • apache2.2.23+jbossas7 sticky session setting

    2012-12-18 18:39:06

    configure: error: ... Error, SSL/TLS libraries were missing or unusable
     
    solution:--
    export LDFLAGS=-ldl
     
    apache configure: error: Size of "void *" is less than size of "long"
     
    solution:--
    apache2.4.3 too high to reinstall apache2.2.23
    ..
    ./configure --prefix=/home/sandbox/apache22 --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util  --enable-mods-shared=all  --enable-ssl --enable-proxy --enable-proxy-ajp --enable-proxy-connect --enable-proxy-http --enable-module=so --enable-rewrite --enable-cgid --enable-cgi
    ..
    vi ./conf/httpd.conf:

    LoadModule authn_file_module modules/mod_authn_file.so
    LoadModule authn_core_module modules/mod_authn_core.so
    LoadModule authz_host_module modules/mod_authz_host.so
    LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
    LoadModule authz_user_module modules/mod_authz_user.so
    LoadModule authz_core_module modules/mod_authz_core.so
    LoadModule access_compat_module modules/mod_access_compat.so
    LoadModule auth_basic_module modules/mod_auth_basic.so
    LoadModule reqtimeout_module modules/mod_reqtimeout.so
    LoadModule filter_module modules/mod_filter.so
    LoadModule mime_module modules/mod_mime.so
    LoadModule log_config_module modules/mod_log_config.so
    LoadModule env_module modules/mod_env.so
    LoadModule headers_module modules/mod_headers.so
    LoadModule setenvif_module modules/mod_setenvif.so
    LoadModule version_module modules/mod_version.so
    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_connect_module modules/mod_proxy_connect.so
    LoadModule proxy_http_module modules/mod_proxy_http.so
    LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
    LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
    LoadModule session_module modules/mod_session.so
    LoadModule session_cookie_module modules/mod_session_cookie.so
    LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
    LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
    LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
    LoadModule unixd_module modules/mod_unixd.so
    LoadModule status_module modules/mod_status.so
    LoadModule autoindex_module modules/mod_autoindex.so
    LoadModule vhost_alias_module modules/mod_vhost_alias.so
    LoadModule dir_module modules/mod_dir.so
    LoadModule alias_module modules/mod_alias.so
    <IfModule mod_jk_module>
    Include conf/extra/mod_jk.conf
    </IfModule>
    <Location /server-status>
        SetHandler server-status
        Order deny,allow
        Deny from all
        Allow from all
    </Location>
    LoadModule weblogic_module modules/mod_wl_22.so
    Include conf/extra/httpd-WLvhosts.conf

    <IfModule proxy_html_module>
    Include conf/extra/proxy-html.conf
    </IfModule>

    <IfModule mod_jk_module>
    Include conf/extra/mod_jk.conf
    </IfModule>
    <Location /server-status>
        SetHandler server-status
        Order deny,allow
        Deny from all
        Allow from all
    </Location>
     
    cat ../conf/extra/httpd-vhosts.conf 
    <VirtualHost *:80>
        ErrorLog "logs/acooly.org-error_log"
        LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
        CustomLog logs/access_log vcommon
        ProxyRequests Off
        ProxyPreserveHost on
        # apache+jboss cluster
    #ProxyPass / http://app01:8080/
    #ProxyPass / http://app02:8080/
    ProxyPass / balancer://jboss-cluster/ stickysession=JSESSIONID|jsessionid nofailover=On
    ProxyPassReverse / balancer://jboss-cluster/
    <Proxy balancer://jboss-cluster>
        BalancerMember http://app01.xxxcorp.net:8080 loadfactor=1 route=node2
        BalancerMember http://app02.xxxcorp.net:8080 loadfactor=1 route=node4
        ProxySet lbmethod=byrequests
    </Proxy>
    </VirtualHost>

    more ../conf/extra/mod_jk.conf
    LoadModule jk_module modules/mod_jk-1.2.31-httpd-2.2.x.so
    #JkWorkersFile conf/workers.properties
    JkShmFile logs/mod_jk.shm
    JkLogFile logs/mod_jk.log
    JkLogLevel info
    JkMount /* jboss
    vi ./jboss-as-7.1.1.Final/standalone/configuration/standalone.xml:
    <subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" instance-id="node4" native="false">
     <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
                <connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp"/>
                <virtual-server name="default-host" enable-welcome-root="true">
                    <alias name="localhost"/>
                    <alias name="example.com"/>
                </virtual-server>
            </subsystem>

  • httpunit

    2008-08-28 22:08:13

    1\直接获取页面内容
    package onlyfun.caterpillar.test;

    import java.io.IOException;
    import java.net.MalformedURLException;

    import org.xml.sax.SAXException;

    import com.meterware.httpunit.GetMethodWebRequest;
    import com.meterware.httpunit.WebConversation;
    import com.meterware.httpunit.WebRequest;
    import com.meterware.httpunit.WebResponse;

    import junit.framework.TestCase;

    public class FirstHttpUnitTest extends TestCase {

    public void testCaterpillarOnlyfun()
    throws MalformedURLException,
    IOException,
    SAXException {
    WebConversation webConversation =
    new WebConversation();
    WebRequest request =
    new GetMethodWebRequest(
    "http://caterpillar.onlyfun.net/phpBB2/");
    WebResponse response =
    webConversation.getResponse(request);
    assertTrue(response.getTitle().startsWith(
    "caterpillar.onlyfun.net"));
    }

    public static void main(String[] args) {
    junit.swingui.TestRunner.run(
    FirstHttpUnitTest.class);
    }
    }
    2\通过Get方法访问页面并且加入参数 
    System.out.println("向服务器发送数据,然后获取网页内容:");   //建立一个WebConversation实例   WebConversation wc = new WebConversation();   //向指定的URL发出请求   WebRequest req = new GetMethodWebRequest( " http://localhost:6888/HelloWorld.jsp " );   //给请求加上参数   req.setParameter("username","姓名");   //获取响应对象   WebResponse resp = wc.getResponse( req );   //用getText方法获取相应的全部内容   //用System.out.println将获取的内容打印在控制台上   System.out.println( resp.getText() );
    3\通过Post方法访问页面并且加入参数
    //建立一个WebConversation实例   WebConversation wc = new WebConversation();   //向指定的URL发出请求   WebRequest req = new PostMethodWebRequest( " http://localhost:6888/HelloWorld.jsp " );   //给请求加上参数   req.setParameter("username","姓名");   //获取响应对象   WebResponse resp = wc.getResponse( req );   //用getText方法获取相应的全部内容   //用System.out.println将获取的内容打印在控制台上   System.out.println( resp.getText() );




    4\处理页面中的链接

    这里的演示是找到页面中的某一个链接,然后模拟用户的单机行为,获得它指向文件的内容。比如在我的页面HelloWorld.html中有一个链接,它显示的内容是TestLink,它指向我另一个页面TestLink.htm. TestLink.htm里面只显示TestLink.html几个字符
    System.out.println("获取页面中链接指向页面的内容:");   //建立一个WebConversation实例   WebConversation wc = new WebConversation();   //获取响应对象   WebResponse resp = wc.getResponse( " http://localhost:6888/HelloWorld.html " );   //获得页面链接对象   WebLink link = resp.getLinkWith( "TestLink" );   //模拟用户单击事件   link.click();   //获得当前的响应对象   WebResponse nextLink = wc.getCurrentPage();   //用getText方法获取相应的全部内容   //用System.out.println将获取的内容打印在控制台上   System.out.println( nextLink.getText() );

    5\处理页面中的表格
    表格是用来控制页面显示的常规对象,在HttpUnit中使用数组来处理页面中的多个表格,你可以用resp.getTables()方法获取页面所有的表格对象。他们依照出现在页面中的顺序保存在一个数组里面。
      [注意] Java中数组下标是从0开始的,所以取第一个表格应该是resp.getTables()[0],其他以此类推。
    下面的例子演示如何从页面中取出第一个表格的内容并且将他们循环显示出来:

    //建立一个WebConversation实例   WebConversation wc = new WebConversation();   //获取响应对象  WebResponse resp = wc.getResponse( " http://localhost:6888/HelloWorld.html " );   //获得对应的表格对象   WebTable webTable = resp.getTables()[0];   //将表格对象的内容传递给字符串数组   String[][] datas = webTable.asText();   //循环显示表格内容   int i = 0 ,j = 0;   int m = datas[0].length;   int n = datas.length;   while (i<n){   j=0;   while(j<m){   System.out.println("表格中第"+(i+1)+"行第"+(j+1)+"列的内容是:"+datas[j]);   ++j;   }   ++i;   }
    6\处理页面中的表单
    表单是用来接受用户输入,也可以向用户显示用户已输入信息(如需要用户修改数据时,通常会显示他以前输入过的信息),在HttpUnit中使用数组来处理页面中的多个表单,你可以用resp.getForms()方法获取页面所有的表单对象。他们依照出现在页面中的顺序保存在一个数组里面。
      [注意] Java中数组下标是从0开始的,所以取第一个表单应该是resp.getForms()[0],其他以此类推。
      下面的例子演示如何从页面中取出第一个表单的内容并且将他们循环显示出来
    System.out.println("获取页面中表单的内容:");   //建立一个WebConversation实例   WebConversation wc = new WebConversation();   //获取响应对象   WebResponse resp = wc.getResponse( " http://localhost:6888/HelloWorld.html " );   //获得对应的表单对象   WebForm webForm = resp.getForms()[0];   //获得表单中所有控件的名字   String[] pNames = webForm.getParameterNames();   int i = 0;   int m = pNames.length;   //循环显示表单中所有控件的内容   while(i<m){   System.out.println("第"+(i+1)+"个控件的名字是"+pNames+",里面的内容是"+
    webForm.getParameterValue(pNames));   ++i;   }
  • cronolog

    2008-05-04 13:32:22

    1.cronolog: ./configure & make & install

    2.add in httpd.conf of apache

    CustomLog "|/usr/local/sbin/cronolog /home/perf/cron_web/logs/%Y/%m/%d/access.log" combined

    3.vim /home/perf/mindy/cron_log.sh

    #!/bin/sh
    #backup old log
    /bin/mv -f /home/perf/cron_web/logs/`date -d yesterday +%w`/access_log /usr/local/apache2/logsbackup

    #remove old log
    /usr/bin/find /home/perf/cron_web/logs -name access_log -mtime +6 -exec rm -rf {}\;

    #analysis with awstats
    /usr/local/sbin/awstats

    4.crontab -e

    5 0 * * * /home/perf/mindy/cron_log.sh

  • mrtg

    2008-05-04 13:21:54

    preconditions:

    install zlib\gd\libpng

    check:perl\gcc\sysstat\iostat\httpd(apache)\net-snmp

    mrtg:./configure & make & make install(default path:/usr/local/mrtg)

    1.vi /etc/snmp/snmpd.conf

    把下面的#号去掉
    #view mib2 included .iso.org.dod.internet.mgmt.mib-2 fc #在89行
    把下面的语句#在62行
    access notConfigGroup "" any noauth exact systemview none none  
    改为:
    access notConfigGroup "" any noauth exact mib2 none none
    改完重启一下snmp
    Service snmpd restat

    2.mkdir /usr/local/apache2/www/mrtg

    3.cp /usr/local/mrtg/* /usr/local/apache2/www/mrtg

    4. /usr/local/mrtg/bin/cfgmaker –output=/usr/local/apache2/www/mrtg/mrtg.cfg public@192.168.98.129

    5.vim /usr/local/apache2/www/mrtg/mrtg.cfg

    add & modify:WorkDir: /usr/local/apache2/www/mrtg

    enable:Options[_]: growright, bits

    add:Language:Chinese

    为了使网络流量图可以每5分钟自动更新一次,我们还需要在
    ###Global Config Options的下一行加入一条命令:
    RunAsDaemon: yes

    6.or add: /etc/profile :

    LC_ALL=C
    LANGUAGE=on

    . /etc/profile

    7.add scrīpts into mrtg.cfg:

    LoadMIBs: /usr/share/snmp/mibs/HOST-RESOURCES-MIB.txt

    ############################# Memory #################################

    #Target[memory]: 1.3.6.1.4.1.9600.1.1.2.1.0&1.3.6.1.4.1.9600.1.1.2.4.0:public@10.5.13.17:::::2 / 1024
    Target[memory]: `/home/perf/mindy/mrtg_monitor/mrtg_mem.sh`
    MaxBytes[memory]: 512000
    Title[memory]:Memory Usages
    ShortLegend[memory]: &
    kmg[memory]:MB,kB --也可k,M,G,T,P,X
    kilo[memory]:1024

    #ShortLegend[memory]: bytes
    YLegend[memory]: &nbsp; Memory Usage :
    Legend1[memory]: &nbsp; Total Memory :
    Legend2[memory]: &nbsp; Used Memory :
    LegendI[memory]: &nbsp; Total Memory :
    LegendO[memory]: &nbsp; Used Memory :
    Options[memory]: growright,gauge,nopercent
    PageTop[memory]:<H1>Memory Usages</H1>

    ######################################################################


    ########################### CPU ######################################

    (注:我的服务器是双CPU的,如果你只有单CPU,把hrProcessorLoad.1&hrProcessorLoad.2 改成 hrProcessorLoad.1&hrProcessorLoad.1)

    #Target[cpu]: hrProcessorLoad.1&hrProcessorLoad.2:public@xx.xx.xx.xx
    #RouterUptime[cpu]: public@xx.xx.xx.xx
    Target[cpu]:`/home/perf/mindy/mrtg_monitor/mrtg_cpu.sh`
    MaxBytes[cpu]:12500000
    Title[cpu]: CPU -- XMNLINUXTEST02
    Options[cpu]: gauge,nopercent,growright
    YLegend[cpu]: CPU loading (%)
    ShortLegend[cpu]:%
    LegendO[cpu]: & CPU SYSTEM;
    LegendI[cpu]: & CPU USER;
    PageTop[cpu]: <H1>;CPU  -- XMNLINUXTEST02</H1>;

    ######################################################################

    ########################### SWAP #####################################

    Target[swap]:`/home/perf/mindy/mrtg_monitor/mrtg_swap.sh`
    Unscaled[swap]: dwym
    MaxBytes[swap]: 1024000
    Title[swap]:Memory State of Server
    ShortLegend[swap]: &
    kmg[swap]:kB,MB
    kilo[swap]:1024
    YLegend[swap]: Swap Usage
    Legend1[swap]: Total Swap
    Legend2[swap]: Used Swap
    LegendI[swap]: Total Swap
    LegendO[swap]: Used Swap
    Options[swap]: growright,gauge,nopercent
    PageTop[swap]:<H1>;Swap-------XMNLINUXTEST02</H1>;

    ######################################################################

    ########################### Disk Space ###############################

    Target[disk]: `/home/perf/mindy/mrtg_monitor/mrtg_df.pl`
    Title[disk]: Disk Space ----XMNLINUXTEST02
    Unscaled[disk]: dwym
    MaxBytes[disk]: 7369794
    kmg[disk]: KB,MB,GB
    LegendI[disk]: Total Disk Space
    LegendO[disk]: Used Disk Space
    Legend1[disk]: Total Disk Space
    Legend2[disk]: Used Disk Space
    YLegend[disk]:  Megabytes
    ShortLegend[disk]: &
    Options[disk]: growright,gauge,nopercent
    PageTop[disk]: <H1>;Disk Space --------XMNLINUXTEST02</H1>;

    ######################################################################

    ############################ Disk I/O ################################

    Target[diskIO]: `/home/perf/mindy/mrtg_monitor/mrtg_diskio.sh`
    Title[diskIO]: Disk HDA I/O Utilization Report
    Unscaled[diskIO]: dwym
    MaxBytes[diskIO]: 100
    PageTop[diskIO]: <H1>;Disk I/O Utilization Report</H1>;
    kmg[diskIO]: KB,MB,GB
    LegendI[diskIO]: Disk I/O KBread/sec
    LegendO[diskIO]: Disk I/O KBwrite/sec
    Legend1[diskIO]: Disk I/O KBread/sec
    Legend2[diskIO]: Disk I/O KBwrite/sec
    YLegend[diskIO]:  Megabytes
    ShortLegend[diskIO]: &
    Options[diskIO]: growright,gauge,nopercent

    ######################################################################

    Target[www]: `/opt/mrtg/mrtg.www`
    MaxBytes[www]: 500
    Options[www]: nopercent, growright
    YLegend[www]: Online Users
    ShortLegend[www]: %
    LegendI[www]: &nbsp; Connect :
    LegendO[www]: &nbsp; Online :
    Title[www]: WWW Connect
    PageTop[www]: <H1> WWW Connect </H1>

    ######################################################################

    Target[process]: hrSystemProcesses.0&hrSystemNumUsers.0:public@10.5.13.17
    RouterUptime[process]: public@10.5.13.17
    MaxBytes[process]: 150
    Title[process]: Processes and Users
    PageTop[process]: <br /><H1>Processes and Users</H1>
    Unscaled[process]: ymwd
    ShortLegend[process]:.
    YLegend[process]: Numbers
    Legend1[process]: Process Numbers
    Legend2[process]: System Users
    LegendI[process]: Process Numbers
    LegendO[process]: System Users
    Options[process]: growright,nopercent,gauge

    end

    8.vim /home/perf/mindy/mrtg_monitor/mrtg_mem.sh

    totalmem=`/usr/bin/free -m|grep Mem|awk '{print $2}'`
    usedmem=`/usr/bin/free -m |grep "buffers/cache"|awk '{print $3}'`
    UPtime=`/usr/bin/uptime |awk '{print $3" "$4" "$5}'`
    echo "totalmem: "$totalmem
    echo "usedmem: "$usedmem
    echo "UPtime: "$UPtime
    hostname

    vim /home/perf/mindy/mrtg_monitor/mrtg_swap.sh

    #!/bin/bash
    # This scrīpt to monitor the swap usage.
    totalswap=`/usr/bin/free -m|grep Swap |awk '{print $2}'`
    usedswap=`/usr/bin/free -m|grep Swap |awk '{print $3}'`
    UPtime=`/usr/bin/uptime |awk '{print $3" "$4" "$5}'`
    echo "totalswap: "$totalswap
    echo "usedswap: "$usedswap
    echo "UPtime: "$UPtime
    hostname

    vim /home/perf/mindy/mrtg_monior/mrtg_cpu.sh

    #!/bin/bash
    cpuusr=`/usr/bin/sar -u 1 3 |grep Average|awk '{print $3}'`
    cpusys=`/usr/bin/sar -u 1 3 |grep Average|awk '{print $5}'`
    UPtime=`/usr/bin/uptime|awk '{print $3" "$4" "$5}'`
    echo "cpusys: "$cpusys
    echo "cpuusr: "$cpuusr
    echo "UPtime: "$UPtime
    hostname

    vim /home/perf/mindy/mrtg_monitor/mrtg_df.pl

    foreach $filesystem (`df -ml | grep -v "Filesystem"`)
    {
      @df = split(/\s+/,$filesystem);
      $total += $df[1];
      $usage += $df[2];

    print "total_df: $total\n";
    print "usage_df: $usage\n";
    }
    hostname

    vim /home/perf/mindy/mrtg_monitor/mrtg_diskio.sh

    hd=sda
    disk=/dev/$hd
    KBread_sec=`iostat -x $disk|grep $hd |awk '{print $8}'`
    KBwrite_sec=`iostat -x $disk|grep $hd |awk '{print $9}'`
    UPtime=`/usr/bin/uptime |awk '{print $3" "$4" "$5}'`
    echo "KBread/sec on sda: "$KBread_sec
    echo "KBwrite/sec on sda: "$KBwrite_sec
    echo "UPtime: "$UPtime
    hostname

    end

    vim /home/perf/mindy/mrtg_monitor/mrtg_connectins.sh

    #!/bin/bash
    all=`netstat -a | grep www|awk '{print $5}'|sort | wc -l|awk '{print$1 - 1}'`
    user=`netstat -a | grep www|awk '{print $5}'|cut -d":" -f1|sort| uniq |wc -l | awk '{print $1 - 1}'`
    if [ "$all" = "-1" ]; then
    echo 0
    else
    echo $all
    fi
    if [ "$user" = "-1" ]; then
    echo 0
    else
    echo $user
    fi
    UPtime=`/usr/bin/uptime | awk '{print $3 " " $4 " " $5}'`
    echo $UPtime
    hostname

    8.add httpd.conf in apache: Alias /mrtg/ "/usr/local/apache2/www/mrtg/"

    9.vim /home/perf/mindy/mrtg_monitor.sh

    env LANG=C /usr/local/mrtg-2/bin/mrtg /usr/local/apache2/www/mrtg/mrtg.cfg
    env LANG=C /usr/local/mrtg-2/bin/indexmaker --output=/usr/local/apache2/www/mrtg/index.html --title="Monitor 129" /usr/local/apache2/www/mrtg/mrtg.cfg

    10.crontab -e

    */5 * * * * /home/perf/mindy/mrtg_monitor.sh

    11.curl http://192.168.98.129:8080/mrtg/index.html

    addition:

    mrtg.cfg 里面几个参数的意思.

    Target:有两种定义方法
       从snmp获取信息:2: public@192.168.1.2 <--2表示从snmp获得的设备号标识,后面是community认证信息和服务器地址
       从脚本获取信息:指定要执行的脚本路径,使用“`”号分割。
    Target:是要执行的脚本
    Xsize:生成图表的横向宽度(最大600)
    Ysize:生成图表的纵向高度(最大200)
    Title:标题
    kMG: Change the default multiplier prefixes
    Ytics:纵向划分为几个块(格子)
    MaxBytes:图表纵向数值的最大上限
    PageTop:页面上面的提示
    kilo:一般是写1024,如果需要的话,是1000在计算机里的单位
    LegendI:从SHELL返回的数据中的第一个
    LegendO:从SHELL返回的数据中的第二个
    Options: growright,表示图表向右延展

    Options: 一些可用参数
       growright:将数据随时间变化的顺序以右而左绘图;
       bits:数据单位为 bits;
       nopercent:在图下方的说明文字中,不显示百分比;
       gauge:图表的上限固定。
    常见:
    Options[192.168.228.153_2]: growright, bits  (用在网络流量中)
    Options[192.168.228.153_3]: growright, nopercent, gauge  (用在 CPU 负载中)

    ------------------------------

    make & make install mod_watch4

    vim apache2 httpd.conf:

    <IfModule mod_watch.c>
    # Allows the URL used to query virtual host data:
    #
    # http://www.snert.com/watch-info
    #
    <Location /watch-info>
    SetHandler watch-info
    </Location>
    # Intended for debugging and analysis of shared memory
    # hash table and weenie files:
    #
    # http://www.snert.com/watch-table
    #
    <Location /watch-table>
    SetHandler watch-table
    </Location>
    # 注意,为了安全,请关闭watch-table选项,或者加以IP限制,以免别人查看你SERVER所放的站点资源,引起不必要的麻烦。
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
    </IfModule>

    check : /usr/local/sbin/apachectl configtest

    restart:/usr/local/sbin/apachectl restart

    就可以从某个虚拟主机的watch-info文件读出某些数据了,比如:

      http://freebsd.onlinecq.com/watch-info

      freebsd.onlinecq.com 2 760 858 2 1 1 0.000 675269920 3217025432

    apache2mrtg.pl /usr/local/etc/apache2/httpd.conf

    and copy some segments such as:

    vi /usr/local/etc/apache2/mod_watch.cfg
    WorkDir:/home/onlinecq.com/mrtg/
    Options[_]: growright,bits
    #Language: gb2312
    #Title[^]: Traffic Analysis for
    PageTop[^]: <H1>Traffic Stats for Online</H1><HR>
    #PageTop[$]: Contact<HR>
    PageFoot[^]: xxx

    ------------------------------------------

    mrtg 远程设置,哈,以上是对本机的监控设置,随着配置的深入,越来越发现以上已经不够用了。下面摘抄中我结合了自己的一些心得和关键点,相信还是有点用的:〉

    cfgmaker --global "WorkDir: /var/www/html/mrtg"
    --global "Options[_]: growright,bits"
    --ifref=descr
    --ifdesc=alias
    public@router1.place.xyz
    public@router2.place.xyz
    --global "Options[_]: growright"
    --ifref=name
    --ifdesc=descr
    public@switch1.place.xyz
    --ifdesc=name
    public@switch2.place.xyz > mrtg.cfg

    那个是针对router和switch配置监控,因为router等可能需要通过alias来识别。详见以下注释。自己的配置:

    cfgmaker --global "WorkDir: /var/www/html/mrtg" -可去掉,通过改生成后的mrtg.cfg就可以了。
    --global "Options[_]: growright,bits" -同上
    --ifref=ip -用IP
    --ifdesc=alias -去掉
    public@router1.place.xyz -公共访问名@目标主机
    public@router2.place.xyz -以上global到此均有效
    > mrtg.cfg

    这里指示监控四个设备:router1.place.xyz、router2.place.xyz、switch1.place.xyz 和switch2.place.xyz,所有的设备都采用共同体名public来进行监控。并且两个路由器采用descr来作为设备的描述信息,而两个交换机则采用alias作为设备描述(这两者是不同的,例如对于cisco路由器来说,对于descr来说设备描述为"Serial0",而对于aliasl来说则为"Link to HQ")。

    执行之后,生成的mrtg.cfg中会有一大堆对每个ethx网卡接口地址信息描述。对号入座就行了。

    执行并测试远程snmpd:

    snmpwalk -c public -v 1 ip(远程主机) .1.3.6.1.4.1.2021:53

    编写追加远程主机/etc/snmp/snmpd.conf并重启:

    exec .1.3.6.1.4.1.2021.53 usrcpu /bin/sh /xx/xx/cpu.sh

    如果遇到执行输出中/bin/sh /xx/xx/cpu.sh permission denied

    就需要进入vim /etc/selinux/config

    更改为:SELINUX=disabled
    再:vi /boot/grub/menu.lst

    kernel /boot/vmlinuz-2.6.9 ro root=/dev/hda1 rhgb selinux=0

    ----------------

    [root@Mindy mindy]# rpm -qa|grep snmp
    net-snmp-5.1.2-11.2
    net-snmp-perl-5.1.2-11.2
    net-snmp-libs-5.1.2-11.2
    net-snmp-utils-5.1.2-11.2
    net-snmp-devel-5.1.2-11.2

    version mrtg:2.13.2
    然后:sync; reboot

  • ssl+jmeter

    2008-04-21 23:17:36

    用jmeter测试https应用

        实验室的项目是做关于web service的security产品,主要是对soap消息进行加密签名。上一次的性能测试是将单纯调用web service和应用我们的security产品后的web service进行对比,然而差距还是相当明显的,尤其是在高并发的时候,毕竟中间的加密和签名过程是相当消耗时间的。上次review的时候,老师就说性能有很大的程度可以提高,我本来想说基本没太多的空间可以优化(除了之后会加入的线程池,应该会有小幅度性能提升),但是苦于没有数据支持。正好这两天为了准备开题,一直在看一些文章,看到网上有人提到,SSL + WS-Security = Web Service安全保障,主张用https的方式来传输soap消息。虽然不是什么很好的方法,不过不是正好拿来作为产品测试对比的对象嘛。

        tomcat上已经配置好了axis,通过http访问soap消息是没有问题了。但是还没有配置https,所以按着官方文档开始干活了。首先用keytool生成服务器段的keystore:

    keytool -genkey -alias tomcat -keystore ktomcat.keystore

        注意,alias的密码要与keystore的密码一致,tomcat文档上是这么说的。接着是修改了server.xml:

    <Connector
               port="8443" protocol="HTTP/1.1" minSpareThreads="5" maxSpareThreads="75"
               enableLookups="true" disableUploadTimeout="true"
               acceptCount="100"  maxThreads="200"
               scheme="https" secure="true" SSLEnabled="true"
               keystoreFile="ktomcat.keystore" keystorePass="changeit"
               clientAuth="false" sslProtocol="TLS"/>

        重启tomcat之后,输入https://localhost:8443进行验证(注意是8443哦,我一开始居然傻乎乎的输入8080^_^)

        接着设置客户端的trustStore,jmeter需要它来信任tomcat服务器段的证书

    keytool -export -alias tomcat -keystore ktomcat.keystore -file tomcat.crt
    keytool -import -alias tomcat -file tomcat.crt -keystore tclient.keystore

        tomcat上的https配置成功之后,就开始jmeter的配置了,默认情况下用jmeter是不可以访问我们配置的https应用的,不过却可以访问像google等网站上的https应用,原因很简单,我们自己生成的证书是不被信任的。jmeter的官方网站有一个很大的陷阱,上面说只要修改jmeter.properties参数,将SSL Configuration部分内的注释去掉就可以了,如下

    #---------------------------------------------------------------------------
    # SSL configuration
    #---------------------------------------------------------------------------

    #Classname of the ssl provider to be used (to enable testing of https urls)
    #And the package name where Stream Handlers can be found
    #These provided defaults can be uncommented, and they will work if you are using
    #Sun's JSSE implementation.

    ssl.provider=com.sun.net.ssl.internal.ssl.Provider
    ssl.pkgs=com.sun.net.ssl.internal.www.protocol

    #The location of the truststore (trusted certificates) and keystore ( if other than the default.
    #you can uncomment this and change the path to the correct location.
    javax.net.ssl.trustStore=/home/flyerhzm/software/jakarta-jmeter-2.2/tclient.keystore
    javax.net.ssl.keyStore=/home/flyerhzm/software/jakarta-jmeter-2.2/kclient.keystore

    #The password to your keystore
    javax.net.ssl.keyStorePassword=changeit

        不过结果还是失败,尝试了好多次,总是报SSLHandshakeException。如果是通过浏览器访问的话,浏览器都会提醒你对方的证书不合法,是否要信任它,但是java是不会询问你,而是直接抛出异常。但是如果设置了trustStore的话,就会信任对方的证书啦,太奇怪了。

        google了一下有关SSLHandshakeException,网上有说可以用-D方式添加应用参数,于是打开了jmter启动文件,修改最后一句话为:

    java $JVM_ARGS $ARGS -jar `dirname $0`/ApacheJMeter.jar -Djavax.net.ssl.trustStore=/home/flyerhzm/software/jakarta-jmeter-2.2/tclient.keystore -Djavx.net.ssl.trustStorePassword=changeit "$@"

        居然成功了,呵呵。可恶,配置文件jmeter.properties居然不起作用,害我辛苦到现在。

        趁热打铁,测试了一下通过https访问web service,果然比应用我们的security产品要多消耗1倍多的时间,赞,终于有数据可以说服老师了,哈哈。

  • PHP 版本与memory_limit

    2008-04-04 21:19:20

    php5.2.0内存管理改进发布:dxy 发布日期:2007-1-22 字体:[增加 减小] 类型:转载
    pHP5.2.0的内存管理做了较大的改进,某些情况下内存不能释放的问题不存在了。
    测试php脚本(mem.php),我用echo N>>和sleep来控制脚本在某个阶段暂停以便检测状态。
    [复制此代码]CODE:
    <?php 
    echo '1>>'; 
    sleep(5); 
    $o = array(); 
    for ($i=0;$i<=100000;$i++) { 
        $o[]='aaaaaaaaaaaaaaaaaaaaa'; 

    echo '2>>'; 
    sleep(5); 
    unset($o); 
    echo '3>>'; 
    while (true) { 
        echo '..'; 
        sleep(10); 

    ?>
    监测内存使用情况的bash scrīpt(注意:里面的”mem”是取自上面的php脚本名):
    while true;do clear;ps au|grep -v "\(vi\|grep\)"|grep "\(mem\|RSS\)";sleep 2;done;
    以下是$/usr/local/bin/php mem.php这个进程在三种状态(数组创建前,数组创建后,数组销毁后)下,用5.1.6和5.2.0的PHP(我使用了一样的configure参数)测试的RSS(内存使用值,单位KB)结果。
    php5.1.6:
    3164
    18076
    17572
    PHP5.2.0:
    4088
    14400
    4424
    大家可以看到5.1.6这个版本,unset数组之后,内存并没有从进程里释放出来,虽然它是可以继续被这个php进程再利用,但是却无法被系统的其他进程所使用。而5.2.0则真正释放出了内存。
    大家可能还注意到,在最开始,5.2.0的内存使用比5.1.6多了几个kb,这是由于5.2.0增加了一些新的东西,这个是很正常的。
    另外php5.2.0的内存分配也进行了大的改进,官方的说法是对memory_limit的检测由每次呼叫emalloc()的时候进行改为直接检测从系统请求的内存数据块(blocks)。需要更进一步了解的朋友可以自己去研究代码。而由于内存分配的实现的更改,内存控制可以更精确地被控制在memory_limit之下,也就是说以前php代码里,如果有超过了memory_limit的内存使用而没有出错的,在php5.2.0里可能会报错。为了平衡这次改进,PHP5.2.0的默认的memory_limit由以前的8MB改为了16MB.搜索源代码可以看到这个修改(find . -name \*c -type f |xargs cat |grep memory_limit)。 
    本文来自: 脚本之家(www.jb51.net) 详细出处参考:http://www.jb51.net/article/6507.htm

  • Apache apr中内存分配子的current_free_index成员作用

    2008-04-04 11:04:25

                  Apache apr中内存分配子的current_free_index成员作用     CSDN Blog鎺ㄥ嚭鏂囩珷鎸囨暟姒傚康锛屾枃绔犳寚鏁版槸瀵笲log鏂囩珷缁煎悎璇勫垎鍚庢帹绠楀嚭鐨勶紝缁煎悎璇勫垎椤瑰垎鍒槸璇ユ枃绔犵殑鐐瑰嚮閲忥紝鍥炲娆℃暟锛岃缃戞憳鏀跺綍鏁伴噺锛屾枃绔犻暱搴﹀拰鏂囩珷绫诲瀷锛涙弧鍒?00锛屾瘡鏈堟洿鏂颁竴娆°? title=  

    1. 背景


    这个问题最初起源于tingya的blog中apache代码分析系列文章 ( http://blog.csdn.net/tingya )。当对内存池部分进行分析时,涉及到了内存分配子(allocator)的内容。内存分配子结构体中包含一个叫做current_free_index的成员。对于该成员的具体作用,广大网友众说纷纭。相关的讨论可以在tingya的blog中看到( http://blog.csdn.net/tingya/archive/2005/12/23/559815.aspx )。

    2. 历史

    关于apr是何时把current_free_index成员放入内存分配子结构体中的,我google了一下,找到了这样一篇文章:

    http://www.mail-archive.com/dev@apr.apache.org/msg06563.html

    从文章中的补丁可以看出,在这之前,内存分配子结构体中是没有current_free_index和max_free_index这两个成员的。并且,那时的apache在内存分配子未被释放之前是不会释放内存分配子中保留的内存。而之所以加入这两个成员,目的就是为了控制内存分配子中保管内存的数量。至此,可以基本断定,current_free_index和max_free_index是协同工作来控制分配子中的内存。

    3. current_free_index与max_free_index的作用

    在tingya的blog上面的讨论中,有一个叫做allan 的网友对current_free_index的功能作了如下的描述:

    current_free_index,是当前应该释放的index值(超过这个值就应该释放)
    这个值是动态调整的,根据你系统中内存的使用情况来判断的
    除了在设置max_free_index的函数中改变了这个值以外,
    在其他的两个地方也有涉及到,分别是:
    用分配子分配node的时候,current_free_index加上了该node的index值
    用分配子释放node的时候,current_free_index减去了这个node的index值
    在一般情况下,这个值一增一减是平衡的。
    考虑一种极端情况:你调用max_free_set之后,max_free_index和current_free_index都不为0,然后一直向分配子申请内存
    分配子的内存不够用了,需要向系统申请,这种内存只有在调用分配子释放的时候,归还到分配子的free链表中
    当你不断释放的时候,current_free_index不断减少,相当于归还给系统的内存门槛在降低,因为这些内存是从操作系统申请而来的
    如果不归还给操作系统,系统资源会耗尽(全部给了分配子)

    这样,即使当你调用max_free_set设置了一个超大的内存归还门槛。你在向系统不断申请内存后调用分配子释放的时候
    分配子也会逐渐调低current_free_index的门槛,把内存归还给操作系统
     
    之后,allan又说了:
    呵呵,其实刚才说的是表面现象,apr靠这样一种机制保证了,分配子只在内存中占有max_free_index这么多的空间,如果你向系统申请了超过这么的空间,apr只把不超过的部分留在自己的free链表中,超过的部分统统还给系统。

    这就是靠我刚才说的使用current_free_index这样一个机制来实现的,呵呵。
     
    至此,current_free_index的功能已经基本有了眉目。
    而tingya在文章中对max_free_index的作用概括为:“如果结点的大小超过了完全释放的阙值max_free_index,那么我们就不能将其简单的归还到索引链表中,而必须将其完全归还给操作系统。
    但是在通过阅读代码之后,可以发现,二人的说法虽然各有一定道理,但是对current_free_index和max_free_index的功能概括却并不准确。我在这里试着对这两个成员的功能作一个更加准确的概括:
    max_free_index用于记录内存分配子中最多可以容纳的内存空间大小。
    current_free_index用于记录内存分配子中当前可以继续容纳的内存空间的大小。
    其实,allan已经基本对这两个功能进行了描述,但是current_free_index并非仅仅如他所说的,“是当前应该释放的index值(超过这个值就应该释放)
    这两个变量控制了内存分配子内容量的大小。这样做是基于以下的事实:
    内存分配子中保存的都是从操作系统申请来的,但是至今仍是闲置的内存空间。这些空间是以多个链表的形式保存的。这样的空间不能太大——否则大量的系统资源被占用却未被利用,影响了系统的效率;同时,这样的空间又不能太小——否则频繁地从操作系统内申请和释放内存同样会影响系统的效率。因此,内存分配子中保存的这些闲置内存的数量就要控制在一定范围之内。这样,通过max_free_index来记录内存分配子中最多可以容纳的内存空间大小。在调用apr_allocator_free函数释放一个分配子节点到分配子中时,会检查分配子中当前内存数,加上这个即将被释放的分配子节点携带的内存空间数之和是否超过了max_free_index。而因为current_free_index记录了内存分配子中当前可以继续容纳的内存空间大小,那么,只要检测这个即将释放的分配子节点携带的内存空间数是否大于current_free_index就好了。这个检测是通过判断 index > current_free_index 的值来完成的。
     
    4. 关于current_free_index溢出的问题
     
    在google的时候,我同样发现了这样的一篇文章:
    http://marc2.theaimsgroup.com/?l=apache-httpd-dev&m=113600944405209&w=2
    其中提到了:
    We probably should have a check in apr_allocator_free() to
    make sure that we're not causing an unsigned int overflow in
    allocator->current_free_index, e.g.,
    + if (index > current_tree_index) {
    + current_tree_index = 0;
    + }
    + else {
    current_free_index -= index;
    + }
    按照如此说法,current_free_index对于溢出的检测的确存在问题。但是就此问题我也做了一个粗略的分析。
    (1) 当max_free_index不等于0时
    即,对于内存分配子中的内存大小作了限制。这时,当释放一个节点时,会执行以下if语句:
            if (max_free_index != APR_ALLOCATOR_MAX_FREE_UNLIMITED
                && index > current_free_index) {
                node->next = freelist;
                freelist = node;
            }
    因为已经假设max_free_index不等于零,即,判断语句的前半部分为真,如果index > current_free_index,则会将分配子节点释放给操作系统而不对current_free_index进行修改。一旦index > current_free_index为假,那么执行current_free_index -= index也不会发生溢出,因为current_free_index - index >= 0。
    (2) 当max_free_index等于0时
    即,对于内存分配子中内存大小不做限制。那么很显然,既然不做限制,current_free_index也便没有了任何作用,它的溢出也就无所谓了。而如果在current_free_index溢出之后再通过apr_allocator_max_free_set调整回收门槛,由于current_free_index溢出变成了一个很大的整数,加上即将释放的节点的index后可能依然大于max_free_index,但是由于下面语句的存在:
        if (allocator->current_free_index > max_free_index)
            allocator->current_free_index = max_free_index;
    所以current_free_index值会被设成max_free_index的值。
     
    但是仍然存在一个问题:
    假如通过apr_allocator_create创建了一个无回收门槛的分配子allocator,调用apr_allocator_alloc在allocator中申请了一个100K的节点。之后,通过调用apr_allocator_alloc将这个节点释放给allocator。此时,allocator->current_free_index已经溢出变为一个很大的正整数。最后再通过apr_allocator_max_free_set调整回收门槛为50K。调用结束,current_free_index和max_free_index值会相等,都表示与50K对应的索引值。但是,此时内存分配子中却存储着一个100K的节点。这样,current_free_index就不再表示当前分配子可以继续存储的内存空间大小。除非用户的再次申请大于或者等于100K的空间,否则分配子中的节点索引的和会大于max_free_index值。不过,这种调用方法(即,先申请 释放内存后再设置门槛)可以比较容易地避免。因此,这种内存浪费的问题也便不是很明显了。
     
    注: 本人十一长假期间在家,手头的电脑不是自己的,只有windows系统且无开发环境,所以无法做相关的测试。因此所说的一些话仅仅是臆断,不能保证正确性。还望有相关测试条件的人员帮忙替我做完这个测试,特别是对我最后提出的那个疑问的测试。文章中不正确的地方,很可能是我自身疏忽的缘故,还望多多谅解。
    5. 溢出问题的解决 
    关于解决上述的current_free_index溢出问题,存在着两种方法(别着急,先别急着改代码,一会我会说原因)。
    第一种,就是如第4节开头部分的补丁所示,修改allocator_free函数,在减少current_free_index前对减数和被减数进行检测,避免current_free_index溢出。
    第二种,就是修改apr_allocator_max_free_set,在其中加入释放多余空间的功能。也就是说,如果max_free_index设置的值表示为a,则将内存分配子中的节点释放直到其中的总大小小于等于a为止。并调整相应的current_free_index值。
    比较起来,第一种方案似乎容易实现些。
    但是,为什么apache项目组在05年收到补丁后却迟迟不肯修改自己的代码呢?我个人认为是有以下原因的:
    1. current_free_index溢出的可能性不是很大。正如我在前面一节说的,它的溢出只有在特定的调用顺序和参数的前提下才会发生,而且会随着下次调用apr_allocator_alloc而逐渐消除溢出对系统的影响。
    2. apr_allocator_free这个函数调用的频率相对较高,它执行的效率直接影响着整个系统的效率。如果要在其中加入什么代码,必须要经过深思熟虑——哪怕是一个简单的if-else。
    3. 正如前面一节所说的,current_free_index溢出是在特定的函数调用顺序和参数的情况下才发生。概括起来,可以说是在申请并释放大量内存后,调用apr_allocator_max_free_set,将本是无回收门槛的分配子设置上门槛。但是,凭借常识可以知道,在一系列大量申请并释放内存后,系统往往会逐渐地恢复到申请小片内存。换句话说,一般的系统,很少在申请大量内存过后,突然间改变成仅仅申请少量的内存而不再申请大片内存。这之间往往会存在一个过渡期,因此,在这个过渡期中,在分配子里面存储一些过剩的内存空间以备不时之需往往是有必要的。况且,这种内存溢出带来的问题可以在调用一次或几次apr_allocator_alloc之后得到消除。如果在调用apr_allocator_max_free_set时便一下子把内存分配子中的节点释放到相应的数量,那么既消耗了系统资源(因为多次调用了free,把节点占用的内存还给操作系统),又不能应付以后可能发生的过渡时期。因此,这么做显然不是非常理智。
    如前所述,消除溢出的方法的确存在,但是比起现在的做法,不如让溢出继续保留——反正这种溢出发生的可能性不是很大,而且非常容易避免。
    最后,感谢tingya对apache代码的分析,我受益匪浅。
    感谢allan对current_free_index的总结。
    感谢各位网友的积极讨论。
  • 不摘抄能咋办?至少我思考了!

    2008-04-03 23:21:21

    netstat -an | grep 61.143.210.228.80 | grep "WA" | wc -l
    ---------------------------
    换多少个*httpd都没有用
    你的问题明显是mysql联接数过多引起的
    十之八九是应用层的dos

    还是赶快先查清楚是不是单个ip过来的吧,
    这种问题居然还讨论半天....
    ---------------------------
    mmcache配置
    ---------------------------
    ps -U apache -u apache u

    我们可以认为RSS数字的一半是httpd线程真正使用的内存数,这可能还有点保守,但是

    离我们的目的已经非常接近了

    对于php脚本来说,把这个参数设置的小一些是有好处的,可以避免程序使用的内存持

    续增长对apache带来的压力:让这个参数定期释放内存,因为php是在脚本执行完毕后

    ,自动释放只用的资源(内存)的。

    比如设置为50?如果太小的话,重新产生一个apache进程也是要消耗资源的,这是一个

    平衡问题。

    ---------------------------
    在 Apache 中,打开和关闭 KeepAlive 功能,服务器端会有什么异同呢?

      先看看理论分析。

      打 开 KeepAlive 后,意味着每次用户完成全部访问后,都要保持一定时间后才关

    闭会关闭 TCP 连接,那么在关闭连接之前,必然会有一个 Apache 进程对应于该用户

    而不能处理其他用户,假设 KeepAlive 的超时时间为 10 秒种,服务器每秒处理 50

    个独立用户访问,那么系统中 Apache 的总进程数就是 10 * 50 = 500 个,如果一个

    进程占用 4M 内存,那么总共会消耗 2G 内存,所以可以看出,在这种配置中,相当消

    耗内存,但好处是系统只处理了 50次 TCP 的握手和关闭操作。
      如 果关闭 KeepAlive,如果还是每秒50个用户访问,如果用户每次连续的请求数

    为3个,那么 Apache 的总进程数就是 50 * 3 = 150 个,如果还是每个进程占用 4M

    内存,那么总的内存消耗为 600M,这种配置能节省大量内存,但是,系统处理了 150

    次 TCP 的握手和关闭的操作,因此又会多消耗一些 CPU 资源。

      在看看实践的观察。

      我 在一组大量处理动态网页内容的服务器中,起初打开 KeepAlive 功能,经常观

    察到用户访问量大时Apache进程数也非常多,系统频繁使用交换内存,系统不稳定,有

    时负载会出现较大波动。关闭了 KeepAlive 功能后,看到明显的变化是: Apache 的

    进程数减少了,空闲内存增加了,用于文件系统Cache的内存也增加了,CPU 的开销增

    加了,但是服务更稳定了,系统负载也比较稳定,很少有负载大范围波动的情况,负载

    有一定程度的降低;变化不明显的是:访问量较少的时候,系统平均 负载没有明显变

    化。


      总结一下:
      在内存非常充足的服务器上,不管是否关闭 KeepAlive 功能,服务器性能不会有

    明显变化;
      如果服务器内存较少,或者服务器有非常大量的文件系统访问时,或者主要处理动

    态网页服务,关闭 KeepAlive 后可以节省很多内存,而节省出来的内存用于文件系统

    Cache,可以提高文件系统访问的性能,并且系统会更加稳定。


      补充:
      关于是否应该关闭 KeepAlive 选项,我觉得可以基于下面的一个公式来判断。

    -----------------------------

      在理想的网络连接状况下,系统的 Apache 进程数和内存使用可以用如下公式表达


    HttpdProcessNumber = KeepAliveTimeout * TotalRequestPerSecond / Average

    (KeepAliveRequests)
    HttpdUsedMemory = HttpdProcessNumber * MemoryPerHttpdProcess
      换成中文:
    总Apache进程数 = KeepAliveTimeout * 每秒种HTTP请求数 / 平均KeepAlive请求
    Apache占用内存 = 总Apache进程数 * 平均每进程占用内存数

      需要特别说明的是:
      [平 均KeepAlive请求] 数,是指每个用户连接上服务器后,持续发出的 HTTP 请

    求数。当 KeepAliveTimeout 等 0 或者 KeepAlive 关闭时,KeepAliveTimeout 不参

    与乘的运算从上面的公式看,如果 [每秒用户请求] 多,[KeepAliveTimeout] 的值大

    ,[平均KeepAlive请求] 的值小,都会造成 [Apache进程数] 多和 [内存] 多,但是当

    [平均KeepAlive请求] 的值越大时,[Apache进程数] 和 [内存] 都是趋向于减少的。
      基于上面的公式,我们就可以推算出当 平均KeepAlive请求 <= KeepAliveTimeout

    时,关闭 KeepAlive 选项是划算的,否则就可以考虑打开。

    ---------------------
            最近发现一个比较奇怪的现象,某台以prefork模式工作的服务器的内存使用

    率在每次重启apache之后会不停的上涨,直到swap用完,直到死机。后来查出来是因为

    apache使用的某一些脚本存在内存泄露的代码段。而apache启动的调用这些代码段的进

    程的处理请求数被设置为无穷。也就是说这些进程只有在apache重启(stop-start模式

    )或者服务器(指的是机器)重启的情况下才会被kill,否则将一直运行下去,直到耗

    尽系统的最后一点资源(主要是内存)。

           问题貌似已经解决了。但是,还有点不对,就是为什么有将近4G的可用空间(

    内存2G加上swap2G,除去操作系统部分),资源还是很快就耗尽了?虽然进程在每处理

    一个请求的情况下都会吃掉一点内存,但是在看了内存泄露的那段代码后发现每次处理

    泄露的内存也不过2K左右。要消耗掉3G的空间,需要至少15.7w次请求。但是目前的手

    机统计平台上一天的点击量也不过5w。其实top命令下就能看出来,每个httpd进程的内

    存使用率有2.4%,3.2%等等。对于一个2G内存的服务器,一个进程2%就等于是40M。仅

    仅一个普通的请求,没有post参数的,没有大规模数据库查询的,怎么会用这么多内存

    ?httpd的进程在被apache的主控进程创建的时候,会预先加载一些包,这些包是在

    apache配置文件里设置的。然后发现在apache加载的包目录下,有一个很大的包,是用

    来根据手机号查找手机卡的信息的。去掉这个包之后,每个httpd的进程使用内存就正

    常了。

           总结有两点:

          1、MaxRequestsPerChild不能设置为0,最好设置为一个相对不大的数字,防止

    httpd进程有意外的内存泄露(当然,也不建议设置为1,否则apache就会不停的fork新

    的进程了,cpu的资源也就过多消耗了);

          2、不要加载过多的包,尤其是比较大的包。如果费用不可,最好能够用数据库

    来存储包里的一些静态信息。

    ----------------------

    计算httpd占用内存的平均数:
    ps aux|grep -v grep|awk '/httpd/{sum+=$6;n++};END{print sum/n}'

    由于基本都是静态页面,CPU消耗很低,每进程占用内存也不算多,大约200K。

    服务器内存有2G,除去常规启动的服务大约需要500M(保守估计),还剩1.5G可用,那

    么理论上可以支持1.5*1024*1024*1024/200000 = 8053.06368

    约8K个进程,支持2W人同时访问应该是没有问题的(能保证其中8K的人访问很快,其他

    的可能需要等待1、2秒才能连上,而一旦连上就会很流畅)

    控制最大连接数的MaxClients ,因此可以尝试配置为:
    <IfModule mpm_prefork_module>
                    StartServers                      5
                    MinSpareServers                   5
                    MaxSpareServers                  10
                    ServerLimit                    5500
                    MaxClients                     5000
                    MaxRequestsPerChild               100
    </IfModule>

    实时检测HTTPD连接数:
    watch -n 1 -d "pgrep httpd|wc -l"

    ----------------------
    工具:cronolog安装:http://www.cronolog.org

    ----------------------
    一般说来,可以不需要的模块包括:
    #LoadModule env_module libexec/mod_env.so
    #LoadModule negotiation_module libexec/mod_negotiation.so
    #LoadModule statuserials_module libexec/mod_status.so
    #server side include已经过时了
    #LoadModule includeserials_module libexec/mod_include.so
    #不需要将没有缺省index文件的目录下所有文件列出
    #LoadModule autoindex_module libexec/mod_autoindex.so
    #尽量不使用CGI:一直是APACHE安全问题最多的地方
    #LoadModule cgi_module libexec/mod_cgi.so
    #LoadModule asiserials_module libexec/mod_asis.so
    #LoadModule imap_module libexec/mod_imap.so
    #LoadModule action_module libexec/mod_actions.so
    #不使用安全校验可以大大提高访问速度
    #LoadModule accesserials_module libexec/mod_access.so
    #LoadModule auth_module libexec/mod_auth.so
    #LoadModule setenvif_module libexec/mod_setenvif.so

    最好保留的有:
    #用于定制log格式
    LoadModule config_log_module libexec/mod_log_config.so
    #用于增加文件应用的关联
    LoadModule mime_module libexec/mod_mime.so
    #用于缺省index文件:index.php等
    LoadModule dir_module libexec/mod_dir.so

    可用可不用的有:
    #比如:需要在~/username/下调试php可以将
    LoadModule userdir_module libexec/mod_userdir.so
    #比如:需要将以前的URL进行转向或者需要使用CGI scrīpt-alias
    LoadModule aliaserials_module libexec/mod_alias.so


    常用的模块:
    最常用的可能就是php和JAVA WEB应用的wrapper,此外,从性能上讲:mod_gzip可以减

    少40%左右的流量,从而减少机器用于传输的负载,而mod_expires可以减少10%左右的

    重复请求,让重复的用户请求CACHE在本地,根本不向服务器发出请求。

    一般将具体的resin设置放在另外一个文件中:
    <IfModule mod_caucho.c>
    CauchoConfigFile /path/to/apache/conf/resin.conf
    </IfModule>

    mod_expires的安装配置:
    <IfModule mod_expires.c>
    ExpiresActive on
    #所有的.gif文件1个月以后过期
    ExpiresByType image/gif "access plus 1 month"
    #所有的文件缺省1天以后过期
    ExpiresDefault "now plus 1 day"
    </IfModule>

    mod_gzip的安装:
    /path/to/apache/bin/apxs -i -a -c mod_gzip.c

    mod_gzip和PHP在一起的配置
    <IfModule mod_gzip.c>
    mod_gzip_on Yes
    mod_gzip_minimum_file_size 1000
    mod_gzip_maximum_file_size 300000
    mod_gzip_item_include file .htm$
    mod_gzip_item_include file .html$
    mod_gzip_item_include file .php$
    mod_gzip_item_include file .php3$
    mod_gzip_item_include mime text/.*
    mod_gzip_item_include mime httpd/unix-directory
    #不要让mod_gzip和php的session使用同一个临时目录:php_session需要通过php.ini

    设置session.save_path = /tmp/php_sess
    mod_gzip_temp_dir /tmp/mod_gzip
    mod_gzip_dechunk Yes
    mod_gzip_keep_workfiles No
    </IfModule>

    mod_gzip和mod_php的配合:不要让mod_gzip和mod_php使用同一个临时目录;

    mod_gzip和RESIN配合:要让mod_gzip在mod_caucho后LOAD,否则mod_gzip不起作用
    ...othr modules
    AddModule mod_so.c
    AddModule mod_caucho.c
    #notice: mod_gzip must load after mod_caucho
    AddModule mod_gzip.c
    AddModule mod_expires.c
    ...

    <IFModule mod_gzip.c>
    mod_gzip_on Yes
    mod_gzip_dechunk yes
    mod_gzip_keep_workfiles No
    mod_gzip_minimum_file_size 3000
    mod_gzip_maximum_file_size 300000
    mod_gzip_item_include file .html$
    mod_gzip_item_include mime text/.*
    mod_gzip_item_include mime httpd/unix-directory
    mod_gzip_item_include handler 'caucho-request'
    </IFModule>

    日志轮循工具cronolog的安装和设置:cronolog可以非常整齐的将日志按天轮循存储
    缺省编译安装到/usr/local/bin/下,只需要将配置改成:

    CustomLog "|/usr/local/sbin/cronolog /path/to/apache/logs/%

    w/accesserials_log" combined

    日志将按天截断并存放在以weekday为目录名的目录下:比如:log/1是周一,log/5是

    周五, log/0是周日

    Apache安装后,缺省根目录下没有但很有用的2个文件:

    favicon.ico: favicon.ico是一个16x16的站点图标文件,如果浏览器发现有这个文件

    ,在地址栏中会用这个图标替换调浏览器的网页图标。IE6和MOZILLA等主流浏览器都支

    持这个功能。
    robots.txt: 用于告诉搜索引擎的爬虫程序(spider)网站那些页面可以被索引,那些

    不可以。具体说明请参考:
    http://www.robotstxt.org/wc/robots.html 


     

  • Web站点崩溃的原因总结(还是摘抄)

    2008-04-03 23:18:07

    Web站点崩溃的原因总结

    有许多种原因可能导致Web站点无法正常工作,这使得系统地检查所有问题变得很困难。下面将集中分析总结导致Web站点崩溃的最常见的问题。如果可以解决这些常规问题,那么也将有能力对付出现的一些意外情况。

       磁盘已满

      导致系统无法正常运行的最可能的原因是磁盘已满。一个好的网络管理员会密切关注磁盘的使用情况,隔一定的时间,就需要将磁盘上的一些负载转存到备份存储介质中(例如磁带)。

      日志文件会很快用光所有的磁盘空间。Web服务器的日志文件、SQL*Net的日志文件、JDBC日志文件,以及应用程序服务器日志文件均与内存泄漏有同等的危害。可以采取措施将日志文件保存在与操作系统不同的文件系统中。日志文件系统空间已满时Web服务器也会被挂起,但机器自身被挂起的几率已大大减低。

       C指针错误

      用C或C++编写的程序,如Web服务器API模块,有可能导致系统的崩溃,因为只要间接引用指针(即,访问指向的内存)中出现一个错误,就会导致操作系统终止所有程序。另外,使用了糟糕的C指针的Java模拟量(analog)将访问一个空的对象引用。Java中的空引用通常不会导致立刻退出JVM,但是前提是程序员能够使用异常处理方法恰当地处理错误。在这方面,Java无需过多的关注,但使用Java对可靠性进行额外的度量则会对性能产生一些负面影响。

       内存泄漏

      C/C++程序还可能产生另一个指针问题:丢失对已分配内存的引用。当内存是在子程序中被分配时,通常会出现这种问题,其结果是程序从子程序中返回时不会释放内存。如此一来,对已分配的内存的引用就会丢失,只要操作系统还在运行中,则进程就会一直使用该内存。这样的结果是,曾占用更多的内存的程序会降低系统性能,直到机器完全停止工作,才会完全清空内存。

      解决方案之一是使用代码分析工具(如Purify)对代码进行仔细分析,以找出可能出现的泄漏问题。但这种方法无法找到由其他原因引起的库中的泄漏,因为库的源代码是不可用的。另一种方法是每隔一段时间,就清除并重启进程。Apache的Web服务器就会因这个原因创建和清除子进程。

      虽然Java本身并无指针,但总的说来,与C程序相比,Java程序使用内存的情况更加糟糕。在Java中,对象被频繁创建,而直到所有到对象的引用都消失时,垃圾回收程序才会释放内存。即使运行了垃圾回收程序,也只会将内存还给虚拟机VM,而不是还给操作系统。结果是:Java程序会用光给它们的所有堆,从不释放。由于要保存实时(Just In Time,JIT)编译器产生的代码,Java程序的大小有时可能会膨胀为最大堆的数倍之巨。

      还有一个问题,情况与此类似。从连接池分配一个数据库连接,而无法将已分配的连接还回给连接池。一些连接池有活动计时器,在维持一段时间的静止状态之后,计时器会释放掉数据库连接,但这不足以缓解糟糕的代码快速泄漏数据库连接所造成的资源浪费。

       进程缺乏文件描述符

      如果已为一台Web服务器或其他关键进程分配了文件描述符,但它却需要更多的文件描述符,则服务器或进程会被挂起或报错,直至得到了所需的文件描述符为止。文件描述符用来保持对开放文件和开放套接字的跟踪记录,开放文件和开放套接字是Web服务器很关键的组成部分,其任务是将文件复制到网络连接。默认时,大多数shell有64个文件描述符,这意味着每个从shell启动的进程可以同时打开64个文件和网络连接。大多数shell都有一个内嵌的ulimit命令可以增加文件描述符的数目。

       线程死锁

      由多线程带来的性能改善是以可靠性为代价的,主要是因为这样有可能产生线程死锁。线程死锁时,第一个线程等待第二个线程释放资源,而同时第二个线程又在等待第一个线程释放资源。我们来想像这样一种情形:在人行道上两个人迎面相遇,为了给对方让道,两人同时向一侧迈出一步,双方无法通过,又同时向另一侧迈出一步,这样还是无法通过。双方都以同样的迈步方式堵住了对方的去路。假设这种情况一直持续下去,这样就不难理解为何会发生死锁现象了。

      解决死锁没有简单的方法,这是因为使线程产生这种问题是很具体的情况,而且往往有很高的负载。大多数软件测试产生不了足够多的负载,所以不可能暴露所有的线程错误。在每一种使用线程的语言中都存在线程死锁问题。由于使用Java进行线程编程比使用C容易,所以Java程序员中使用线程的人数更多,线程死锁也就越来越普遍了。可以在Java代码中增加同步关键字的使用,这样可以减少死锁,但这样做也会影响性能。如果负载过重,数据库内部也有可能发生死锁。

      如果程序使用了永久锁,比如锁文件,而且程序结束时没有解除锁状态,则其他进程可能无法使用这种类型的锁,既不能上锁,也不能解除锁。这会进一步导致系统不能正常工作。这时必须手动地解锁。

       服务器超载

      Netscape Web服务器的每个连接都使用一个线程。Netscape Enterprise Web服务器会在线程用完后挂起,而不为已存在的连接提供任何服务。如果有一种负载分布机制可以检测到服务器没有响应,则该服务器上的负载就可以分布到其它的Web服务器上,这可能会致使这些服务器一个接一个地用光所有的线程。这样一来,整个服务器组都会被挂起。操作系统级别可能还在不断地接收新的连接,而应用程序(Web服务器)却无法为这些连接提供服务。用户可以在浏览器状态行上看到connected(已连接)的提示消息,但这以后什么也不会发生。

      解决问题的一种方法是将obj.conf参数RqThrottle的值设置为线程数目之下的某个数值,这样如果越过RqThrottle的值,就不会接收新的连接。那些不能连接的服务器将会停止工作,而连接上的服务器的响应速度则会变慢,但至少已连接的服务器不会被挂起。这时,文件描述符至少应当被设置为与线程的数目相同的数值,否则,文件描述符将成为一个瓶颈。

       数据库中的临时表不够用

      许多数据库的临时表(cursor)数目都是固定的,临时表即保留查询结果的内存区域。在临时表中的数据都被读取后,临时表便会被释放,但大量同时进行的查询可能耗尽数目固定的所有临时表。这时,其他的查询就需要列队等候,直到有临时表被释放时才能再继续运行。

      这是一个不容易被程序员发觉的问题,但会在负载测试时显露出来。但可能对于数据库管理员(DataBase Administrator,DBA)来说,这个问题十分明显。

      此外,还存在一些其他问题:设置的表空间不够用、序号限制太低,这些都会导致表溢出错误。这些问题表明了一个好的DBA对用于生产的数据库设置和性能进行定期检查的重要性。而且,大多数数据库厂商也提供了监控和建模工具以帮助解决这些问题。

      另外,还有许多因素也极有可能导致Web站点无法工作。如:相关性、子网流量超载、糟糕的设备驱动程序、硬件故障、包括错误文件的通配符、无意间锁住了关键的表。
  • too many sleep connections to handle (二)

    2008-04-02 22:41:42

    摘抄:
    在项目应用部署中却频繁出现的问题。
       这些问题都有很多比较明显的共同点,也大多集中在如下情况中:
       (1)连接池和数据库服务器,表现为大量sleeping connection未释放
       (2)应用程序获取的连接为stale connection(无效连接)
       (3)数据库服务器重起后,应用服务器也需要重起
       在应用部署过程中,为了在获取尽可能高效的数据库连接处理,采用应用服务器的连接池,这是个正确的选择。几乎所有的项目组都会这么做,而且配置和应用也都没有什么难度。—— 但是很不幸运,正是很多人所寄予厚望的应用服务器连接池,却很容易忽悠大家,在系统运行运行一段时间后,会毫无情面的抛出获取连接超时、失败,或者报告这是一个无效的连接······等等匪夷所思的问题。
       正是 连接池的“池缓存”的功能,让数据库连接能够高效的利用;但也正是“池缓存”的功能,让这些问题不断的暴露出来,正所谓“成也萧何,败也萧何”。
       因为在池中缓冲的那些“Connection”,有很多是刚刚被Client端释放,但是连接池本身来却没有去close它们,而是依然“维持”连接,以期等待后续其他Client的请求。—— 但是就是这么一段可能并不长的时间,却有着很多潜在的危险:此时网络有一定的不稳定,池中原本与数据库保持连接的Connection,却因此而中断了通讯——但是此时连接池依然以为这个一个有效的Connection返回给了Client······结果大家可想而知。
       真实的原因可能比这更加复杂,也更多种情况,也因此就造成了上面那些种异常的发生。
       其实,解决这些异常,本身不是很难,而且几乎当前所有的应用服务器连接池都提供了支持,甚至包括很多开源的连接池组件,比如Apache DBCP。
       解决诸如此类连接池异常问题,把握如下两个关键点即可:
       (1)打开应用服务器连接池的“续连接支持开关”,就是说,在把池中的Connection对象返给Client端的时候(或从Client端回收的时候)做一次有效性验证,以确定这是一个有效连接。
       (2)打开连接池的无效连接定期回收机制,就是说,让连接池每经过一段时间,就对连接池中的那些已经无效的连接进行回收。(但切记,这样的回收操作尽量不要过于频繁)
       下面就拿Weblogic和WebShpere两款应用服务来说明,如何设置它们连接池的“续连接”和“回收”机制
      (一)WebLogic Application Server
       (1)weblogic的连接验证设置:
       WLS里设置连接的检查,一个是获取连接的时候检查该连接是否有效,另外一个就是释放连接的时候检查。这两个检查在配置连接池的时候都是可以设置的。
       TestConnectionsOnReserve 从连接池获取连接后是否进行有效性测试 True/false
       RefreshMinutes parameter 设定connection pool的刷新时间 刷新的时间间隔
       Test Table Name 测试的表名,也可以指定SQL 表名或者是SQL
       (2)weblogic的无效连接回收时间设置:
       通过设置weblogic-ra.xml中的inactive-connection-timeout-seconds,weblogic连接池会根据设置,主动关闭那些超时idle的connection。关于weblogic-ra.xm的文档如下:
       http://e-docs.bea.com/wls/docs81/jconnector/dtdappen.html#1031211
      (二)Webshpere Application Server
       (1)首先需要通过修改配置文件来启动预连接测试功能。主要是修改$WAS_HOME/properties/j2c.properties 配置文件,修改后重新启动服务器。
      修改advanced-connection-properties 元素,jdbc/DataSource应替换为用户的数据源的JNDI名称。
      testConnection必须设为true,以表明用户启动预连接测试功能。
      testConnectionRetryInterval为预连接测试失败后重试间隔的秒数。
       (2)其次需要配置预连接测试语句:
       WebSphere的管理控制台,定位Resources > JDBC_provider > Data Sources > data_source > Custom Properties 。
       新建一个用户属性,指定 preTestSQLString (大小写敏感) 作为属性名,指定要测试的SQL语句作为属性值。
       注:这条SQL语句是用来检查连接是否有效的,必须用有效的SQL语句,并且需要执行速度最快,占用资源最少。每次用户发出数据库连接请求时WebSphere会先调用这条语句做连接尝试。DB2数据库用户可以选择SELECT 1 FROM SYSIBM.SYSDUMMY1 。Oracle用户可以选择SELECT USER FROM DUAL作为测试连接语句。
       但是,在应用过程中,不代表所有的应用连接池部署都需要开启“续连接”或“回收”,这是因为,续连接回造成每次获取连接的时间会无形的增加,而“回收”操作则会比较占用资源,如果过于频繁,则影响了系统响应效率。
       所以,这两项连接池的服务,是否一定需要开启,则要根据应用特点来分别对待了。
  • TOP详解(摘抄)

    2008-04-02 22:11:20

    01:06:48当前时间
    up 1:22系统运行时间,格式为时:分
    1 user当前登录用户数
    load average: 0.06, 0.60, 0.48系统负载,即任务队列的平均长度。
    三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。

    Tasks: 29 total进程总数
    1 running正在运行的进程数
    28 sleeping睡眠的进程数
    0 stopped停止的进程数
    0 zombie僵尸进程数

    (stop模式:与sleep进程应区别,sleep会主动放弃cpu,而stop是被动放弃cpu ,例单步跟踪,stop(暂停)的进程是无法自己回到运行状态的)


    Cpu(s): 0.3% us用户空间占用CPU百分比
    1.0% sy内核空间占用CPU百分比
    0.0% ni用户进程空间内改变过优先级的进程占用CPU百分比
    98.7% id空闲CPU百分比
    0.0% wa等待输入输出的CPU时间百分比
    0.0% hi
    0.0% si

    Mem: 191272k total物理内存总量
    173656k used使用的物理内存总量
    17616k free空闲内存总量
    22052k buffers用作内核缓存的内存量
    Swap: 192772k total交换区总量
    0k used使用的交换区总量
    192772k free空闲交换区总量
    123988k cached缓冲的交换区总量。
    内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,
    该数值即为这些内容已存在于内存中的交换区的大小。
    相应的内存再次被换出时可不必再对交换区写入。

    序号列名含义
    aPID进程id
    bPPID父进程id
    cRUSERReal user name
    dUID进程所有者的用户id
    eUSER进程所有者的用户名
    fGROUP进程所有者的组名
    gTTY启动进程的终端名。不是从终端启动的进程则显示为 ?
    hPR优先级
    iNInice值。负值表示高优先级,正值表示低优先级
    jP最后使用的CPU,仅在多CPU环境下有意义
    k%CPU上次更新到现在的CPU时间占用百分比
    lTIME进程使用的CPU时间总计,单位秒
    mTIME+进程使用的CPU时间总计,单位1/100秒
    n%MEM进程使用的物理内存百分比
    oVIRT进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
    pSWAP进程使用的虚拟内存中,被换出的大小,单位kb。
    qRES进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
    rCODE可执行代码占用的物理内存大小,单位kb
    sDATA可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
    tSHR共享内存大小,单位kb
    unFLT页面错误次数
    vnDRT最后一次写入到现在,被修改过的页面数。
    wS进程状态。
    D=不可中断的睡眠状态
    R=运行
    S=睡眠
    T=跟踪/停止
    Z=僵尸进程

    进程的状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数。
    xCOMMAND命令名/命令行
    yWCHAN若该进程在睡眠,则显示睡眠中的系统函数名
    zFlags任务标志,参考 sched.h

  • too many sleep connection in mysql

    2008-04-01 22:58:30

    结合netstat和awk命令来统计网络连接数
    From: http://hi.baidu.com/thinkinginlamp/blog/item/afbcab64b1ad81f3f6365453.html

    netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

    会得到类似下面的结果,具体数字会有所不同:

    LAST_ACK 1
    SYN_RECV 14
    ESTABLISHED 79
    FIN_WAIT1 28
    FIN_WAIT2 3
    CLOSING 5
    TIME_WAIT 1669

    状态:描述
    CLOSED:无连接是活动的或正在进行
    LISTEN:服务器在等待进入呼叫
    SYN_RECV:一个连接请求已经到达,等待确认
    SYN_SENT:应用已经开始,打开一个连接
    ESTABLISHED:正常数据传输状态
    FIN_WAIT1:应用说它已经完成
    FIN_WAIT2:另一边已同意释放
    ITMED_WAIT:等待所有分组死掉
    CLOSING:两边同时尝试关闭
    TIME_WAIT:另一边已初始化一个释放
    LAST_ACK:等待所有分组死掉

    也就是说,这条命令可以把当前系统的网络连接状态分类汇总。

    下面解释一下为啥要这样写:

    一个简单的管道符连接了netstat和awk命令。

    ------------------------------------------------------------------

    先来看看netstat:

    netstat -n

    Active Internet connections (w/o servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State
    tcp 0 0 123.123.123.123:80 234.234.234.234:12345 TIME_WAIT

    你实际执行这条命令的时候,可能会得到成千上万条类似上面的记录,不过我们就拿其中的一条就足够了。

    ------------------------------------------------------------------

    再来看看awk:

    /^tcp/
    滤出tcp开头的记录,屏蔽udp, socket等无关记录。

    state[]
    相当于定义了一个名叫state的数组

    NF
    表示记录的字段数,如上所示的记录,NF等于6

    $NF
    表示某个字段的值,如上所示的记录,$NF也就是$6,表示第6个字段的值,也就是TIME_WAIT

    state[$NF]
    表示数组元素的值,如上所示的记录,就是state[TIME_WAIT]状态的连接数

    ++state[$NF]
    表示把某个数加一,如上所示的记录,就是把state[TIME_WAIT]状态的连接数加一

    END
    表示在最后阶段要执行的命令

    for(key in state)
    遍历数组

    print key,"\t",state[key]
    打印数组的键和值,中间用\t制表符分割,美化一下。

    如发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,
    vim /etc/sysctl.conf
    编辑文件,加入以下内容:
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 30

    然后执行 /sbin/sysctl -p 让参数生效。

    net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
    net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
    net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
    net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

    下面附上TIME_WAIT状态的意义:

    客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口
    状态为TIME_WAIT

    是不是所有执行主动关闭的socket都会进入TIME_WAIT状态呢?
    有没有什么情况使主动关闭的socket直接进入CLOSED状态呢?

    主动关闭的一方在发送最后一个 ack 后
    就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间
    这个是TCP/IP必不可少的,也就是“解决”不了的。

    也就是TCP/IP设计者本来是这么设计的
    主要有两个原因
    1。防止上一次连接中的包,迷路后重新出现,影响新连接
    (经过2MSL,上一次连接中所有的重复包都会消失)
    2。可靠的关闭TCP连接
    在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发
    fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以
    主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。

    TIME_WAIT 并不会占用很大资源的,除非受到攻击。

    还有,如果一方 send 或 recv 超时,就会直接进入 CLOSED 状态

  • php 内存占用(问/答)

    2008-03-25 22:44:38

    问:
    变量创建  class 使用 等 对内存的占用 情况如何?

    决定内存高占用的都有哪些因素?
    ______________________________________________________________________________________________
    答1:
    这和zend的引擎有关
    没研究过PHP这方面的代码
    帮你顶一下
    ______________________________________________________________________________________________
    答2:
    变量存储的数据是不是很大,如果是用完变量记得unset一下。
    数据库查询时候条件允许的化用一些专用函数,比如mysql_unbuffered_query,
    ______________________________________________________________________________________________
    答3:
    个人感觉对资源的消耗更多的是在服务器方面,像APACHE占用的资源.
    ______________________________________________________________________________________________
    答4:
    up 高手继续谈下经常验
    ______________________________________________________________________________________________
    答5:
    程序冗余代码多,内存就占用高。
    ______________________________________________________________________________________________
    答6:
    内存的管理由操作系统进行,php通过c函数alloc向操作系统申请内存空间。注意这个申请是申请一块连续的空间,若申请不到则php将不断的发出申请直到申请成功。你最好在服务器上安装内存整理软件来回收闲散的内存碎片。
    php向系统申请的空间不会超过php.ini中memory_limit的设置,该空间包括php进(线)程
    php向系统申请的空间在php进(线)程结束时将自动释放,但有未关闭的数据库连接时,这一动作将延迟一段时间。

    ______________________________________________________________________________________________
    答7:
    如果其中涉及到共享内存的情况的话 考虑到unix/windows系统,情况是不一样的
    ______________________________________________________________________________________________
    答8:
    多用户访问 时 这时的内存使用是怎样的呢?
    如: 1000 个用户同时访问    
    程序中的 $var = values;
    是每个用户都创建一次 单独占用一块内存    还是共享使用?

    在程序结整时 会自动释放这些内存的占用?    还是需要自己unset 他们?
    ______________________________________________________________________________________________
    答9:
    不是已经说了吗?每个连接独占不大于memory_limit的内存,用完后有php释放。自己unset可以减少向系统请求的空间,但作用不大
    ____________________________________________________________________________________

  • PHP优化(摘抄)

    2008-03-20 22:35:43

    PHP is a very fast programming language, but there is more to optimizing PHP than just speed of code execution.
    php 是一个高效的语言,不过优化php不仅仅是优化程序的代码

    In this chapter, we explain why optimizing PHP involves many factors which are not code related, and why tuning PHP requires an understanding of how PHP performs in relation to all the other subsystems on your server, and then identifying bottlenecks caused by these subsystems and fixing them. We also cover how to tune and optimize your PHP scrīpts so they run even faster.

    在这篇文章中,我们将揭示为什么优化php包括很多代码没有涉及的因素。和为什么调整php需要理解你的服务器上的所有子系统上PHP的表现并寻找出由这些系统引起的瓶颈并修复他们。当然这也适用于调整和优化你的PHP脚本来使他们运行的更快。

    Achieving High Performance
    达到高性能

    When we talk about good performance, we are not talking about how fast your PHP scrīpts will run. Performance is a set of tradeoffs between scalability and speed. scrīpts tuned to use fewer resources might be slower than scrīpts that perform caching, but more copies of the same scrīpt can be run at one time on a web server.
    当我们谈及高性能时,我们不是谈论你的PHP脚本如何的快。性能是在资源占用和速度之间的折中。调整脚本去使用更少的资源会比使用更多的缓存要慢。但是可以有更多的拷贝同时在服务器上运行[就是我们常说的以资源换速度还是以速度换资源—by achieverain]

    In the example below, A.php is a sprinter that can run fast, and B.php is a marathon runner than can jog forever at the nearly the same speed. For light loads, A.php is substantially faster, but as the web traffic increases, the performance of B.php only drops a little bit while A.php just runs out of steam.
    在下面的例子中,A.php 是一个跑的很快的短跑选手。B.php是一个可以永远跑下去的马拉松选手。在轻量级负载中。A.php绝对领先,但是当网页的流量增加时,B.php的速度仅仅下降了一点,但A.php已经被淘汰了。

    Let us take a more realistic example to clarify matters further. Suppose we need to write a PHP scrīpt that reads a 250K file and generates a HTML summary of the file. We write 2 scrīpts that do the same thing: hare.php that reads the whole file into memory at once and processes it in one pass, and tortoise.php that reads the file, one line at time, never keeping more than the longest line in memory. Tortoise.php will be slower as multiple reads are issued, requiring more system calls.
    让我们举更过的类似的例子来证明这个事实。假设我们需要写一个读取一个250k大小的文件并生成一个HTML摘要文件。我们同时写两个脚本来做这个事情:hare.php[hare 是兔子的意思 –by achieverain]每次运行直接把整个文件读入内存,tortoise.php[tortoise 是乌龟的意思 –by achieverain]每次只读文件的一行,并且让内存的数据保持在一行。Tortoise.php当然因为因为多次的读取而更慢,需要更多次的系统调用

    Hare.php requires 0.04 seconds of CPU and 10 Mb RAM and tortoise.php requires 0.06 seconds of CPU and 5 Mb RAM. The server has 100 Mb free actual RAM and its CPU is 99% idle. Assume no memory fragmentation occurs to simplify things.
    hare.php 需要CPU运行0.04秒。10M 内存,tortoise.php 需要CPU运行0.06秒。5M 内存,服务器有100M的空闲物理内存,CPU的空闲资源(idle)为99%.简单起见:假设没有内存碎片。

    At 10 concurrent scrīpts running, hare.php will run out of memory (10 x 10 = 100). At that point, tortoise.php will still have 50 Mb of free memory. The 11th concurrent scrīpt to run will bring hare.php to its knees as it starts using virtual memory, slowing it down to maybe half its original speed; each invocation of hare.php now takes 0.08 seconds of CPU time. Meanwhile, tortoise.php will be still be running at its normal 0.06 seconds CPU time.
    在10个并发的情况下,hare.php将把所有的内存用完(10 x 10 = 100)。而tortoise.php将还有50M的剩余内存。如果要同时运行第11个 hare.php将是服务器使用虚拟内存,降低的速度也许是原始速度的一般;每次调用hare.php将消耗0.08秒,与此同时,tortoise.php将仍然是0.06秒。
    In the table below, the faster php scrīpt for different loads is in bold:
    在下面的图表中,不同负载情况下更快的php脚本将被加黑。
    Connections
    CPU seconds required to satisfy 1 HTTP request
    CPU seconds required to satisfy 10 HTTP requests
    CPU seconds required to satisfy 11 HTTP requests

    hare.php
    0.04
    0.40
    0.88
    (runs out of RAM)

    tortoise.php
    0.06
    0.60
    0.66

    As the above example shows, obtaining good performance is not merely writing fast PHP scrīpts. High performance PHP requires a good understanding of the underlying hardware, the operating system and supporting software such as the web server and database.
    由上可知,取得良好的表现并不仅仅是写一个高速的php脚本。高性能的PHP需要很好的理解程序所基于的硬件基础,操作系统,web server [如apache]和数据库之类的支援软件

    Bottlenecks
    瓶颈

    The hare and tortoise example has shown us that bottlenecks cause slowdowns. With infinite RAM, hare.php will always be faster than tortoise.php. Unfortunately, the above model is a bit simplistic and there are many other bottlenecks to performance apart from RAM:
    刚才那个例子给我们展示了瓶颈的存在导致速度降低,如果有无限的内存,hare.php将永远比tortoise.php跑的快。不幸的是,上面的有点太单纯了,而且很多其他的瓶颈也在蚕食着内存。

    (a) Networking
    (a)网络

    Your network is probably the biggest bottleneck. Let us say you have a 10 Mbit link to the Internet, over which you can pump 1 megabyte of data per second. If each web page is 30k, a mere 33 web pages per second will saturate the line.
    你的网络情况也许会是一个最大的瓶颈。假设服务器带宽10Mbit那么你每秒能传输大约1Mbyte数据。如果每个网页30K,那么你每秒最多传输33个网页。
    More subtle networking bottlenecks include frequent access to slow network services such as DNS, or allocating insufficient memory for networking software.
    更多在网络不佳时导致访问速度降低的原因有DNS或者内存不足等。
    (b) CPU
    (b) CPU

    If you monitor your CPU load, sending plain HTML pages over a network will not tax your CPU at all because as we mentioned earlier, the bottleneck will be the network. However for the complex dynamic web pages that PHP generates, your CPU speed will normally become the limiting factor. Having a server with multiple processors or having a server farm can alleviate this.
    如果你控制你的CPU负载。发送一个无格式的HTML页基本不占用你的CPU资源。然而一个完全由PHP生成的动态页会占用很多CPU资源。多CPU服务器或者服务器集群可以缓解这个问题。

    (c) Shared Memory
    (c) 共享内存

    Shared memory is used for inter-process communication, and to store resources that are shared between multiple processes such as cached data and code. If insufficient shared memory is allocated any attempt to access resources that use shared memory such as database connections or executable code will perform poorly.
    共享内存是为进程间通讯准备的,如果系统内存不足的话,使用共享内存的操作如 数据库联接,执行代码将会是低效的。
    (d) File System
    (d) 文件系统

    Accessing a hard disk can be 50 to 100 times slower than reading data from RAM. File caches using RAM can alleviate this. However low memory conditions will reduce the amount of memory available for the file-system cache, slowing things down. File systems can also become heavily fragmented, slowing down disk accesses. Heavy use of symbolic links on Unix systems can slow down disk accesses too.
    访问硬盘比访问内存要慢50到100倍。将文件缓存存入内存可以解决这个问题。但是服务器内存会被文件缓存的数据大量占用,反而将系统速度减慢。严重的文件碎片也会降低访问硬盘的速度,在Unix系统上大量使用符号链接也会降低访问硬盘的速度

    Default Linux installs are also notorious for setting hard disk default settings which are tuned for compatibility and not for speed. Use the command hdparm to tune your Linux hard disk settings.
    默认设置下安装的linux有个糟糕的问题就是硬盘的设置是兼容性优先而不是速度。使用 hdparm 这个命令可以调整你的linux硬盘的设置
    (e) Process Management
    (e) 进程管理

    On some operating systems such as Windows creating new processes is a slow operation. This means CGI applications that fork a new process on every invocation will run substantially slower on these operating systems. Running PHP in multi-threaded mode should improve response times (note: older versions of PHP are not stable in multi-threaded mode).
    在windows等的操作系统中建立一个新的进程是个缓慢的操作。这意味着CGI软件在这些系统上的调用是缓慢的。在多线程模式下运行PHP可以加快速度(注意:老版本的PHP不支持多线程模式)

    Avoid overcrowding your web server with too many unneeded processes. For example, if your server is purely for web serving, avoid running (or even installing) X-Windows on the machine. On Windows, avoid running Microsoft Find Fast (part of Office) and 3-dimensional screen savers that result in 100% CPU utilization.
    避免你的服务器被过多没有必要的进程所拥塞。例如:假如你的服务器纯粹用于网站服务,不在服务器上运行(甚至安装)X-Windows,在windows上,不运行Microsoft Find Fast (part of Office)和3D屏保可以防止100%CPU的情况

    Some of the programs that you can consider removing include unused networking protocols, mail servers, antivirus scanners, hardware drivers for mice, infrared ports and the like. On Unix, I assume you are accessing your server using SSH. Then you can consider removing:

    deamons such as telnetd, inetd, atd, ftpd, lpd, sambad
    sendmail for incoming mail
    portmap for NFS
    xfs, fvwm, xinit, X

    You can also disable at startup various programs by modifying the startup files which are usually stored in the /etc/init* or /etc/rc*/init* directory.

    Also review your cron jobs to see if you can remove them or reschedule them for off-peak periods.

    (f) Connecting to Other Servers

    一些你可以考虑移除的网络控制软件,邮件服务器,杀毒软件,鼠标驱动,红外驱动等等一些.在Unix上,我认为你是通过SSH访问的网站.那么你就可以考虑移除一些像  
    telnetd, inetd, atd, ftpd, lpd, sambad
    sendmail for incoming mail
    portmap for NFS
    xfs, fvwm, xinit, X
    之类的服务,你也可以考虑仅用一些启动时加载的项目.你可以通过修改 /etc/init* 或/etc/rc*/init*的启动配置文件来实现他们的配置.你一个可以看下你的计划任务,不需要的就移除,需要执行的就把他放在没人访问服务器的时候执行.

    If your web server requires services running on other servers, it is possible that those servers become the bottleneck. The most common example of this is a slow database server that is servicing too many complicated SQL requests from multiple web servers.
    如果你的服务器需要一些在其他服务器上运行的服去.这也许也会成为一个瓶颈.最常见的例子就是一个缓慢的或者被过多连接拥塞的数据库服务器

    When to Start Optimizing?
    什么时候开始优化?

    Some people say that it is better to defer tuning until after the coding is complete. This advice only makes sense if your programming team's coding is of a high quality to begin with, and you already have a good feel of the performance parameters of your application. Otherwise you are exposing yourselves to the risk of having to rewrite substantial portions of your code after testing.
    一些人说最好推迟到代码完成之后.这个建议指挥令你感觉到你的程序员团队有高质量的代码,你已经对你的程序表现十分满意.否则就是你认为你将在测试之后重写你的部分代码

    My advice is that before you design a software application, you should do some basic benchmarks on the hardware and software to get a feel for the maximum performance you might be able to achieve. Then as you design and code the application, keep the desired performance parameters in mind, because at every step of the way there will be tradeoffs between performance, availability, security and flexibility.

    我的建议是在你设计一个程序之前,你就应该做一些你可以做到的能够提升性能的基准。然后你开始设计软件的代码。在脑子里时刻想着这些准则,因为每一步设计都有可能是你在性能,实用性,安全性,易用性的折中方案。

    Also choose good test data. If your database is expected to hold 100,000 records, avoid testing with only a 100 record database – you will regret it. This once happened to one of the programmers in my company; we did not detect the slow code until much later, causing a lot of wasted time as we had to rewrite a lot of code that worked but did not scale.

    选择良好的测试用数据。如果你的数据库将要承载100,000条记录,避免使用只有100条记录的数据库进行测试–这样会让你后悔的.这种事情曾经在我所在的公司的一个程序员身上发生过:我们没有发现导致缓慢的代码.直到很久以后,程序执行消耗了大量时间.我们不得不重写达赖能够的数据.

    Tuning Your Web Server for PHP
    为PHP调整你的服务器

    We will cover how to get the best PHP performance for the two most common web servers in use today, Apache 1.3 and IIS. A lot

    of the advice here is relevant for serving HTML also.
    接下来我们谈谈如何在现今最流行的两个网络服务器平台 Apache 和 IIS 上让PHP取得最好的的表现。这里也有很多关于HTML的建议(??)

    The authors of PHP have stated that there is no performance nor scalability advantage in using Apache 2.0 over Apache 1.3

    with PHP, especially in multi-threaded mode. When running Apache 2.0 in pre-forking mode, the following discussion is still

    relevant (21 Oct 2003).
    PHP的作者统计过PHP在 Apache 2.0 上的表现比apache 1.3 上的表现在实际上并没有实质的优势,尤其在多线程模式下。当在apache 2.0的预

    编译模式下运行。他们的讨论结果也是类似的

    (a) Apache 1.3/2.0
    (a) Apache 1.3/2.0

    Apache is available on both Unix and Windows. It is the most popular web server in the world. Apache 1.3 uses a pre-forking

    model for web serving. When Apache starts up, it creates multiple child processes that handle HTTP requests. The initial

    parent process acts like a guardian angel, making sure that all the child processes are working properly and coordinating

    everything. As more HTTP requests come in, more child processes are spawned to process them. As the HTTP requests slow down,

    the parent will kill the idle child processes, freeing up resources for other processes. The beauty of this scheme is that it

    makes Apache extremely robust. Even if a child process crashes, the parent and the other child processes are insulated from

    the crashing child.

    Apache 在Unix和Windows都可以使用。他是世界上最流行的网络服务器。apache为网络服务使用了预编译模式(pre-forking model)。当

    apache启动时。他创建了多个等待http请求的子进程。最初的父进程(parent process)就像个守护天使,他保证那些子进程在正常工作。当出现

    更多的HTTP请求时,更多的子进程被创建。当HTTP请求减少时,空闲的子进程就会被结束,他们(子进程)占用的资源也将会被释放。这种完美

    的配置使Apache高效的运行。甚至当一个子进程崩溃时,父进程将把它和其他子进程隔离。
    The pre-forking model is not as fast as some other possible designs, but to me that it is "much ado about nothing" on a

    server serving PHP scrīpts because other bottlenecks will kick in long before Apache performance issues become significant.

    The robustness and reliability of Apache is more important.
    预编译模式并不比其他一些必要的设计/实现更快。但是对于我们来说在其他瓶颈影响apache性能之前这个是非常简单的。apache的稳定和可靠

    是更重要的。

    Apache 2.0 offers operation in multi-threaded mode. My benchmarks indicate there is little performance advantage in this

    mode. Also be warned that many PHP extensions are not compatible (e.g. GD and IMAP). Tested with Apache 2.0.47 (21 Oct 2003).
    apache 2.0 提供在多线程模式的操作。我的测试显示在这个模式下的性能只有一点点的提升。当然要提醒一下:很多PHP扩展不被兼容。

    Apache is configured using the httpd.conf file. The following parameters are particularly important in configuring child

    processes:

    APACHE 使用httpd.conf作为配置文件。下面的这些对配置子进程非常重要

    Directive
    Default
    Descrīption

    MaxClients
    256
    The maximum number of child processes to create. The default means that up to 256 HTTP requests can be handled concurrently.

    Any further connection requests are queued.

    StartServers
    5
    The number of child processes to create on startup.

    MinSpareServers
    5
    The number of idle child processes that should be created. If the number of idle child processes falls to less than this

    number, 1 child is created initially, then 2 after another second, then 4 after another second, and so forth till 32 children

    are created per second.

    MaxSpareServers
    10
    If more than this number of child processes are alive, then these extra processes will be terminated.

    MaxRequestsPerChild
    0
    Sets the number of HTTP requests a child can handle before terminating. Setting to 0 means never terminate. Set this to a

    value to between 100 to 10000 if you suspect memory leaks are occurring, or to free under-utilized resources.

    For large sites, values close to the following might be better:

    MinSpareServers 32

    MaxSpareServers 64

    对于大型网站。建议按照以下的数值进行配置

    MinSpareServers 32

    MaxSpareServers 64

    Apache on Windows behaves differently. Instead of using child processes, Apache uses threads. The above parameters are not

    used. Instead we have one parameter: ThreadsPerChild which defaults to 50. This parameter sets the number of threads that can

    be spawned by Apache. As there is only one child process in the Windows version, the default setting of 50 means only 50

    concurrent HTTP requests can be handled. For web servers experiencing higher traffic, increase this value to between 256 to

    1024.
    apache在windows上的表现不同。apache在windows使用上使用线程(threads).上面的那些参数将不会被使用。作为替代的是我们使用一个参数

    :ThreadsPerChild (默认数值为50)由于在windows版本上只有一个子进程,默认设为50意味着只有50个http并发请求。大流量的服务器请把

    这个数值提升到256至1024。<

    Other useful performance parameters you can change include:
    其他一些你应该修改的有用参数
    Directive
    Default
    Descrīption

    SendBufferSize
    Set to OS default
    Determines the size of the output buffer (in bytes) used in TCP/IP connections. This is primarily useful for congested or

    slow networks when packets need to be buffered; you then set this parameter close to the size of the largest file normally

    downloaded. One TCP/IP buffer will be created per client connection.

    KeepAlive [on|off]
    On
    In the original HTTP specification, every HTTP request had to establish a separate connection to the server. To reduce the

    overhead of frequent connects, the keep-alive header was developed. Keep-alives tells the server to reuse the same socket

    connection for multiple HTTP requests.

    If a separate dedicated web server serves all images, you can disable this option. This technique can substantially improve

    resource utilization.

    KeepAliveTimeout
    15
    The number of seconds to keep the socket connection alive. This time includes the generation of content by the server and

    acknowledgements by the client. If the client does not respond in time, it must make a new connection.

    This value should be kept low as the socket will be idle for extended periods otherwise.

    MaxKeepAliveRequests
    100
    Socket connections will be terminated when the number of requests set by MaxKeepAliveRequests is reached. Keep this to a

    high value below MaxClients or ThreadsPerChild.

    TimeOut
    300
    Disconnect when idle time exceeds this value. You can set this value lower if your clients have low latencies.

    LimitRequestBody
    0
    Maximum size of a PUT or POST. O means there is no limit.

    If you do not require DNS lookups and you are not using the htaccess file to configure Apache settings for individual

    directories you can set:

    # disable DNS lookups: PHP scrīpts only get the IP address

    HostnameLookups off

    # disable htaccess checks

    <Directory />

    AllowOverride none

    </Directory>

    If you are not worried about the directory security when accessing symbolic links, turn on FollowSymLinks and turn off

    SymLinksIfOwnerMatch to prevent additional lstat() system calls from being made:

    Options FollowSymLinks

    #Options SymLinksIfOwnerMatch

    (b) IIS Tuning
    (b) IIS 调整
    IIS is a multi-threaded web server available on Windows NT and 2000. From the Internet Services Manager, it is possible to

    tune the following parameters:
    IIS 是一个在 Windows NT 和 2000上运行的多线程网络服务器。通过IIS管理器,他可以调整以下的参数:
    Performance Tuning based on the number of hits per day.
    Determines how much memory to preallocate for IIS. (Performance Tab).

    Bandwidth throttling
    Controls the bandwidth per second allocated per web site. (Performance Tab).

    Process throttling
    Controls the CPU% available per Web site. (Performance Tab).

    Timeout
    Default is 900 seconds. Set to a lower value on a Local Area Network. (Web Site Tab)

    HTTP Compression
    HTTP 压缩
    In IIS 5, you can compress dynamic pages, html and images. Can be configured to cache compressed static html and images. By

    default compression is off.
    在IIS 5,你可以压缩动态页,html页和图片。他可以被配置为缓存静态页和图片。默认情况下压缩是关闭的

    HTTP compression has to be enabled for the entire physical server. To turn it on open the IIS console, right-click on the

    server (not any of the subsites, but the server in the left-hand pane), and get Properties. Click on the Service tab, and

    select "Compress application files" to compress dynamic content, and "Compress static files" to compress static content.

    You can also configure the default isolation level of your web site. In the Home Directory tab under Application Protection,

    you can define your level of isolation. A highly isolated web site will run slower because it is running as a separate

    process from IIS, while running web site in the IIS process is the fastest but will bring down the server if there are

    serious bugs in the web site code. Currently I recommend running PHP web sites using CGI, or using ISAPI with Application

    Protection set to high.
    你也可以单独编辑你的网站的等级。在网站管理的根目录的标签上,你可以单另定义你的等级。由于他运行在一个单独的进程下,高度自定义

    等级的网站会慢一些。尽管在IIS上运行网站一般很快,但是当代码有缺陷的时候会减慢网站的运行速度。我强烈建议PHP以CGI方式在IIS上运

    行,或者当以ISAPI模式运行时使用高等级。

    You can also use regedit.exe to modify following IIS 5 registry settings stored at the following location:
    你也可以使用 regedit.exe 直接编辑IIS 5 在注册表中的信息,他的位置是:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Inetinfo\Parameters\

    MemCacheSize
    内存缓存大小
    Sets the amount of memory that IIS will use for its file cache. By default IIS will use 50% of available memory. Increase if

    IIS is the only application on the server. Value is in megabytes.
    当IIS使用文件缓存的时候设置他使用内存的大小。默认情况下IIS将使用50%可使用的内存。只有当IIS是服务器上唯一的网络服务器的时候将

    会增长占用的内存。他增长的数量单位是MB

    MaxCachedFileSize
    Determines the maximum size of a file cached in the file cache in bytes. Default is 262,144 (256K).

    ObjectCacheTTL
    Sets the length of time (in milliseconds) that objects in the cache are held in memory. Default is 30,000 milliseconds (30

    seconds).

    MaxPoolThreads
    Sets the number of pool threads to create per processor. Determines how many CGI applications can run concurrently. Default

    is 4. Increase this value if you are using PHP in CGI mode.

    ListenBackLog
    Specifies the maximum number of active Keep Alive connections that IIS maintains in the connection queue. Default is 15, and

    should be increased to the number of concurrent connections you want to support. Maximum is 250.

    If the settings are missing from this registry location, the defaults are being used.
    如果设置错了。服务器就会使用默认数值。

    High Performance on Windows: IIS and FastCGI
    在windows上高效的 :IIS 和 FastCGI

    After much testing, I find that the best PHP performance on Windows is offered by using IIS with FastCGI. CGI is a protocol

    for calling external programs from a web server. It is not very fast because CGI programs are terminated after every page

    request. FastCGI modifies this protocol for high performance, by making the CGI program persist after a page request, and

    reusing the same CGI program when a new page request comes in.
    在多次测试之后,我发现在windows上PHP表现最好的情况是以 FastCGI方式在IIS上运行(我个人持保留意见—by achieverain)。CGI是网络服

    务器调用扩展程序的一个协议。他由于每个页面请求结束之后都回停止而不是很快。FastCGI是一种高效的协议。当出现重复的页面请求的时候

    他会恢复并返回一个相同的页面执行的结果。

    As the installation of FastCGI with IIS is complicated, you should use the EasyWindows PHP Installer. This will install PHP,

    FastCGI and Turck MMCache for the best performance possible. This installer can also install PHP for Apache 1.3/2.0.
    以FastCGI 方式安装到IIS上是很复杂的,你必须使用EasyWindows PHP Installer。他将把PHP, FastCGI 和 Turck MMCache以最优化的方式安

    装好。这个安装包也可以给Apache 1.3/2.0安装PHP。(因为这是比较古老的文章[2005年],我实际使用中发现EasyWindows PHP Installer并不

    是万灵丹,还是自己老老实实调整吧 —by achieverain)
    This section on FastCGI added 21 Oct 2003.

    PHP4's Zend Engine
    PHP4的 Zend 引擎
    The Zend Engine is the internal compiler and runtime engine used by PHP4. Developed by Zeev Suraski and Andi Gutmans, the

    Zend Engine is an abbreviation of their names. In the early days of PHP4, it worked in the following fashion:
    Zend引擎是PHP4使用的内部编译器和运行用引擎,他是由Zeev Suraski 和 Andi Gutmans开发。zend引擎是他们名字的混合体。在PHP4的早期

    ,他是以下方式运行的:

    The PHP scrīpt was loaded by the Zend Engine and compiled into Zend opcode. Opcodes, short for operation codes, are low level

    binary instructions. Then the opcode was executed and the HTML generated sent to the client. The opcode was flushed from

    memory after execution.
    PHP脚本被Zend引擎读取并被编译成Zend中间代码,中间代码比操作代码短,比二进制描述要低级。然后中间代码会被执行,Html被生成并发送

    到客户端。在执行完毕之后中间代码就被从内存中清除。

    Today, there are a multitude of products and techniques to help you speed up this process. In the following diagram, we show

    the how modern PHP scrīpts work; all the shaded boxes are optional.
    现在,有很多产品和技术帮助你加速这个过程。在以下的简述中,我们将展现当代PHP的工作方式,所有隐藏的技巧将被展现。

    PHP scrīpts are loaded into memory and compiled into Zend opcodes. These opcodes can now be optimized using an optional

    peephole optimizer called Zend Optimizer. Depending on the scrīpt, it can increase the speed of your PHP code by 0-50%.
    PHP脚本读入内存并被编译成Zend的中间代码。这些中间代码将被一个内置解析器: Zend Optimizer 优化。通过这些步骤,他可以提高你的程

    序0-50%的执行速度

    Formerly after execution, the opcodes were discarded. Now the opcodes can be optionally cached in memory using several

    alternative open source products and the Zend Accelerator (formerly Zend Cache), which is a commercial closed source product.

    The only opcode cache that is compatible with the Zend Optimizer is the Zend Accelerator. An opcode cache speeds execution by

    removing the scrīpt loading and compilation steps. Execution times can improve between 10-200% using an opcode cache.
    原本在执行结束之后,中间代码将被清除。但现在使用一些开源代码和 Zend Accelerator(原生的zend缓存,虽然不是个开源软件)
    Where to find Opcode Caches
    哪里可以找到中间代码的缓存

    Zend Accelerator: A commercial opcode cache developed by the Zend Engine team. Very reliable and robust. Visit

    http://zend.com for more information.
    Zend Accelerator: 一个由Zend 引擎团队开发的商业缓存。非常可靠和稳定。你可以访问http://zend.com去得到相关信息。

    You will need to test the following open source opcode caches before using them on production servers as their performance

    and reliability very much depends on the PHP scrīpts you run.
    你要在部署以下开源缓存之前详细测试他们。因为他们的稳定性和速度很依赖于你的PHP脚本。

    Turcke MMCache: http://turck-mmcache.sourceforge.net/ is no longer maintained. See eAccelerator, which is a branch of mmcache

    that is actively maintained (Added 28 Feb 2005).

    Alternative PHP Cache: http://apc.communityconnect.com/

    PHP Accelerator: http://www.php-accelerator.co.uk/

    AfterBurner Cache: http://www.bwcache.bware.it/

    One of the secrets of high performance is not to write faster PHP code, but to avoid executing PHP code by caching generated

    HTML in a file or in shared memory. The PHP scrīpt is only run once and the HTML is captured, and future invocations of the

    scrīpt will load the cached HTML. If the data needs to be updated regularly, an expiry value is set for the cached HTML. HTML

    caching is not part of the PHP language nor Zend Engine, but implemented using PHP code. There are many class libraries that

    do this. One of them is the PEAR Cache, which we will cover in the next section. Another is the Smarty template library.
    一个取得高性能的秘密就是不要写过快的程序,但是要避免在文件缓存或者在共享内存中生成HTML。PHP脚本只是在HTML被捕获的时候运行一次

    ,之后的调用PHP就会读取缓存的HTML。如果数据需要经常改变。缓存的HTML就需要设置一个失效时间。HTML缓存并不是PHP语言或Zend引擎中

    的一部分,但可以用PHP实现。现在有很多的类库可以做这个。其中一个就是PEAR 缓存。另一个是Smarty 模版库
    Finally, the HTML sent to a web client can be compressed. This is enabled by placing the following code at the beginning of

    your PHP scrīpt:
    最后,发送到客户端的HTML可以被压缩。这需要你在PHP代码的开始加上以下的代码
    <?php

    ob_start("ob_gzhandler");

    :
    :

    ?>

    If your HTML is highly compressible, it is possible to reduce the size of your HTML file by 50-80%, reducing network

    bandwidth requirements and latencies. The downside is that you need to have some CPU power to spare for compression.
    如果你的HTML被高度压缩,他可能将你的HTML减少50-80%的体积。这可以节省网络带宽和减少数据延迟,而代价仅仅是增加少量的CPU占用。
    HTML Caching with PEAR Cache
    PEAR Cache中的HTML缓存
    The PEAR Cache is a set of caching classes that allows you to cache multiple types of data, including HTML and images.
    PEAR Cache是一个允许包括HTML和图片在内多种类型数据的缓存类。

    The most common use of the PEAR Cache is to cache HTML text. To do this, we use the Output buffering class which caches all

    text printed or echoed between the start() and end() functions:
    PEAR Cache最常见的使用便是缓存HTML文本。我们可以在输出缓存类使用start() 和 end()输出所有缓存的数据。

    require_once("Cache/Output.php");

    $cache = new Cache_Output("file", array("cache_dir" => "cache/") );

    if ($contents = $cache->start(md5("this is a unique key!"))) {

    #
    # aha, cached data returned
    #

      print $contents;
      print "<p>Cache Hit</p>";

    } else {

    #
    # no cached data, or cache expired
    #

      print "<p>Don't leave home without it…</p>"; # place in cache
      print "<p>Stand and deliver</p>"; # place in cache
      print $cache->end(10);

    }

    Since I wrote these lines, a superior PEAR cache system has been developed: Cache Lite; and for more sophisticated

    distributed caching, see memcached (Added 28 Feb 2005).
    当我们写下这些代码之后,一个超级PREA缓存系统就被开发出来了:缩水版缓存;如果需要复杂的缓存,看看memcached 。
    The Cache constructor takes the storage driver to use as the first parameter. File, database and shared memory storage

    drivers are available; see the pear/Cache/Container directory. Benchmarks by Ulf Wendel suggest that the "file" storage

    driver offers the best performance. The second parameter is the storage driver options. The options are "cache_dir", the

    location of the caching directory, and "filename_prefix", which is the prefix to use for all cached files. Strangely enough,

    cache expiry times are not set in the options parameter.
    缓存创建的第一个参数是存储的路径,文件,数据库,共享内存都可以;看看pear/Cache/Containe的路径。Ulf Wendel的测试指出“文件”存

    储提供了最好的性能,第二个参数是存储的选项。这个选项是"cache_dir",存储缓存的路径;filename_prefix:所有缓存文件名字的前缀。

    很奇怪,缓存失效时间并不在这些参数里设置。

    To cache some data, you generate a unique id for the cached data using a key. In the above example, we used md5("this is a

    unique key!").
    为缓存以下数据,你需要为缓存数据生成唯一ID。在上面的例子中,我们使用了d5("this is a unique key!")
    The start() function uses the key to find a cached copy of the contents. If the contents are not cached, an empty string is

    returned by start(), and all future echo() and print() statements will be buffered in the output cache, until end() is

    called.
    start()函数生成一个key以寻找缓存的内容的拷贝。如果内容没有被缓存,start()将返回一个空字符串,当调用end()时所有的输出将会被写

    进缓存。
    The end() function returns the contents of the buffer, and ends output buffering. The end() function takes as its first

    parameter the expiry time of the cache. This parameter can be the seconds to cache the data, or a Unix integer timestamp

    giving the date and time to expire the data, or zero to default to 24 hours.
    end()函数返回并输出缓冲中的数据。end()函数的第一个参数就是失效时间,这个参数可以设置数据的秒(后失效)或者失效的Unix时间戳,或

    者默认的0(即24小时);
    Another way to use the PEAR cache is to store variables or other data. To do so, you can use the base Cache class:
    另一个使用PREA缓存的方式是存储变量和其他数据。为实现这个目标,你可以使用基础的缓存类:

    <?php

    require_once("Cache.php");

    $cache = new Cache("file", array("cache_dir" => "cache/") );
    $id = $cache->generateID("this is a unique key");

    if ($data = $cache->get($id)) {

      print "Cache hit.<br>Data: $data";

    } else {

      $data = "The quality of mercy is not strained…";
      $cache->save($id, $data, $expires = 60);
      print "Cache miss.<br>";

    }

    ?>

    To save the data we use save(). If your unique key is already a legal file name, you can bypass the generateID() step.

    Objects and arrays can be saved because save() will serialize the data for you. The last parameter controls when the data

    expires; this can be the seconds to cache the data, or a Unix integer timestamp giving the date and time to expire the data,

    or zero to use the default of 24 hours. To retrieve the cached data we use get().
    为了存储这些数据我们将使用save(),如果你的唯一ID已经生成,你可以跳过生成ID这一步。因为save()序列化了数据,所以他可以存储类和

    数组。最后一个参数控制着数据的实效时间;这个可以是缓存数据的失效秒数。或者UNIX时间戳。或者默认的24小时。重新取得这些缓存过的

    数据我们使用get()函数。

    You can delete a cached data item using $cache->delete($id) and remove all cached items using $cache->flush().
    你可以使用$cache->delete($id)删除一个缓存过的数据,使用$cache->flush()删除所有缓存。
    New: A faster Caching class is Cache-Lite. Highly recommended.
    提示:一个更快的缓存类是Cache-Lite,高度推荐。
    Using Benchmarks
    使用测试

    In earlier section we have covered many performance issues. Now we come to the meat and bones, how to go about measuring and

    benchmarking your code so you can obtain decent information on what to tune.
    在前面的部分我们谈论了很多方便的性能。现在我们上正餐吧,如何测试你的代码的性能以使你取得如何调整的信息。

  • show innodb status (mysql)

    2008-03-11 23:29:43

    MySQL: SHOW INNODB STATUS 详解(二)
    2007年12月18日 星期二 20:30

    当前活跃的事务:

    1. ------------
    2. TRANSACTIONS
    3. ------------
    4. Trx id counter 0 80157601
    5. Purge done for trx's n:o <0 80154573 undo n:o <0 0
    6. History list length 6
    7. Total number of lock structs in row lock hash table 0
    8. LIST OF TRANSACTIONS FOR EACH SESSION:
    9. ---TRANSACTION 0 0, not started, process no 3396, OS thread id 1152440672
    10. MySQL thread id 8080, query id 728900 localhost root
    11. show innodb status
    12. ---TRANSACTION 0 80157600, ACTIVE 4 sec, process no 3396, OS thread id 1148250464, thread declared inside InnoDB 442
    13. mysql tables in use 1, locked 0
    14. MySQL thread id 8079, query id 728899 localhost root Sending data
    15. select sql_calc_found_rows * from b limit 5
    16. Trx read view will not see trx with id>= 0 80157601, sees <0 80157597
    17. ---TRANSACTION 0 80157599, ACTIVE 5 sec, process no 3396, OS thread id 1150142816 fetching rows, thread declared inside InnoDB 166
    18. mysql tables in use 1, locked 0
    19. MySQL thread id 8078, query id 728898 localhost root Sending data
    20. select sql_calc_found_rows * from b limit 5
    21. Trx read view will not see trx with id>= 0 80157600, sees <0 80157596
    22. ---TRANSACTION 0 80157598, ACTIVE 7 sec, process no 3396, OS thread id 1147980128 fetching rows, thread declared inside InnoDB 114
    23. mysql tables in use 1, locked 0
    24. MySQL thread id 8077, query id 728897 localhost root Sending data
    25. select sql_calc_found_rows * from b limit 5
    26. Trx read view will not see trx with id>= 0 80157599, sees <0 80157595
    27. ---TRANSACTION 0 80157597, ACTIVE 7 sec, process no 3396, OS thread id 1152305504 fetching rows, thread declared inside InnoDB 400
    28. mysql tables in use 1, locked 0
    29. MySQL thread id 8076, query id 728896 localhost root Sending data
    30. select sql_calc_found_rows * from b limit 5
    31. Trx read view will not see trx with id>= 0 80157598, sees <0 80157594

    如果连接数量很大,InnoDB只能打印出其中的一部分,以维持整个列表的长度。

    Transaction id是当前事务的标识符。Purge done for trx's n:o 是回收程序启动事务的数量。如果回收程序没有运行事务,InnoDB只能回收旧版本。旧的未提交事务可能会阻塞回收进程而吃掉资源。通过查看当前事务数和 最近一次回收事务数的差值就可以发现这个问题。在某些情况下,回收程序效率很低而要维持更新率,在这种情况下差值也会增加,这时innodb_max_purge_lag 会有所帮助。"undo n:o"显示回收程序正在处理的undo日志记录数,如果当前没有回收程序运行,则该值为0。

    History list length 是在回滚段中为回收的事务数。当更新事务提交时该值增加,当回收线程运行时该值减少。

    Total number of lock structs in row lock hash table是所有事务分配的行锁结构数。该值并不等于锁住的行数-因为一个锁结构中包含很多行。

    MySQL的连接要么是not started 状态(该连接没有活动的事务),要么是ACTIVE状态(有活动事务)。注意,尽管连接是"SLEEP"状态,但事务也可以是活跃的-如果事务中有多个语句。事务状态就是事务正在做什么,如"fetching rows", "updating"。"Thread declared inside InnoDB 400"意思是线程正在InnoDB内核中运行,当前还可以有400个线程可以进来。InnoDB限制内核中的并发线程数使用变量innodb_thread_concurrency 。如果线程没在InnoDB内核中运行,状态应该是"waiting in InnoDB queue" 或"sleeping before joining InnoDB queue"。为避免太多线程竞争进入InnoDB队列,InnoDB有时会让线程先sleep,而不是wait。这样就会使InnoDB内核中的活跃线程少于innodb_thread_concurrency。这会减少线程等待进入队列的时间,可以调整innodb_thread_sleep_delay 的值,该值为微秒。

    mysql tables in use 1, locked 0 是由线程正使用的表数,和线程锁住的表数。InnoDB一般不会锁表,因此该值一般为0,除非ALTER TABLELOCK TABLES 相似的操作。

    文件I/O:

    1. --------
    2. FILE I/O
    3. --------
    4. I/O thread 0 state: waiting for i/o request (insert buffer thread)
    5. I/O thread 1 state: waiting for i/o request (log thread)
    6. I/O thread 2 state: waiting for i/o request (read thread)
    7. I/O thread 3 state: waiting for i/o request (write thread)
    8. Pending normal aio reads: 0, aio writes: 0,
    9. ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
    10. Pending flushes (fsync) log: 0; buffer pool: 0
    11. 17909940 OS file reads, 22088963 OS file writes, 1743764 OS fsyncs
    12. 0.20 reads/s, 16384 avg bytes/read, 5.00 writes/s, 0.80 fsyncs/s

    IO的四个进程(括号中的名字)。插入缓存合并,异步日志刷新,read-ahead和脏缓存刷新。如果线程准备好了则为waiting for i/o request 状态,否则它就正在执行某种操作。

    Number of pending operation is shown for each of helper threads - these are amount of operations queued for execution or being executed at the same time. Also number of pending fsync operations is displayed. For writes Innodb has to ensure data makes it to the disk - just passing it to OS cache is not enough. This is typically done by calling fsync() for modified files. Constant high values for any of these variables is indication of IO bound workload. Note however - IO requests submited by threads executing requests are not accounted here so you may have these at zeroes while workload being IO bound still.

    Next, number of file IO operations is shown as well as computed averages. This is parameters which is great for graphing and monitoring.
    "16384 avg bytes/read" shows average size of read requests. For random IO these should be 16K - page size, for full table scan or index scan read-ahead may be performed which can increase average read size significantly. So you can think about this value as read-ahead efficiency.

    CODE:
    1. -------------------------------------
    2. INSERT BUFFER AND ADAPTIVE HASH INDEX
    3. -------------------------------------
    4. Ibuf for space 0: size 1, free list len 887, seg size 889, is not empty
    5. Ibuf for space 0: size 1, free list len 887, seg size 889,
    6. 2431891 inserts, 2672643 merged recs, 1059730 merges
    7. Hash table size 8850487, used cells 2381348, node heap has 4091 buffer(s)
    8. 2208.17 hash searches/s, 175.05 non-hash searches/s

    This section shows insert buffer and adaptive hash status. First line shows status of insert buffer - segment size and free list as well as if
    there are any records is insert buffer. Next it shows how many inserts were done in insert buffer, how many recs were merged and how many merges did it took. Ratio of number of merges to number of inserts is pretty much insert buffer efficiency.

    Adaptive hash index is hash index Innodb builds for some pages to speed up row lookup replacing btree search with hash search. This section shows hash table size, number of used cells and number of buffers used by adaptive hash index. You can also see number of hash index lookups and number of non-hash index lookups which is indication of hash index efficiency.

    There is currently not much you can do to adjust adaptive hash index or insert buffer behavīor so it is pretty much for informational purposes only.

    CODE:
    1. ---
    2. LOG
    3. ---
    4. Log sequence number 84 3000620880
    5. Log flushed up to 84 3000611265
    6. Last checkpoint at 84 2939889199
    7. 0 pending log writes, 0 pending chkp writes
    8. 14073669 log i/o's done, 10.90 log i/o's/second

    Log section provides information about log subsystem of Innodb. You can see current log sequence number - which is amount of bytes Innodb has written in log files since system tablespace creation. You can also see up to which point logs have been flushed - so how much data is unflushed in log buffer as well as when last checkpoint was performed. Innodb uses fuzzy checkpointing so this line hold log sequence, all changes up to which has been flushed from buffer pool. Changes having higher log sequences may still only be recored in logs and not flushed from buffer pool so such log sequences can't be overwritten in log files. By monitoring log sequence number and value up to which logs have been flushed you can check if your innodb_log_buffer_size is optimal - if you see more than 30% of log buffer size being unflushed you may want to increase it.

    You also can see number of pending normal log writes and number of checkpoint log writes. Number of log/io operations allows to separate tablespace related IO from log related IO so you can see how much IO your log file requires. Note depending on your innodb_flush_log_at_trx_commit value your log writes may be more or less expensive. If innodb_flush_logs_at_trx_commit=2 log writes are done to OS cache, and being sequential writes these logs writes are pretty fast.

    CODE:
    1. ----------------------
    2. BUFFER POOL AND MEMORY
    3. ----------------------
    4. Total memory allocated 4648979546; in additional pool allocated 16773888
    5. Buffer pool size 262144
    6. Free buffers 0
    7. Database pages 258053
    8. Modified db pages 37491
    9. Pending reads 0
    10. Pending writes: LRU 0, flush list 0, single page 0
    11. Pages read 57973114, created 251137, written 10761167
    12. 9.79 reads/s, 0.31 creates/s, 6.00 writes/s
    13. Buffer pool hit rate 999 / 1000

    该部分描述了内存的使用情况。包括的信息有:InnoDB分配的总内存,额外分配的内存,缓存池中的页数,空闲页数,数据库页和脏页数。从这些值中 可以看出是否InnoDB缓存分配得恰当-如果总有很多空闲页,表明数据库要比内存小,可以把innoDB缓存调小些。如果空闲页为0,那么数据库页不会 和缓存容量相同,因为还要存锁、索引和其他得系统结构。

    Pending reads and writes are pending requests on buffer pool level. Innodb may merge multiple requests to one on file level so these are different. We can also see different types of IO submited by Innodb - pages to be flushed via LRU pages - dirty pages which were not accessed long time, flush list - old pages which need to be flushed by checkpointing process and single page - independent page writes.

    We can also see number of pages being read and written. Created pages is empty pages created in buffer pool for new data - when previous page content was not read to the buffer pool.

    Finally you can see buffer pool hit ratio which measures buffer pool efficiency. 1000/1000 corresponds to 100% hit rate. It is hard to tell what buffer pool hit rate is good enough - it is very workload dependent. Sometimes 950/1000 will be enough, sometimes you can see IO bound workload with hit rate of 995/1000.

    CODE:
    1. --------------
    2. ROW OPERATIONS
    3. --------------
    4. 0 queries inside InnoDB, 0 queries in queue
    5. 1 read views open inside InnoDB
    6. Main thread process no. 10099, id 88021936, state: waiting for server activity
    7. Number of rows inserted 143, updated 3000041, deleted 0, read 24865563
    8. 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s

    Finally last section - row operations which shows activity on the row basics and some system information.

    It shows innodb thread queue status - how many threads are waiting and being active. How many read views are open inside Innodb - this is when transaction was started but no statement is currently active, state of Innodb main thread which controls scheduling of number of system operations - flushing dirty pages, checkpointing, purging, flusing logs, doing insert buffer merge. Values for "state" field are rather self explanatory.

    You can also see number of rows operation since system startup as well as average values. This is also very good values to monitor and graph - row operations is very good measure of Innodb load. Not all row operations are created equal of course and accessing of 10 byte rows is much cheaper than accessing 10MB blog, but it is still much more helpful than number of queries, which is even more different.

    One more thing to note - SHOW INNODB STATUS is not consistent - it does not correspond to some particular point in time. Different lines in SHOW INNODB STATUS populated in different point in times, so sometimes you may see a bit conflicting information. This is by design as requiring global lock to provide consitent information would cause significant overhead.


  • mysql sleep 线程过多 (摘抄)

    2008-03-11 23:28:25

    关于Apache::DBI与MYsql的持续连接太多的问题


    (这条文章已经被阅读了 324次) 时间:2002年03月08日 19:10 来源:韩伟 收藏

    关于Apache::DBI与MYsql的持续连接太多的问题大家已经研
    究了一段时间了。

    我经过这几天研究发现mod_perl提供的持续连接并不智能(也许是我还没有找到更
    好的解决方案),如果脚本中的参数和初始化的参数不一样,在内存中会出现两个
    句柄。

    Apache::DBI->connect_on_init("DBI:mysql:mysql:localhost","root","root",
    {
    PrintError => 1,
    RaiseError => 0,
    AutoCommit => 1,
    });



    my $dbh = DBI->connect("DBI:mysql:database=localhost","root","root",{
    PrintError => 1,
    RaiseError => 0,
    AutoCommit => 1,
    });

    以上两个语句实现同一个连接,返回同一种结果,但是他们的概念完全不一样。

    经过统一参数,写作方法,和格式。测试后,发现process不再无故增长,达到预
    期效果。

    事故原因分析:对于一个数据库,Apache::DBI建立一个持续连接, 如果在
    startup.pl文件中初始化的时候采用一种书写格式,参数,而脚本中
    DBI->connect又采用不同的连接方式和格式,因此假如一个以上的句柄实现同一个
    目的(连接同一个数据库)的话,最后一个连接进入时,它会企图查找最后一个相
    匹配的句柄(Handler),换句话说就是找一个参数,格式都一样的句柄。这里问题
    就出来了,内存中存在两个实现同一目的的句柄(但是格式或参数不一样),这个
    连接无法识别应该使用哪一个,所以被迫建立一个新的句柄,而导致原先的句柄继
    续Sleep(我管它叫做僵尸句柄)。

    解决方案:其实解决方法非常简单,因为昨天我也在其他操作系统上(RedHat 7)装
    了Apache+Mod_perl+Mysql,仍然出现相同的问题。根据内存分析与同伴们的测
    试。得出一个结论,当内存中连接同一数据库的句柄数在一个以上的时候,
    process会无故增加,当句柄为一个的时候,process不会增长,而采用原有内存中
    的句柄,这个就是我们想要的。为实现这一目的,我们需要统一初始化和connect
    的格式,参数和相关信息。

    关于并发处理:测试发现,句柄初始化在process中建立的5个连接完全可以人工控
    制。修改MinSpareServers(最小空闲服务器)和MaxSpareServers(最大空闲服务器)
    的数量。该数量放的越大,服务器的并发处理能力就越高。但是我们要付出的是宝
    贵的内存为代价,根据网站的点击次数合理调节该数量是最为明智的选择。如果服
    务器遇到大量并发请求,系统会自动克隆相应的句柄以适应并发的数量。当请求完
    毕后,系统将自动断开克隆的句柄以释放沉余的内存。大家看下面的例子,我采用
    ab(ApacheBench)这个工具对服务器请求5000次,并发数为100,观看mysql的句柄
    线程数,最高峰值达到50,当请求完毕后,释放沉余的句柄空闲内存,这时线程数
    量又恢复到5个(我的Apache Config File中 MaxSpareServers 设置为5)。

    D:\>ab -n 5000 -c 100 http://10.4.1.32/mod_perl/dbi.cgi
    This is ApacheBench, Version 1.3e <> apache-2.0
    Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.
    net/
    Copyright (c) 1998-2001 The Apache Software Foundation,
    http://www.apache.org/

    Benchmarking 10.4.1.32 (be patient)
    Completed 500 requests
    Completed 1000 requests
    Completed 1500 requests
    Completed 2000 requests
    Completed 2500 requests
    Completed 3000 requests
    Completed 3500 requests
    Completed 4000 requests
    Completed 4500 requests
    Finished 5000 requests
    Server Software: Apache/1.3.20
    Server Hostname: 10.4.1.32
    Server Port: 80

    Document Path: /mod_perl/dbi.cgi
    Document Length: 99 bytes

    Concurrency Level: 100
    Time taken for tests: qd.qd seconds
    Complete requests: 5000
    Failed requests: 0
    Write errors: 0
    Total transferred: 1220000 bytes
    HTML transferred: 495000 bytes
    Requests per second: 132.37 [#/sec] (mean)
    Time per request: 755.48 [ms] (mean)
    Time per request: 7.55 [ms] (mean, across all concurent requests)
    Transfer rate: 32.30 [Kbytes/sec] received

    Connnection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 3 72.2 0 2964
    Processing: 80 743 3199.6 260 37263
    Waiting: 10 725 3198.1 240 37253
    Total: 80 746 3200.0 260 37263

    Percentage of the requests served within a certain time (ms)
    50% 260
    66% 320
    75% 420
    80% 490
    90% 741
    95% 3054
    98% 4606
    99% 4626
    100% 37263 (last request)

    --------------------------

    多种原因

    mysql_pconnect()/mysql_close()和mysql_connect()

    PHP.ini
    my.conf: wait_timeout/interactive_timeout

    slow_query.log

     


     

  • C/C++ mem leak tool

    2008-02-26 23:36:23

     

    用C/C++开发其中最令人头疼的一个问题就是内存管理,有时候为了查找一个内存泄漏或者一个内存访问越界,需要要花上好几天时间,如果有一款工具能够帮助我们做这件事情就好了,valgrind正好就是这样的一款工具。

    Valgrind是一款基于模拟linux下的程序调试器和剖析器的软件套件,可以运行于x86, amd64和ppc32架构上。valgrind包含一个核心,它提供一个虚拟的CPU运行程序,还有一系列的工具,它们完成调试,剖析和一些类似的任务。valgrind是高度模块化的,所以开发人员或者用户可以给它添加新的工具而不会损坏己有的结构。

    valgrind的官方网址是:http://valgrind.org

    你可以在它的网站上下载到最新的valgrind,它是开放源码和免费的。

    一、介绍

    valgrind包含几个标准的工具,它们是:

    1、memcheck

    memcheck探测程序中内存管理存在的问题。它检查所有对内存的读/写操作,并截取所有的malloc/new/free/delete调用。因此memcheck工具能够探测到以下问题:

    1)使用未初始化的内存

    2)读/写已经被释放的内存

    3)读/写内存越界

    4)读/写不恰当的内存栈空间

    5)内存泄漏

    6)使用malloc/new/new[]和free/delete/delete[]不匹配。

    2、cachegrind

    cachegrind是一个cache剖析器。它模拟执行CPU中的L1, D1和L2 cache,因此它能很精确的指出代码中的cache未命中。如果你需要,它可以打印出cache未命中的次数,内存引用和发生cache未命中的每一行代码,每一个函数,每一个模块和整个程序的摘要。如果你要求更细致的信息,它可以打印出每一行机器码的未命中次数。在x86和amd64上,cachegrind通过CPUID自动探测机器的cache配置,所以在多数情况下它不再需要更多的配置信息了。

    3、helgrind

    helgrind查找多线程程序中的竞争数据。helgrind查找内存地址,那些被多于一条线程访问的内存地址,但是没有使用一致的锁就会被查出。这表示这些地址在多线程间访问的时候没有进行同步,很可能会引起很难查找的时序问题。

    二、valgrind对你的程序都做了些什么

    valgrind被设计成非侵入式的,它直接工作于可执行文件上,因此在检查前不需要重新编译、连接和修改你的程序。要检查一个程序很简单,只需要执行下面的命令就可以了

    valgrind --tool=tool_name program_name

    比如我们要对ls -l命令做内存检查,只需要执行下面的命令就可以了

    valgrind --tool=memcheck ls -l

    不管是使用哪个工具,valgrind在开始之前总会先取得对你的程序的控制权,从可执行关联库里读取调试信息。然后在valgrind核心提供的虚拟CPU上运行程序,valgrind会根据选择的工具来处理代码,该工具会向代码中加入检测代码,并把这些代码作为最终代码返回给valgrind核心,最后valgrind核心运行这些代码。

    如果要检查内存泄漏,只需要增加--leak-check=yes就可以了,命令如下

    valgrind --tool=memcheck --leak-check=yes ls -l

    不同工具间加入的代码变化非常的大。在每个作用域的末尾,memcheck加入代码检查每一片内存的访问和进行值计算,代码大小至少增加12倍,运行速度要比平时慢25到50倍。

    valgrind模拟程序中的每一条指令执行,因此,检查工具和剖析工具不仅仅是对你的应用程序,还有对共享库,GNU C库,X的客户端库都起作用。

    三、现在开始

    首先,在编译程序的时候打开调试模式(gcc编译器的-g选项)。如果没有调试信息,即使最好的valgrind工具也将中能够猜测特定的代码是属于哪一个函数。打开调试选项进行编译后再用valgrind检查,valgrind将会给你的个详细的报告,比如哪一行代码出现了内存泄漏。

    当检查的是C++程序的时候,还应该考虑另一个选项 -fno-inline。它使得函数调用链很清晰,这样可以减少你在浏览大型C++程序时的混乱。比如在使用这个选项的时候,用memcheck检查openoffice就很容易。当然,你可能不会做这项工作,但是使用这一选项使得valgrind生成更精确的错误报告和减少混乱。

    一些编译优化选项(比如-O2或者更高的优化选项),可能会使得memcheck提交错误的未初始化报告,因此,为了使得valgrind的报告更精确,在编译的时候最好不要使用优化选项。

    如果程序是通过脚本启动的,可以修改脚本里启动程序的代码,或者使用--trace-children=yes选项来运行脚本。

    下面是用memcheck检查ls -l命令的输出报告,在终端下执行下面的命令

    valgrind --tool=memcheck ls -l

    程序会打印出ls -l命令的结果,最后是valgrind的检查报告如下:

    ==4187==

    ==4187== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 19 from 2)

    ==4187== malloc/free: in use at exit: 15,154 bytes in 105 blocks.

    ==4187== malloc/free: 310 allocs, 205 frees, 60,093 bytes allocated.

    ==4187== For counts of detected errors, rerun with: -v

    ==4187== searching for pointers to 105 not-freed blocks.

    ==4187== checked 145,292 bytes.

    ==4187==

    ==4187== LEAK SUMMARY:

    ==4187== definitely lost: 0 bytes in 0 blocks.

    ==4187== possibly lost: 0 bytes in 0 blocks.

    ==4187== still reachable: 15,154 bytes in 105 blocks.

    ==4187== suppressed: 0 bytes in 0 blocks.

    ==4187== Reachable blocks (those to which a pointer was found) are not shown.

    ==4187== To see them, rerun with: --show-reachable=yes

    这里的“4187”指的是执行ls -l的进程ID,这有利于区别不同进程的报告。memcheck会给出报告,分配置和释放了多少内存,有多少内存泄漏了,还有多少内存的访问是可达的,检查了多少字节的内存。

    下面举两个用valgrind做内存检查的例子

    例子一 (test.c):

    #include <string.h>
    
    int main(int argc, char *argv[])
    {
        char *ptr;
    
        ptr = (char*) malloc(10);
        strcpy(ptr, "01234567890");
    
        return 0;
    }

    编译程序

    gcc -g -o test test.c

    用valgrind执行命令

    valgrind --tool=memcheck --leak-check=yes ./test

    报告如下

    ==4270== Memcheck, a memory error detector.

    ==4270== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.

    ==4270== Using LibVEX rev 1606, a library for dynamic binary translation.

    ==4270== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.

    ==4270== Using valgrind-3.2.0, a dynamic binary instrumentation framework.

    ==4270== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.

    ==4270== For more details, rerun with: -v

    ==4270==

    ==4270== Invalid write of size 1

    ==4270== at 0x4006190: strcpy (mc_replace_strmem.c:271)

    ==4270== by 0x80483DB: main (test.c:8)

    ==4270== Address 0x4023032 is 0 bytes after a block of size 10 alloc'd

    ==4270== at 0x40044F6: malloc (vg_replace_malloc.c:149)

    ==4270== by 0x80483C5: main (test.c:7)

    ==4270==

    ==4270== Invalid write of size 1

    ==4270== at 0x400619C: strcpy (mc_replace_strmem.c:271)

    ==4270== by 0x80483DB: main (test.c:8)

    ==4270== Address 0x4023033 is 1 bytes after a block of size 10 alloc'd

    ==4270== at 0x40044F6: malloc (vg_replace_malloc.c:149)

    ==4270== by 0x80483C5: main (test.c:7)

    ==4270==

    ==4270== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 12 from 1)

    ==4270== malloc/free: in use at exit: 10 bytes in 1 blocks.

    ==4270== malloc/free: 1 allocs, 0 frees, 10 bytes allocated.

    ==4270== For counts of detected errors, rerun with: -v

    ==4270== searching for pointers to 1 not-freed blocks.

    ==4270== checked 51,496 bytes.

    ==4270==

    ==4270==

    ==4270== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1

    ==4270== at 0x40044F6: malloc (vg_replace_malloc.c:149)

    ==4270== by 0x80483C5: main (test.c:7)

    ==4270==

    ==4270== LEAK SUMMARY:

    ==4270== definitely lost: 10 bytes in 1 blocks.

    ==4270== possibly lost: 0 bytes in 0 blocks.

    ==4270== still reachable: 0 bytes in 0 blocks.

    ==4270== suppressed: 0 bytes in 0 blocks.

    ==4270== Reachable blocks (those to which a pointer was found) are not shown.

    ==4270== To see them, rerun with: --show-reachable=yes

    从这份报告可以看出,进程号是4270,test.c的第8行写内存越界了,引起写内存越界的是strcpy函数,

    第7行泄漏了10个字节的内存,引起内存泄漏的是malloc函数。

    例子二(test2.c)

    #include <stdio.h>
    
    int foo(int x)
    {
        if (x < 0) {
            printf("%d ", x);
        }
    
        return 0;
    }
    
    int main(int argc, char *argv[])
    {
        int x;
       
        foo(x);
    
        return 0;
    }

    编译程序

    gcc -g -o test2 test2.c

    用valgrind做内存检查

    valgrind --tool=memcheck ./test2

    输出报告如下

    ==4285== Memcheck, a memory error detector.

    ==4285== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.

    ==4285== Using LibVEX rev 1606, a library for dynamic binary translation.

    ==4285== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.

    ==4285== Using valgrind-3.2.0, a dynamic binary instrumentation framework.

    ==4285== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.

    ==4285== For more details, rerun with: -v

    ==4285==

    ==4285== Conditional jump or move depends on uninitialised value(s)

    ==4285== at 0x8048372: foo (test2.c:5)

    ==4285== by 0x80483B4: main (test2.c:16)

    ==4285==p p

    ==4285== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 1)

    ==4285== malloc/free: in use at exit: 0 bytes in 0 blocks.

    ==4285== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.

    ==4285== For counts of detected errors, rerun with: -v

    ==4285== All heap blocks were freed -- no leaks are possible.

    从这份报告可以看出进程PID是4285,test2.c文件的第16行调用了foo函数,在test2.c文件的第5行foo函数使用了一个未初始化的变量。

  • vrlgrind

    2008-02-26 23:35:10

    这段时间在对一个产品进行稳定性测试,让程序在Purify下运行,结果Purify最后出现了错误。同事告诉我有一款工具——valgrind,可以定位程序内存方面的错误,于是我下载下来,运行测试,效果很好,这个工具运行稳定,给出的结果也很清晰。
        valgrind这款工具是运行在linux下的,可以用来定位c/c++程序中内存使用方面的错误。包括:内存泄漏、使用未初始化的内存、读/写已释放的内存、读/写内存越界、使用malloc/new/new[]和free/delete/delete[]不匹配,等等。
        valgrind官方网站:http://valgrind.org/,是一款open source软件。我下载的时候最新版是3.2.3。安装过程很简单——configure,make,make install,安装后不需要任何设置,直接可以开始使用。
        valgrind运行方法很简单:valgrind --leak-check=full --track-fds=yes 程序 参数
      这样你的程序就会在valgrind监控下运行了,结果会直接输出到屏幕上。如果想把结果输出到日志文件(通常也需要这样),用如下的命令:valgrind --log-file=valgrind_log --leak-check=full --track-fds=yes 程序 参数
  • logrotate

    2008-02-26 23:22:57

    /usr/local/apache-server1/logs/* {
       weekly
       size=100M
       rotate 4
       compress

       postrotate
       /bin/kill -1 `cat /usr/local/apache/PID/httpd.pid`
       endscrīpt
    }

    向进程发送HUP信号,使其重新读取配置文件。
    因为apache是持续性运行,日志文件始终处于打开状态,执行日志轮转后,日志不会被保存到新的access_log中。而/var/log/wtmp只是在是在用户登陆系统时被打开,存入日志后文件后被关闭。
     
    ----
    sort -m -t " " -k 4 -o logall log1 log2
     
    ----
     
    安装了awstats来分析日志 用命令
    /usr/local/awstats/wwwroot/cgi-bin/perl awstats.pl -config=www.abc.com -update -lang=cn
    分析日志没有问题
    此时日志格式如下
    LogFile="/usr/local/apache/logs/access_log"
    设置
    AllowToUpdateStatsFromBrowser=1
    在页面可以点更新 且正常分析日志

    但是当日志格式设置为
    LogFile="gzip -d </usr/local/apache/logs/access_log.gz |"
    时 用命令分析日志没有问题 但是启用从浏览器中实时更新统计即AllowToUpdateStatsFromBrowser=1时
    点击更新出现Error: Command for pipe 'gzip -d </usr/local/apache/logs/access_log.gz |' failed
    Setup ('/etc/awstats/awstats.www.abc.com.conf' file, web server or permissions) may be wrong.
    Check config file, permissions and AWStats documentation (in 'docs' directory).

    虽然说做到crontab中可以更新。但总感觉不爽,也搜了些资料说是权限问题 但还是无法解决 特
    请教!看下面帮助说是权限问题
    可我的如下,还是有问题
    /usr/local/awstats/data
    drwxr-xr-x 2 daemon daemon 4096 01-15 05:21 data
    data内文件也都属主daemon 权限为755了
    # When AWStats updates its statistics, it stores results of its analysis in
    # files (AWStats database). All those files are written in the directory
    # defined by the "DirData" parameter. Set this value to the directory where
    # you want AWStats to save its database and working files into.
    # Warning: If you want to be able to use the "AllowToUpdateStatsFromBrowser"
    # feature (see later), you need "Write" permissions by web server user on this
    # directory (and "Modify" for Windows NTFS file systems).
    # Example: "/var/lib/awstats"
    # Example: "../data"
    # Example: "C:/awstats_data_dir"
    # Default: "."          (means same directory as awstats.pl)
    #
    DirData="/usr/local/awstats/data"

    # When this parameter is set to 1, AWStats add a button on report page to
    # allow to "update" statistics from a web browser. Warning, when "update" is
    # made from a browser, AWStats is ran as a CGI by the web server user defined
    # in your web server (user "nobody" by default with Apache, "IUSR_XXX" with
    # IIS), so the "DirData" directory and all already existing history files
    # awstatsMMYYYY[.xxx].txt must be writable by this user. Change permissions if
    # necessary to "Read/Write" (and "Modify" for Windows NTFS file systems).
    # Warning: Update process can be long so you might experience "time out"
    # browser errors if you don't launch AWStats enough frequently.
    # When set to 0, update is only made when AWStats is ran from the command
    # line interface (or a task scheduler).
    # Possible values: 0 or 1
    # Default: 0
    #
    AllowToUpdateStatsFromBrowser=1
     
  • apache httpd相关

    2008-01-31 23:04:09

    lsof |grep apache

    Apache是运行在Linux操作系统上的头号Web服务器。很多小地方都可以用来调整Apache的性能,并降低它对系统资源的影响。其中一个就是调整内存使用率,当然达到这一目的可能还是需要花点功夫的。

    例如,通过ps来确定httpd线程的内存使用率,可以输入下面的命令:

    # ps -U apache -u apache u
    USERPID %CPU %MEMVSZRSS TTYSTAT START TIME COMMAND
    apache130670.05.3 149704 54504 ?SOct071:53 /usr/sbin/httpd -f /etc/httpd/conf/httpd.conf -DAPACHE2
    ...

    上面这段输出显示了单个httpd进程使用了50 MB的RSS(驻留集大小)内存(或者非交换物理内存),以及149 MB的VSZ(虚拟)内存。这当然在很大程度上取决于你在Apache里加载和运行的模块数量。这决不是一个固定的数字。由于这个数字里还包含了共享库包,所以不是100%的准确。我们可以认为RSS数字的一半是httpd线程真正使用的内存数,这可能还有点保守,但是离我们的目的已经非常接近了。

    在本文里,我们假设每个httpd进程都在使用了27 MB内存。然后,你需要确定可以让httpd真正使用的内存数。根据运行在机器上的其他进程,你可能希望要求50%的物理内存都供Apache使用。在一个装有1GB内存的系统上,就有512MB的内存可以被划分为多个27MB的内存,也就是大约19个并发的httpd内存。有些人坚持认为每个httpd 线程“真正”使用大约5MB的内存,所以从理论上讲你可以把512MB的内存划分出102个并发进程供Apache使用(要记住的是,除非你的网站需要极其巨大的流量,否则这种情况是非常罕见的)。

    在默认状态下,Apache会分配最大256个并发客户端连接,或者256个进程(每一个都对应一个请求)。按照这种设置,一个流量巨大的网站会在顷刻间崩溃(即使你假设每个进程占用5MB内存,那也需要1.3GB的内存来满足请求的数量)。如果不采取其它措施,系统会通过硬盘来尝试使用交换空间以处理它无法在物理内存中完成的任务。

    其他可以调整的项目包括KeepAlive、KeepAliveTimeout和MaxKeepAliveRequests等设置。可以放在httpd.conf文件里的推荐设置有:

    ServerLimit 128MaxClients 128KeepAlive OnKeepAliveTimeout 2MaxKeepAliveRequests 100

    通过将KeepAliveTimeout从15秒减到2秒,可以增加MaxClients命令;19太小,而128要好得多。通过减少进程存活的秒数,你可以在相同的时间内允许更多的连接。

    当然,如果没有真正的测试在背后支持,数字就是毫无意义的,这就是ab的作用之所在。使用ab对Apache配置文件(MaxClients等于 256、ServerLimit等于256、KeepAliveTimeout等于15)进行调整,使其能够满足1000个请求(100个连续请求并发产生)的调整方法如下。(在执行测试的时候要确保服务器上有一个终端打开以观察系统的负载。)

    $ ab -n 1000 -c 100 -k http://yoursite.com/index.php

    现在把上面的服务器设置改为更加保守的设置,重新启动Apache,试着再次测试(总是从远程计算机上进行,而不是本机)。

    在这里的测试中,不同的设置导致执行所消耗的时间产生了一倍的差距(分别为27.8s和16.8s),但是负载的平均值为0.03和0.30。这可能会使得你的网站变得稍慢,但是会确保它不会在高负载的情况下崩溃。还要记住的是,你将需要进行多次测试,以便取得一个平均值。

    使用ab是测试调整Apache配置的一个极佳方法,应该在你每次做出影响性能的更改时使用它。

561/3123>
Open Toolbar