Nginx优化篇 Nginx+php_fpm使用php及其配置优化 (十九)-张柏沛IT博客

正文内容

Nginx优化篇 Nginx+php_fpm使用php及其配置优化 (十九)

栏目:Linux 发布时间:2020-02-17 22:42 浏览量:202

Nginx+php_fpm使用php及其配置优化

说到php-fpm,我们就不得不先说一下PHP运行的4种模式
CGI、FastCGI、cli和Web模块四种模式

1.cli 命令行模式
就是使用php命令执行php脚本文件。

php-cli模式下不会限制超时时间

2.module 模式
这是一种将php作为一个子模块集成到web服务器(Apache)的模式。
具体的配置:
LoadModule php_5_module modules/mod_php5.so

客户端访问php动态文件的时候,请求到了Apache,Apache直接调用PHP模块来解析php脚本。

当然,Apache也是支持fastcgi这个模式的。

3.cgi 通用网关接口(Common Gateway Interface)
cgi可以让客户端向运行在服务器的应用程序(如php)发送请求。cgi是一种接口,描述的是客户端和程序(php)之间传输数据的一种标准。cgi独立于任何语言,只要这种语言符合cgi设定的标准就可以使用cgi模式。

cgi模式的详细流程:
以请求php文件为例
请求会从客户端发送到web服务端(如nginx,Apache),web服务器只能处理html这样的静态文件请求,所以它会创建一个cgi进程,这里是php-cgi,php-cgi会解析php.ini文件,初始化执行环境再处理请求,最后以cgi规定的格式返回处理结果给web服务器,Web服务器再关闭这个cgi进程,然后web服务端将结果再返回到客户端。
整个流程就是一个 Fork-And-Execute 模式

cgi模式下,客户端发送了多少个http请求,web服务端就会创建几个cgi进程,而且每次都要解析php.ini和初始化环境。所以高并发下会创建大量的进程,消耗大量内存,性能很低。

cgi模式下,Web服务器同时处理静态请求(html)和动态请求(php)

4.FastCGI 快速通用网关接口(Fast Common Gateway Interface)
是CGI的升级版,也是一种接口,协议或者标准。

FastCGI是一种常驻型的CGI,这种fastCGI进程只需要启动一次,解析一次php.ini和初始化执行环境就会一直开启着,请求结束也不会关闭进程。避免了每请求一次就创建一个进程,请求完就关闭进程的问题,提高了效率。
php的请求都会让web服务器交由fastcgi进程来解析,再返回给web服务器再返回给客户端。

出现了FastCGI后,PHP-FPM(PHP FastCGI Process Manager)也随之出现。php-FPM全称为PHP FastCGI 进程管理器,用于管理PHP fastcgi进程的工具。

 

PHP-FPM 进程管理器

开启php-fpm之后,会产生一个master主进程和多个worker子进程。

master进程的任务:
CGI及PHP环境初始化、监听端口等;
与web服务器建立TCP连接(三次握手),将连接放入accept队列中;
调度和管理worker进程(当worker进程出现错误或执行超时就会杀死该worker进程并重启一个worker进程,这些是通过信号来实现的,和nginx的架构很像)

worker进程的任务:
调用accept函数获取连接,接收来自web服务器的请求
调度php-cgi解析器来解析php文件(如果超时会返回504错误)

 

php-fpm可以监听多个端口,每个端口对应一个进程池,每一个进程池都有多个worker进程。
但是一般都是只会建立一个进程池,监听一个端口。

 

PHP-FPM有三种模式


static  
静态模式会生成固定数量的worker进程。
worker进程数由pm.max_children决定

pm=static
pm.max_children=40


dynamic
动态模式启动时分配固定数量的work进程,然后随着请求的增加会增加进程数,此模式下几个重要的配置项如下:
pm=dynamic
pm_max_spare_servers 允许最大的空闲进程数
min_spare_servers 允许最小的空闲进程数
start_servers 启动时的进程数


ondemand
按需分配模式相对static模式比较复杂,会根据请求量的增加动态增加,但是处理完请求后不会立即释放,而是由定时事件定时的检测空闲到一定时间的进程才会释放

 

 

PHP-FPM配置和参数优化

动态模式
pm = dynamic;   # 使用fpm动态模式
pm.max_children = 300;  # 限制动态模式下最大worker进程数
pm.start_servers = 20;  # 启动php-fpm时,worker进程的初始数量
pm.min_spare_servers = 5;    # 闲置时worker进程数量的最小值,这个值肯定比start_servers小
pm.max_spare_servers = 35;
# 闲置时worker进程数量的最大值,这个值肯定要比start_servers大

动态模式下,按照上面的配置,在fpm启动时会创建20个worker进程。如果请求较多,则会自动增加,并且保证空闲的进程数不小于pm.min_spare_servers,但是最大进程数不超过pm.max_children个;请求不多的时候,如果进程数较多,也会进行相应清理,保证空闲的进程数不多于pm.max_spare_servers;
可以将max_spare_servers设置的比start_servers大个10%。min_spare_servers可以设置为start_servers的10%


静态模式
pm = static;    # 使用静态模式
pm.max_children=300;    # 开启固定个数的worker进程

静态模式下,如果设置为300,则无论有没有请求进来,fpm都会保持300个进程数。

一个worker进程处理一个请求,php-fpm的worker进程数越高,就能处理越多nginx发过来的PHP请求,从而应对高并发。每个worker进程最多会消耗20M的内存(一个worker进程会消耗多少内存要看这个worker进程处理过多少个请求才被杀死再生出新worker进程),所以worker进程的个数由你的系统内存大小决定,例如2G 内存你可以让php-fpm的worker进程占用1.6G,留个0.4G给其他进程使用。
1600/20=80个worker进程。创建80个worker进程就可以处理80个并发的PHP请求。

如果是使用静态模式,则设置pm.max_children=80;
如果是使用动态模式,则可以看情况设置,如 pm.start_servers=40;
pm.max_spare_servers=60;
pm.min_spare_servers=10;    

假如此时80个并发请求进来,fpm有80个进程在处理请求,但是要保证10个进程空闲,所以此时会有90个worker进程。
当请求处理完,就会从90个减到60个进程

对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率。
因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好。

对于内存较小的服务器比如1~2G的,推荐使用动态模式。

 

可以通过 free -m查看系统内存大小,单位为M。

 

 

 

其他的fpm参数:


pm.max_requests = 1000;

nginx+php-fpm配置过程中最大问题是内存泄漏(内存泄漏即因为疏忽或错误造成程序未能释放已经不再使用的内存的情况)出问题:服务器的负载不大,但是内存占用迅速增加,很快吃掉内存接着开始吃交换分区,系统很快挂掉!

每个worker进程每处理完1个请求,内存不会释放给操作系统,所以处理了越多个请求之后,该worker进程占用的内存会越来越多。此时需要关闭这个worker进程释放内存再重新生成一个worker进程。

官方的解决办法是设置max_requests,该值的意思是worker进程处理了多少个请求后会重启该进程,我们需要适当降低这个值,用以让php-fpm自动的释放内存。默认是不限制worker进程的最大请求数,建议设置小一点如1000。实际上还有另一个跟它有关联的值max_children,这个是每次php-fpm会建立多少个进程,这样实际上的内存消耗是max_children*max_requests*每个请求使用的内存。

 

# 每个请求的最大执行时间
request_terminate_timeout = 30;

 

# 增加php-fpm打开文件描述符的限制。设为和ulimit一样大。php7.2版本默认是1024
rlimit_files = 10240;

 

# 连接队列的长度
listen.backlog=10240 ;    # 建议设置大一些,设为1024以上,为2的幂次方,设置的和net.core.somaxconn一样,但不要太大,不要超过20万。php7.2版本的fpm默认是511

 

# 静态优先级
process.priority = -19      # -20~19 ,越小优先级越高

 

#最长执行时间,单位秒

request_terminate_timeout=30

 

 

# php-fpm 重载配置(平滑重启)
service php-fpm reload

 

可以通过
ps -aux|grep php-fpm
查看fpm的worker进程数。显示的结果除了一个master进程,其他的都是worker进程。


PS:
一般会将 nginx的backlog和php-fpm的backlog设为和系统参数tcp_max_syn_backlog,somaxconn一致。
将nginx的worker_rlimit_nofile和php-fpm的rlimit_files设置的与系统的ulimit -n的值一致

如果您需要转载,可以点击下方按钮可以进行复制粘贴;本站博客文章为原创,请转载时注明以下信息

张柏沛IT技术博客 > Nginx优化篇 Nginx+php_fpm使用php及其配置优化 (十九)

热门推荐
推荐新闻