apache2三种模式及参数调优

 

apache2三种模式

prefork MPM

prefork是比较古老而又稳定的apache模式,特点是每个进程都是单线程,在一个时间点只能处理一个连接,需要启动大量的进程来处理高并发的请求。由于是单线程进程,因而无须考虑线程安全的问题,可以使用非线程安全的库,例如mod_php。

优点是成熟稳定,缺点是比较消耗内存,而且并发支持受限于进程数量,对高并发支持稍差。

worker MPM

worker同样使用多个进程,但每个进程又拥有多个线程,每个线程处理一个连接。由于线程是轻量级的,因而具有较高的并发性,同时,多个进程又获得了一定的稳定性。worker模式特点是占用内存少,并发性比较高,缺点是必须考虑线程安全。如果使用了keep-alive方式,一个线程可能会被一直保持一个连接,但中间没有请求,直到超时。如果有多个线程被这样占据,在高并发场景下同样会出现无线程可用的情形。

event MPM

event模式是在2.4版本中才稳定发布的模式,它在worker的基础上,解决了keep-alive连接不能释放的问题。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力。

apache2 配置

查看当前使用的模式:apachectl -V | grep -i mpm

prefork MPM

mpm_prefork.conf文件内容如下:

<IfModule mpm_prefork_module>

    StartServers         10         # 启动时进程数

    MinSpareServers      5          # 最小空闲进程数

    MaxSpareServers      10         # 最大空闲进程数

    MaxRequestWorkers    100        # 最大并发进程数

    MaxRequestsPerChild   10000  # 最大连接数限制

</IfModule>

各个指令的含义:

StartServers : apache2启动时创建的服务进程数量。

MinSpareServers:最小空闲进程数量,空闲进程指的是没有处理请求的进程。

MaxSpareServers : 最大空闲进程数量。

MaxRequestWorkers : 最大同时处理请求的进程数量,也是最大的同时连接数,表示了apache的最大请求并发能力,超过该数目后的请求,将排队。

MaxConnectionsPerChild : 进程生命周期内,处理的最大请求数目。达到该数目后,进程将死掉。如果设置为0,表示没有限制。该参数的意义在于,避免了可能存在的内存泄露带来的系统问题。

通过上面的介绍可以发现,prefork模式下,影响并发性能最重要的参数就是MaxRequestWorkers,它决定了apache的并发处理能力。但是这个参数不是越大越好,因为如果超出了系统硬件能力,机器会卡死。

确定合适的MaxRequestWorkers:通过top命令查看apache进程占用的资源,主要看%CPU和%MEM这两个指标,例如,每个进程的CPU占用率不超过1%,每个进程的内存占用率不超过2%,考虑内存限制,比较合适的apache进程数量为50个。

然后,逐步测试最大值。通过观测得来的CPU和内存的指标有一定的误差,一般可以适当调节这个数值,例如调到1.5或者2倍,再通过峰值场景下的机器是否卡顿来判断是继续上调还是下调。

worker MPM

<IfModule mpm_worker_module>

    StartServers         20        # 启动时进程数

    MinSpareThreads      25       # 最小空闲线程数

    MaxSpareThreads      75       # 最大空闲线程数

    ThreadLimit          64       # 每个进程可以启动的线程数量上限值

    ThreadsPerChild      25       # 每个进程可以启动的线程数量

    MaxRequestWorkers    400      # 线程数量最大值

    MaxRequestsPerChild   0    # 最大连接数限制

</IfModule>

配置文件和前面的prefork有一些变动,但是基本的概念差不多。原来以进程为单位的概念转变成了以线程为单位的概念,例如MinSpareServers转变为MinSpareThreads,多了一个ThreadsPerChild,表示每个进程可以有的线程数量,其上限值为ThreadLimit。

注意,修改了ThreadsPerChild后可以通过apache2 restart来生效,但是修改了ThreadLimit只能先stop,然后start。

在worker模式中,MaxRequestWorkers转变为了线程数量,比起prefork模式下可以有比较大的增长,通常可以有好几倍的差别。这是worker模式相比于prefork的优势,worker拥有比较多的处理线程,可以同时保持大量的连接,峰值应对能力比较强。尽管出于CPU或者数据库的原因,这些连接不能在第一时间内被处理,可能产生较大延迟。

确定worker模式的参数:有两个参数比较重要,一是ThreadsPerChild,这个表示每个进程的线程数目,一般采用默认值即可,如果是并发量比较大,可以考虑加大这个值。另外一个就是MaxRequestWorkers了,在workers模式下,任务处理的负载会分发给php-fpm来处理,所以apache主要承担了建立和保持连接的任务,并不消耗太多资源,因而在理论上,MaxRequestWorkers可以非常大。

但是从实用体验来看,如果MaxRequestWorkers远超系统的请求处理能力,会有大量的请求排队,因而产生比较大的延迟,这个时候的体验并不好。所以这个参数一开始可以稍大,例如可以设置为prefork模式下的几倍,然后根据线上峰值延迟不断调整这个数值。MaxRequestWorkers必须是ThreadsPerChild的整数倍,否则apache会提示调整到一个相近的值。MaxRequestWorkers也有最大值限制,即ServerLimit乘以ThreadsPerChild。默认ServerLimit值是16,必要时可以显式声明加大这个值。

event MPM

event模式下的参数意义和worker模式完全一样,按照上面的策略来调整即可。

event相比于worker的优势是,它解决了worker模式下长连接线程的阻塞问题。

值得一提的是,worker/event模式的请求处理模式,已经和nginx的libevent模式相同了。在mod_php模式下,每个apache进程都需要直接执行php,所以很容易达到系统资源限制。但是在php-fpm模式下,apache只负责建立连接,然后把请求传递给php-fpm来处理。这样,apache可以保持大量的连接,请求处理能力取决于php服务器的性能。由于event是明显优于worker的,所以在apache2.4及后续版本中,一般优先选择event模式。

常见问题

查看apache的error日志,可以发现许多系统运行中的问题。

[mpm_prefork:error] [pid 1134] AH00161: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting

进程或者线程数目达到了MaxRequestWorkers,可以考虑增加这个值,当然,先考虑增加硬件。

[mpm_event:error] [pid 7555:tid 140058436118400] AH00485: scoreboard is full, not at MaxRequestWorkers

这个问题好像是apache2自带的bug,我们无力解决。好在这个问题一般只会影响单个线程,所以暂时可以忍。

一些系统状态指标

ps命令

查看当前系统apache和php进程、线程数目,下面的命令适用于ubuntu系统。

查看apache进程:ps aux | grep apache

查看apache进程数目:ps aux | grep apache | wc -l

worker/event模式下,查看线程数目:ps -eLf | grep apache | wc -l

查看php-fpm进程数:ps aux | grep php-fpm | wc -l
apache性能调试是一个比较复杂的问题。除了apache本身配置、PHP配置,还会涉及到数据库。后台的难点就在于如何应对高并发、大流量的请求,这往往不是单个点可以解决的,需要系统各个模块来协调。

修改Linux下Apache的最大连接数

Apache的最大连接数,默认为256个。

修改apache的最大连接数,方法如下:   

一:先修改usr/local/apache/conf/httpd.conf文件。

  将“#Include conf/extra/httpd-mpm.conf”前面的 # 去掉,保存。

二:再修改./apache/conf/extra/httpd-mpm.conf文件。

找到<IfModule mpm_winnt_module>
ThreadsPerChild  150 #推荐设置小型网站=1000 中型网站=1000~2000 大型网站=2000~3500
MaxRequestsPerChild  0 #推荐设置:小=10000 中或大=20000~100000
</IfModule>

查看apache当前工作模式:httpd -V或者apachectl -V | grep -i mpm

 

 

 

<IfModule mpm_prefork_module>
StartServers          5 #推荐设置:小=默认 中=20~50 大=50~100
MinSpareServers       5 #推荐设置:与StartServers保持一致
MaxSpareServers      10 #推荐设置:小=20 中=30~80 大=80~120 
ServerLimit         1000
MaxRequestWorkers   150 #推荐设置:小=500 中=500~1500 大型=1500~3000
MaxConnectionsPerChild   0 #推荐设置:小=10000 中或大=10000~500000

在apache2.3.13以前版本MaxRequestWorkers被称为MaxClients       

注意:1、一定添加ServerLimit,并且要在MaxClients前面,且数值要比MaxClient的值大;

2、重启apache,仅仅/bin/apachectl restart无效,需要先apachectl stop 然后再apachectl start

对apache中并发控制数prefork理解和调优

一个apache有linux下的并发不是很高的,大约到3K的样子,普通的服务器都会不同程度的出现问题.apache有关并发控制主要是 prefork和worker二个其中一个来控制.我们可以使用httpd -l来确定当前使用的MPM是prefork.c,还是Worker.c.下面是apache中有关prefork的配置.下面是优化过的参数.

<IfModule prefork.c>

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

ServerLimit 2000

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

StartServers 25

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

MinSpareServers 25

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

MaxSpareServers 50

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

MaxClients 2000

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

MaxRequestsPerChild 10000

</IfModule>

将MaxRequestsPerChild设置成非零值有两个好处:

1.可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。

2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。

工作方式:一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的 (spare)或者是空闲的子进程用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。在Unix系统中,父进程通常以root身份运行以便邦定80端口,而 Apache产生的子进程通常以一个低特权的用户运行。User和Group指令用于设置子进程的低特权用户。运行子进程的用户必须要对它所服务的内容有读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限。

我们调优常常要查看httpd进程数(即prefork模式下Apache能够处理的并发请求数):#ps -ef | grep httpd | wc -l

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

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

状态:描述

CLOSED:无连接是活动的或正在进行

LISTEN:服务器在等待进入呼叫

SYN_RECV:一个连接请求已经到达,等待确认

SYN_SENT:应用已经开始,打开一个连接

ESTABLISHED:正常数据传输状态

FIN_WAIT1:应用说它已经完成

FIN_WAIT2:另一边已同意释放

ITMED_WAIT:等待所有分组死掉

CLOSING:两边同时尝试关闭

TIME_WAIT:另一边已初始化一个释放 处理完毕,等待超时结束

LAST_ACK:等待所有分组死掉

#mpm_worker模块
<IfModule mpm_worker_module>
StartServers          2 #推荐设置:小=默认 中=3~5 大=5~10
ServerLimit         1000
MaxRequestWorkers   150 #推荐设置:小=500 中=500~1500 大型=1500~3000
MinSpareThreads      25 #推荐设置:小=默认 中=50~100 大=100~200
MaxSpareThreads      75 #推荐设置:小=默认 中=80~160 大=200~400 
ThreadsPerChild      25 #推荐设置:小=默认 中=50~100 大型=100~200
MaxConnectionsPerChild   0 #推荐设置:小=10000 中或大=10000~50000(此外,还需额外设置ServerLimit参数,ServerLimit必须大于等于MaxClients/ThreadsPerChild 的值。)
</IfModule>

 

说明:非原创,忘记文章链接了

posted on 2020-01-13 14:13  Helianthus720  阅读(1239)  评论(0编辑  收藏  举报

导航