Nginx 与 FPM 的工作机制

php中会涉及到的术语

  • cgi:它是一种协议。通过cgi协议,web server可以将动态请求和相关参数发送给专门处理动态内容的应用程序。
  • fastcgi:也是一种协议,只不过是cgi的优化版。cgi的性能较烂,fastcgi则在其基础上进行了改进。
  • php-cgi:fastcgi是一种协议,而php-cgi实现了这种协议。不过这种实现比较烂。它是单进程的,一个进程处理一个请求,处理结束后进程就销毁。
  • php-fmp:是对php-cgi的改进版,它直接管理多个php-cgi进程/线程。也就是说,php-fpm是php-cgi的进程管理器因此它也算是fastcgi协议的实现。在一定程度上讲,php-fpm与php的关系,和tomcat对java的关系是类似的。
  • cgi进程/线程:在php上,就是php-cgi进程/线程。专门用于接收web server的动态请求,调用并初始化zend虚拟机。
  • cgi脚本:被执行的php源代码文件。
  • zend虚拟机:对php文件做词法分析、语法分析、编译成opcode,并执行。最后关闭zend虚拟机。
  • cgi进程/线程和zend虚拟机的关系:cgi进程调用并初始化zend虚拟机的各种环境。

CGI是什么

CGI 是 Web Server 与后台语言交互的协议,有了这个协议,开发者可以使用任何语言处理 Web Server 发来的请求,动态的生成内容

CGI的缺点

  • 那就是每处理一个请求都需要 fork 一个全新的进程,随着 Web 的兴起,高并发越来越成为常态,这样低效的方式明显不能满足需求

FastCGI

FastCGI,顾名思义为更快的 CGI,它允许在一个进程内处理多个请求,而不是一个请求处理完毕就直接结束进程,性能上有了很大的提高。

PHP-FPM(FastCGI Process Manager)

FPM 是一个 PHP 进程管理器,包含 master 进程和 worker 进程两种进程

  • master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,
  • 而 worker 进程则一般有多个 (具体数量根据实际需要配置),
  • 每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方

图解

file

自己服务器的php-fpm 1个master,6个worker

➜  ~ ps aux | grep php-fpm
root     22847  0.0  2.0 705156 80944 ?        Ss   4月16   0:02 php-fpm: master process (/etc/php-fpm.conf)
www      22848  0.0  1.0 784796 42048 ?        S    4月16   0:03 php-fpm: pool www
www      22849  0.0  1.0 711004 41772 ?        S    4月16   0:03 php-fpm: pool www
www      22850  0.0  1.1 708916 43140 ?        S    4月16   0:03 php-fpm: pool www
www      22851  0.0  1.1 782700 44876 ?        S    4月16   0:04 php-fpm: pool www
www      22852  0.0  0.8 708800 34864 ?        S    4月16   0:03 php-fpm: pool www
www      22871  0.0  1.1 782604 45856 ?        S    4月16   0:03 php-fpm: pool www

从 FPM 接收到请求,到处理完毕,其具体的流程如下

  • FPM 的 master 进程接收到请求
  • master 进程根据配置指派特定的 worker 进程进行请求处理,如果没有可用进程,返回错误,这也是我们配合 Nginx 遇到502错误比较多的原因。
  • worker 进程处理请求,如果超时,返回504错误
  • 请求处理结束,返回结果

php是如何和nginx配置处理动态资源的呢?

nginx配置

server {
    listen  443 http2 ssl;
    server_name iluoy.com;
    root    /mnt/www/iluoy.com/public;
    index   index.php   index.html  index.htm;

    # 省略ssl配置

    location / {
        concat on;
        concat_max_files 30;
        concat_unique off;
        if (!-e $request_filename) { 
            rewrite ^/(.*) /index.php last;
        }

    } 

    location ~ \.(js|css|png|jpg|jpeg|gif)$ {
        expires off;
        if (!-e $request_filename) {
            break;
        }
    }
    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

.php 结尾的请求都交给 fastcgi 模块处理

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

参考文献

Fast-cgi cgi nginx php-fpm 的关系

Nginx 与 FPM 的工作机制

Nginx+Php-fpm运行原理详解

深入理解PHP之:Nginx 与 FPM 的工作机制