nginx 和 PHP-fpm 的交互

nginx是一个webservice的功能,当检测到访问php文件时,会把请求交给fastcgi模块处理。我们可以在nginx的配置文件中配置fastcgi的相关参数

nginx和php-fpm的交互
nginx的fastcgi模块会把请求交给php-fpm程序处理。php-fpm的worker进程处理完后,会把数据返回给nginx,nginx会把数据放到内存缓存中,缓存区大小为fastcgi_buffer_size,fastcgi_buffers控制。如果返回数据大于缓存,则多出来的数据会被临时写入到文件中,放在fastcgi_temp目录下面。

PHP-FPM

php-fpm是一种master(主)/worker(子)多进程架构
master的工作分为四步:
1.cgi初始化阶段:分别调用fcgi_init()和 sapi_startup()函数,注册进程信号以及初始化sapi_globals全局变量。

2.php环境初始化阶段:a).加载和解析php配置;b).加载php模块并记入函数符号表(function_table);c).加载zend扩展 ; d).设置禁用函数和类库配置;e).注册回收内存方法;

3.php-fpm初始化阶段:执行fpm_init()函数。负责解析php-fpm.conf文件配置,获取进程相关参数(允许进程打开的最大文件数等),初始化进程池及事件模型等操作。

4.php-fpm运行阶段:执行fpm_run() 函数,运行后主进程发生阻塞。该阶段分为两部分:fork子进程 和 循环事件。fork子进程部分交由fpm_children_create_initial函数处理( 注:ondemand模式在fpm_pctl_on_socket_accept函数创建)。循环事件部分通过fpm_event_loop函数处理,其内部是一个死循环,负责事件的收集工作。

worker进程分三步:
1.接收客户端请求:执行fcgi_accept_request函数,其内部通过调用accept 函数获取客户端请求。

2.处理请求阶段:首先,分别调用fpm_request_info、php_request_startup获取请求内容及注册全局变量($_GET、$_POST、$_SERVER、$_ENV、$_FILES);然后根据请求信息调用php_fopen_primary_script访问脚本文件;最后交给php_execute_script执行。php_execute_script内部调用zend_execute_scripts方法将脚本交给zend引擎处理。

3.请求结束阶段:执行php_request_shutdown函数。此时 回调register_shutdown_function注册的函数及__destruct()方法,发送响应内容、释放内存等操作。

PHP-FPM的三种模式

php-fpm.conf配置pm
pm=static

nginx 和 PHP-fpm 的交互

始终保持固定数量的worker进程数,由pm.max_children决定。
pm=dynamic
php-fpm启动时,会初始启动一些worker,初始启动worker数决定于pm.max_children的值。在运行过程中动态调整worker数量,worker的数量受限于pm.max_children配置,同时受限全局配置process.max。
pm=ondemand
php-fpm启动的时候,不会启动任何一个worker,而是按需启动,只有当连接过来的时候才会启动。
启动的最大worker数决定于pm.max_children的值,同时受限全局配置process.max。
1秒定时器作用,如果空闲worker时间超过pm.process_idle_timeout的值(默认值为10s),则关闭该worker。这个机制可能会关闭所有的worker。

worker数量不足
当master监听到连接事件时,发现worker进程数量不够,会把连接放入到一个等待队列中,一直等待到有新的worker进程创建出来,就从等待等待队列中获取一个连接,然后accept请求处理。当连接太多而worker数量太少时,等待的时间太长,超过了nginxf的fastcgi连接时间限制,就会返回504超时。

常见错误码

php-fpm的work进程超时情况:
php-fpm:
request_terminate_timeout = 0
php.ini:
max_execution_time = 30 //这个参数记录的是php执行时间比较,不包括数据交互,网络连接的时间,所以如果不设置request_terminate_timeout的话,会导致worker永不超时,占用php-fpm的worker.直到超过fastcgi_connect_timeout的设置,返回504.

request_terminate_timeout 适用于,当max_execution_time由于某种原因无法终止脚本的时候(连接数据库,sleep等),会把这个php-fpm请求干掉。所以最好是在php-fpm.conf加上这个设置。

502:PHP-FPM没有开启或者php-fpm运行时手动kill掉对应的worker进程, php-fpm没有正常返回数据给nginx,报502 bad gateway.

500:当max_execution_time或者request_terminate_timeout生效的时候,php-fpm主动kill这个worker进程,php有Fatal error超时日志,http状态码为500。php无Fatal error超时日志,http状态码为502,php-fpm日志中有杀掉子进程日志

504:nginx的Fastcgi的参数fastcgi_connect_timeout 超时,就是说php-fpm的执行时间超过了nginx的fastcgi连接时间限制。

nginx与php-fpm的通讯方式

Nginx和PHP-FPM的进程间通信有两种方式,一种是TCP,一种是UNIX Domain Socket.

tcp

允许通过网络进程之间的通信,也可以通过loopback进行本地进程之间通信。

UNIX Domain Socket

允许在本地运行的进程之间进行通信。
其中TCP是IP加端口,可以跨服务器.而UNIX Domain Socket不经过网络,只能用于Nginx跟PHP-FPM都在同一服务器的场景.用哪种取决于你的PHP-FPM配置:

方式1:
php-fpm.conf: listen = 127.0.0.1:9000
nginx.conf: fastcgi_pass 127.0.0.1:9000;
方式2:
php-fpm.conf: listen = /tmp/php-fpm.sock
nginx.conf: fastcgi_pass unix:/tmp/php-fpm.sock;
本作品采用《CC 协议》,转载必须注明作者和本文链接
用过哪些工具?为啥用这个工具(速度快,支持高并发...)?底层如何实现的?
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!