blog

博客

View on GitHub

php-fpm配置调优


5.31更新

最近在看 《TCP IP网络编程》这本书,对进程、线程的有了更深入的理解, 并且学到了 epoll select 这两种网络编程模型的区别。

php-fpm 是阻塞的单线程模型,pm.max_children 指定的是最大的进程数量,
pm.max_requests 指定的是每个进程处理多少个请求后重启(因为 PHP 偶尔会有内存泄漏,所以需要重启).
php-fpm 的每个进程也只有一个线程,但是一个进程同时只能服务一个客户端。


原内容


前几天知乎有人邀请我回答一下关于php-fpm的问题,就顺便写个博客记录一下

首先说一下关于php-fpm比较重要的几个配置选项

pm  :php-fpm的运行方式,选项有static(静态)和dynamic(动态)

pm.max_requests:php-fpm工作进程处理完多少请求后自动重启

pm.max_children:静态方式下开启的php-fpm进程数量,简单来说设置2倍CUP核心数比如8核cpu 就设置16

pm.start_servers:动态方式下的起始php-fpm进程数量
pm.min_spare_servers:动态方式下的最小php-fpm进程数
pm.max_spare_servers:动态方式下的最大php-fpm进程数量

下面详细说说 pm.max_requests

php-fpm会不可避免的出现一些内存泄露的问题,这个参数指定了一个php-fpm子进程执行多少次之后重启该进程。理论上这个值可以随便设置,但是为了预防内存泄漏的风险,还是设置一个合理的数比较好。不能太小,也不宜太大,需要根据自己服务器的实际配置设置。

再说下 php-fpm进程数的设置,这部分引用网上搜索得到的资料。

1、 进程多了,会增加进程管理的开销,系统进程切换的开销。并且能并发执行的fpm进程不会超过cpu核心数。不会说你多开了几个进程,就多出几个cpu来处理。 2 、但worker进程开少了,如果server比较繁忙的话,会导到nginx把数据打到fpm的时候,发现所有的woker都在工作中,没有空闲的worker来接受请求,从而导致502 这么看来,设置进程数 = cpu核心数最合理了,但是并不是这样的。如同第二点所说的worker进程少了,会增大502的概率。所以需要设置的数稍大一点粗略来说, 2倍CPU核心数就可以。
如果按实际情况设置合理的值,该怎么处理呢?

可以通过每个worker在单位时间内处理的请求数来预估max_children的个数。假如最大的一个请求的处理时间是100ms内,而在100ms之内同时有100个请求过来,那了理论上就需要配置100个worker进程,先把请求给hang住。 这里有一个捷径,来配置你的max_children数, 就是你前期先把max_childnren设置成一个比较大的值,稳定运行一段时间后,观察fpm的status里的 max active processes 是多少,然后把max_children配置比他大一些就ok了。 此外还需要考虑内存问题,考虑一个worker占用多大内存,最大进程数*内存 得到最大并发情况下内存,看看是否超出服务器的内存限制。