apache的工作方式及优化

6450阅读 0评论2010-08-30 dongyue91
分类:系统运维

系统环境 : debian-5
这里只说一下最简单的安装方式:

apt-get insatll apache2

apache2ctl -l //命令用于查看已安装的apache的工作模式

APACHE的工作模式有beos|worker|prefork|mpmt_os2| perchild|leader|threadpool 如此之多.
常用的工作模式不外乎worker | prefork

一,先来说一下prefork工作原理及各优化参数的意义
prefork的工作原理是:控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进 程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止。这就是预派生(prefork)的由来。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销 以增加性能。

StartServers 10

#指定服务器启动时建立的子进程数量,prefork默认为5。

MinSpareServers 10

#指定空闲子进程的最小数量,默认为5。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。此参数不要设的太大。

MaxSpareServers 15

#设置空闲子进程的最大数量,默认为10。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数 不要设的太大。如果你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改成"MinSpareServers+1"。

ServerLimit 2000

#有这个参数就不必像apache1一样修改源码才能修改256客户数的限制,听讲要放到最前面才会生效,20000是这个参数的最大值

MaxClients 1000

#限定同一时间客户端最大接入请求的数量(单个进程并发线程数),默认为256。任何超过MaxClients限制的请求都将进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。要增大这个值,你必须同时增大ServerLimit 。

MaxRequestsPerChild 10000

#每个子进程在其生存期内允许伺服的最大请求数量,默认为10000.到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。

MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild” 个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:

  ◆ 可防止意外的内存泄漏;
  ◆ 在服务器负载下降的时侯会自动减少子进程数。 

MaxClients是这些指令中最为重要的一个,设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值 150是远远不够的,如果请求总数已达到这个值(可通过ps -ef|grep http|wc -l来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。系统管理员可以根据硬件配置 和负载情况来动态调整这个值。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256。如果把这个值设为大于256,那么 Apache将无法起动。事实上,256对于负载稍重的站点也是不够的。在Apache 1.3中,这是个硬限制。如果要加大这个值,必须在“configure”前手工修改的源代码树下的src/include/httpd.h中查找 256,就会发现“#define HARD_SERVER_LIMIT 256”这行。把256改为要增大的值(如4000),然后重新编译Apache即可。在Apache 2.0中新加入了ServerLimit指令,使得无须重编译Apache就可以加大MaxClients


二,再来说一下worker的参数
worker的工作原理是:由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild 线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最 多的空闲线程数;而MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。

KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 10
<IfModule mpm_prefork_module>
    StartServers 200 //启动进程数
    MinSpareServers 5 //最小空闲进程数
    MaxSpareServers 10 //最大空闲进程数
    ServerLimit 10000 //最大进程数限制
    MaxClients 10000 //最大连接数,MaxClients决定了最大的httpd进程数
    MaxRequestsPerChild 10000 //0为默认,不限制。设置为10000防止内存泄漏。
</IfModule>

需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于MaxClients,而且 MaxClients必须是ThreadsPerChild的整数倍,否则Apache将会自动调节到一个相应值(可能是个非期望值)。


三,httpd.conf的其他优化点有以下几处:

1. KeepAlive
用于优化网站图片的

我安装的Apache2.0出厂值居然是Off。除非你的网站只有文字没有图片,否则改成On。然后所有的麻烦就来了。

以前看到过一个Web2.0和Web1.0的服务比较图,有印象的就是AdSense是1.0,垃圾Chitika成了2.0,同样Akamai是 1.0, BitTorrent成了2.0,真晕。其实Akamai的图片存储服务主要解决服务器的KeepAlive问题。看下面这个sample.html:

Hello world

当浏览器将请求发送给Apache后,Apache会为该用户建立连接,返回/sample.html的内容,浏览器解析HTML文件,发现还需要 显示 /hello.gif,就再次向Apache发出请求。这时如果KeepAlive为Off,Apache就需要重新建立连接。试想如果页面请求了 1000个图片,Apache就需要建立1000个连接(但建立第N个时候N-x个连接已经被Apache聪明的关闭了)。如果KeepAlive为 On,Apache会在同一个连接中处理所有这些请求,大大的节省了连接资源,可惜这个世界上有很多攻击者,他们会利用这个连接不断的特性不停的请求文 件,耗尽服务器的资源。所以一些大公司像Yahoo、AOL都选用Akamai作为图片存储服务,结果这些公司的sample.html版本就成了这个样 子:

Hello world

(真实地图片地址会比这个复杂)

这样一来每次用户访问仅会向本机服务器的Apache请求一次,剩下的请求发送到akamai了。不必为akamai的能力担心,因为它有充足的抗负载技术,Web2.0的大喇叭们想用BT取代akamai,我靠。

2. MaxKeepAliveRequests

明白了1中的内容,这个看名字就知道一个连接可以最多发送多少次请求。默认是500。

3. KeepAliveTimeout

同样,两次请求间超过这个数字就中断这个连接。如果你的KeepAlive是On,MaxKeepAliveRequests是500, KeepAliveTimeout是100,你可以算算攻击者们用多久可以耗干你的Apache。我把KeepAliveTimeout设为5,因为从我 网站受众人群的上网速度和网站的图片大小、数量考虑,5秒种可以完成加载多数页面。

KeepAlive参数

KeepAlive On
MaxKeepAliveRequests 0
KeepAliveTimeout 15 #使用keepalive可以在单一连接时进行多个请求。
Keepalivetimeout #每个连接保持的时间
MaxKeepAliveRequests #最大保持的连接数,0为不限制。

4. HostnameLookups

设为Off,避免DNS查询的等待。

除了这8个参数外,Apache的另一个可塑点是加载的Module,把不需要的LoadModule注释掉即可,大大的节省了内存。但是问题是你 不知道那个Module不需要,即便对照着Apache的Module文档朗读各个Module作用,也只能注释掉很少几个。下面是我比较踏实的注释掉的 几个Module:
mime_magic_module、info_module、userdir_module、proxy_module、proxy_ftp_module、proxy_http_module、proxy_connect_module。


四,优化之后的测试方法:

1,可以用自带的工具ab先测试下,比如
就先测试下apache自带的默认主页:
  ./ab c -1000 -n 10000
每次发1000个请求,共发10000个

2,我们调优常常要查看httpd进程数(即prefork模式下Apache能够处理的并发请求数)

#ps -ef | grep httpd | wc -l

返回结果示例:1388
表示Apache能够处理1388个并发请求,这个值Apache可根据负载情况自动调整

出现的结果,就是当前Apache能够处理的多少个并发请求,这个值Apache根据负载情况自动调.

3,查看Apache的并发请求数及其TCP连接状态:

#netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’

返回结果示例:
LAST_ACK 5
SYN_RECV 30   #
正在等待处理的请求数;
ESTABLISHED 1597  #正常数据传输状态;
FIN_WAIT1 51
FIN_WAIT2 504
TIME_WAIT 1057  #
处理完毕,等待超时结束的请求数

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


上一篇:分页显示类
下一篇:用tail命令及时查看文件变化