PHP7内核学习 - Fpm的master进程和worker进程

Fpm的master进程

作为一种多进程的模型,Fpm一个master进程多个worker进程组成。

master进程启动时,会创建一个socket,但是他本身并不接收/处理请求。他会fork出子进程来完成请求的接收和处理。所以,master的主要职责是管理worker进程,比如forkworker进程,或者killworker进程

master进程不直接worker进程进行通信,那么他是如何管理worker进程呢?实际上,master进程通过共享内存的方式来读取worker进程的状态信息,包括:worker进程当前状态,worker进程已经处理的请求数量等等。master进程会通过发送信号的方式来killworker进程

fpm_init()方法中会有一步:fpm_signals_init_main(),他会通过socketpair()创建一个管道,但是这个管道并非用于masterworker进行通信的。他master进程中使用。同时,设置master的信号处理函数为sig_handler(),当master收到SIGTERMSIGINTSIGUSR1SIGUSR2SIGCHLDSIGQUIT这些信号时将调用sig_handler()进行处理,在此函数中会把收到的信号写入刚刚创建的管道。


Fpm中的worker进程

Fpm中的worker进程的主要工作是处理请求。每个worker进程会竞争Accept请求,接收成功的那一个来处理本次请求。请求处理完毕后又重新进入等待状态。此处需要注意的是:一个worker进程同一时刻只能处理一个请求。这与Nginx的事件驱动模型有很大的区别。Nginx的子进程使用epoll来管理socket,当一个请求的数据还未发送完成的话他就会处理下一个请求,即同一时刻,一个子进程会连接多个请求。而Fpm的这种子进程处理方式则大大简化了PHP的资源管理,使得在Fpm模式下我们不需要考虑并发导致的资源冲突。


worker进程运行流程:
  • 等待请求的到来
  • 请求到来时竞争Accept请求,
  • 竞争成功后,读取并解析FastCGI协议的数据,
  • 解析完成后开始执行PHP脚本,
  • 执行完毕后关闭请求,继续监听下一个请求的到来

worker进程处理请求的周期:
  • 等待请求worker进程阻塞fcgi_accept_request()中等待请求
  • 解析请求FastCGI请求到达后被worker接收,然后worker开始接收并解析请求数据,直到request数据完全到达
  • 请求初始化:执行php_request_startup(),此阶段会调用每个扩展PHP_RINIT_FUNCTION
  • 执行PHP脚本:由php_execute_script()完成PHP脚本的编译执行
  • 关闭请求:请求完成后执行php_request_shutdown(),此阶段会调用每个扩展的PHP_RSHUTDOWN_FUNCTION,然后进入第一步等待下一个请求

一次请求过程中worker的状态:
  • FPM_REQUEST_ACCEPTING:等待请求阶段
  • FPM_REQUEST_READING_HEADERS:读取fastcgi请求的header阶段
  • FPM_REQUEST_INFO:获取请求信息阶段,此阶段是将请求的methodquery stringrequest uri等信息保存到各worker进程的fpm_scoreboard_proc_s结构中,此操作需要加锁,因为master进程也会操作此结构
  • FPM_REQUEST_EXECUTING:执行PHP脚本阶段
  • FPM_REQUEST_END:没有使用
  • FPM_REQUEST_FINISHED:请求处理完成

你可能感兴趣的:(#,php-fpm,#,PHP7内核)