apache2三种模式及参数调优

来源:互联网 发布:网络教育英语统考作弊 编辑:程序博客网 时间:2024/06/06 02:47
 

apache2三种模式及参数调优


问题来源

如果访问量比较小,其实什么配置都没问题。在一些特殊场景下,例如促销活动,访问量会比较集中。峰值差不多能达到每秒1000到2000次的访问,而且还在继续增长中。

我们一直判断是数据库卡死的问题,后来发现,原来了服务器挂了。进一步定位,发现是apache接收了太多了请求,起了无数进程,内存用爆,机器卡死了。

如何配置apache,最大程度的发挥系统性能呢?

apache2三种模式

从2.0开始,apache引入了MPM(Multi-Processing Module,多进程处理模块)。MPM有prefork, worker和event(在2.4版本中稳定发布)模式,三种模式拥有不同的特点和性能。

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 配置

apache服务器的性能,在很大程度上取决于参数配置。

首先,我们如何查看当前apache所采用的模式呢?可以通过下面的命令:

apachectl -V | grep -i mpm
  • 1
  • 1

接下来,针对相应的模式,进行配置。apache2的默认配置文件位于/etc/apache2/apache2.conf,不同模式对应的配置文件在/etc/apache2/mods-available/下,有mpm_prefork.conf, mpm_worker.conf和mpm_event.conf。

prefork MPM

mpm_prefork.conf文件内容如下:

<IfModule mpm_prefork_module>    StartServers         10         # 启动时进程数    MinSpareServers      5          # 最小空闲进程数    MaxSpareServers      10         # 最大空闲进程数    MaxRequestWorkers    100        # 最大并发进程数    MaxConnectionsPerChild   10000  # 最大连接数限制</IfModule>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

各个指令的含义:

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倍,再通过峰值场景下的机器是否卡顿来判断是继续上调还是下调。

调整完参数后,一般需要重启apache。

service apache2 restart
  • 1
  • 1

worker MPM

mpm_worker.conf文件内容如下:

<IfModule mpm_worker_module>    StartServers         2        # 启动时进程数    MinSpareThreads      25       # 最小空闲线程数    MaxSpareThreads      75       # 最大空闲线程数    ThreadLimit          64       # 每个进程可以启动的线程数量上限值    ThreadsPerChild      25       # 每个进程可以启动的线程数量    MaxRequestWorkers    400      # 线程数量最大值    MaxConnectionsPerChild   0    # 最大连接数限制</IfModule>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

配置文件和前面的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,必要时可以显式声明加大这个值。

调整php-fpm

worker模式下的PHP一般运行在fastcgi环境下,所以决定系统性能的其实是PHP的处理能力。默认的php-fpm配置文件位于/etc/php5/fpm/pool.d/www.conf。通常有以下选项可以配置:

pm = dynamic                # PHP进程管理方式,动态pm.max_children = 32        # 最大PHP处理进程数pm.start_servers = 2        # 启动时PHP进程数目pm.min_spare_servers = 4    # 最小的空闲PHP进程数pm.max_spare_servers = 8    # 最大的空闲PHP进程数pm.max_requests = 5000      # 进程生命周期处理的最大请求数,避免内存泄露
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

同理,这里比较关键的是max_children参数,它直接决定了PHP处理请求的能力。这个参数的选取,也需要根据每个php-fpm所占用的CPU和内存来决定,同样通过top命令查看php-fpm进程消耗的资源,然后计算一个大概值。在调整的过程中,可以结合top命令查看CPU和内存消耗的总量,只要有足够剩余,是可以加大这个数值的。调整完参数后,需要重启php-fpm。

service php5-fpm restart
  • 1
  • 1

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日志,可以发现许多系统运行中的问题。

server reached MaxRequestWorkers setting

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

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

scoreboard is full

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

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

一些系统状态指标

top命令

这里写图片描述

第一行里面的load average可以查看系统负载情况。第三行可以查看CPU使用问题。第四行可以查看内存占用及剩余内存。

进程列表里面,%CPU和%MEM显示了每个进程所占用的资源百分比。

apache日志

访问日志默认位置/var/log/apache2/access.log,可以通过日志文件查看每个请求处理结果及所用时间。

error日志一般位于/var/log/apache2/error.log,可以查看apache运行中的一些error报告 。

ps命令

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

查看apache进程。

ps aux | grep apache
  • 1
  • 1

查看apache进程数目

加上wc -l 命令即可。

ps aux | grep apache | wc -l
  • 1
  • 1

worker/event模式下,查看线程数目。

ps -eLf | grep apache | wc -l
  • 1
  • 1

查看php-fpm进程数。

ps aux | grep php-fpm | wc -l
  • 1
  • 1



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

参考

Apache MPM Common Directives

How do I select which Apache MPM to use?

PERFORMANCE OF APACHE 2.4 WITH THE EVENT MPM COMPARED TO NGINX

Determining the correct number of child processes for PHP-FPM on NGinx

CGI、FastCGI和PHP-FPM关系图解

0 0
原创粉丝点击