• 2007-06-06

    apache使用的一些心得

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://happyman-bruce.blogbus.com/logs/5690398.html

    web服务器用了一段时间,总结了以下一些经验供大家参考


    一、够用就好
    可以理解为web服务器是一条高速公路,如果出现让每一条车道都足够宽,那么消耗了很多的路面资源,能跑的车就少了。同样web服务器也是这样,不是所有的配置调整的越大越好,一般php+mysql+apache的架构,因为老碰到mysql连接数满的问题,所以把mysql连接数设置的非常高,同时加大mysql cache结果导致负载很高的时候,内存被大量消耗导致服务器频繁死机。
    后来检查了下程序,发现mysql连接数过高是由于程序编写不合理造成了,调整了下,服务器连接数就下来了:很多人可能跟我一样写php数据库查询完以后没有立即关闭数据库的习惯,让进程终止后系统自动回收打开的数据连接,但是如果系统非常慢的时候,执行一个php需要花费非常长是时间,那么导致mysql数据库一直保持着,导致连接数非常高,这样数据库消耗大量的内存,导致系统频繁使用swap,导致系统更加慢,然后恶性循环,最终服务器发生菪机。一个原则:在需要数据库的时候才打开数据库连接,一旦数据读取完成,立即关闭数据库。另外mysql cache的大小也不应该设置太大,应该经常使用show status命令察看下mysql的情况,按照实际需求配置mysql相关的chache 和最大连接数。
    检测Mysql的性能可以通过 select benchmark(100000,sql语句) 来检查mysql运行100000那个sql语句需要的时间。
    你可以可以通过 SELECT * FROM 表名 PROCEDURE ANALYSE ( )  来分析各个子段类型大小是否设置合适


    二、研究是web的限制和系统本身的限制
    linux 内核对打开的文件数一些有限制,一般可以通过ulimit -a 察看,/proc目录下有一些相关的最大值的控制,当服务器出现菪机的时候,一定要分析一下/var/log/message目录下的文件,机器菪机前系统报了什么错误。如果机器还能操作你可以使用命令dmesg看看内核当时出现了那些错误

    如果是内核的限制看下 http://shika.aist-nara.ac.jp/member/atsush-m/doc/kernel_tune.html 重新编译下内核,看这篇文章的时候注意一点这份文档居然没让你改大include/linux/fs.h NR_FILE,需要将NR_FILE设置成INR_OPEN的三倍大小,千万不要小于INR_OPEN,光光打开apache的HARD_SERVER_LIMIT 是不够的。
    检测打开的文件数是否够用可以运行下 more /proc/sys/fs/file-nr ,第一个值是系统已经分配的句柄数(你可以理解为系统打开最大的句柄数),第二个值是系统当前使用句柄数,第三个值是系统允许打开得句柄数,如果第一个值等于第三个值你需要考虑是否需要增加系统打开的句柄数,一方面你可以echo 一个比较大的值到 /proc/sys/fs/file-max,但是内核编译的时候决定了系统最大的文件数,这个值超过内核编译时候设置的内核数就需要重新编译内核来支持。

    如果机器有一定的内存,可以把bdflush的值设大,类似这样
    echo "100 128 128 512 5000 3000 60 0 0">;/proc/sys/vm/bdflush
    希望长期有效的话可以配放在rc.local下
    这个值具体什么意思可以运行 update -d 看下具体的解释

    另外如果你怀疑有Dos攻击的话,可以运行
    netstat -an | grep -i "服务器ip地址:80" | awk '{print $6}' | sort | uniq -c | sort -n

    这个命令会自动统计Tcp连接各个状态的数量,如果SYN_RECV很高的话(我的机器出现过给人建立了4000个SYN_RECV的事情。。。),就不能排除有基于tcp协议的ddos攻击的可能
    这样的话,你需要打开tcp_syncookies
    echo 1 >; /proc/sys/net/ipv4/tcp_syncookies
    如果没有 /proc/sys/net/ipv4/tcp_syncookies说明你的内核不支持syncookies,需要重新编译内核
    同时
    降低syn重试次数
    echo "1" >; /proc/sys/net/ipv4/tcp_syn_retries
    echo "1" >; /proc/sys/net/ipv4/tcp_synack_retries
    加大syn_backlog,以保证用户的访问(消耗内存为代价,设的太高。。)
    echo "2048" >; /proc/sys/net/ipv4/tcp_max_syn_backlog
    如果还是不行,那么只能交给相应的硬件防火墙了


    如果机器是用来做虚拟主机的话,如果有很多行
    <VirtualHost>;
    。。。。。。
    </VirtualHost>;
    这样的东东的话(我看见过一个人配了1000个不同的域名在一个机器里面,佩服他的耐心)可以考虑使用mod_rewrite方式来做,可以通过增加一个rewrite规则到apache里面,实现域名对应自动对应某个目录

    三、不要太迷信一些第三方的加速软件
    相信很多人在服务器负载较高的时候使用mod_limitipconn,mmcache等做服务器的加速,但是mod_limitipconn需要打开ExtendedStatus,反而会导致服务器性能下降,同样由于自身程序写得不够规范也可能导致mmcache这样的php加速软件使用的时候发生一些问题。
    如果条件许可,尽量建立cms系统让动态的叶面以静态的叶面显示


    以下是一个web服务系统检测的程序,5秒检查一次服务器负载,如果loadavg超过50系统自动重起apache


    #!/usr/bin/perl
    #pid文件
    $pidfile="/www/apache/logs/httpd.pid";
    #apache操作文件
    $apachectl="/www/apache/bin/apachectl";

    $ApacheIsRun=1;
    while (true) {
    $nowLoadavg=CheckLoadavg();
    print "Now:$nowLoadavg\n";
    if ($nowLoadavg >;50 && $ApacheIsRun==1) {
    #负载高于50
    print "The Server have problem\nStop Webserver\n";
    while (CheckApacheRun()==0) {
    system("$apachectl stop");
    sleep(20);
    }
    $ApacheIsRun=0;
    }
    if ($ApacheIsRun==0 || CheckApacheRun()==-1) {
    print "Start Webserver\n";
    system("$apachectl start");
    $ApacheIsRun=1;
    sleep(360);
    }

    sleep(5);
    }

    sub CheckApacheRun {
    my $PID="";
    my $Status="";
    #是否存在pid 不存在返回-1
    if (-e $pidfile) {
    $PID=`cat $pidfile`;
    $PID=~s/\n//g;
    if ($PID eq "") { #pid文件为空
    return -1;
    } else {
    $Status=`ps -ef|grep httpd|wc -l`;
    if ($Status < 3) {return -1;} else {return 0;}
    }
    } else {
    #pid文件不存在
    return -1;
    }
    }


    sub CheckLoadavg {
    my @avg=split(/\ /,`cat /proc/loadavg`);
    return $avg[0];
    }

    随机文章:

    my.cnf说明 2007-07-11
    vi 2005-12-20

    收藏到:Del.icio.us




    评论

  • ddddadsgffads
    brucectl回复tttrrrr说:
    yrdy
    2007-06-27 03:49:05