Nginx、CGI、FastCGI、php-fpm关系,介绍了 NGINX PHP-FPM FastCGI 之间的关系。

本问介绍一下 NGINX 与 PHP-FPM 是如何进行通讯的,NGINX 是如何将请求转发到 PHP-FPM,PHP-FPM 有事如何知道该区找哪个脚本执行相应的代码逻辑。

建立连接

NGINX 通过 fastcgi_pass 与 PHP-FPM 建立连接,fastcgi_pass 有两种方式进行配置

通过 TCP 连接

1
fastcgi_pass 127.0.0.1:9000;

优势:

  1. 将 PHP-FPM 与 NGINX 进行解耦,可以动态的扩展 PHP-FPM 的服务数量

劣势:

  1. 由于将服务暴露到外网,会带来一些安全相关的风险

通过 UNIX socket 连接

1
fastcgi_pass unix:/var/run/php-fpm.sock;

优势:

  1. 进程间通讯,效率更高

劣势

  1. NGINX 和 PHP-FPM 必须在同一系统环境内

两种建立连接的方式都需要 PHP-FPM 配置进行配合,如果 NGINX 采用 TCP 连接,则 PHP-FPM 也需要进行 TCP 的监听,反之亦然。

传递参数

PHP 在处理业务的时候需要一些参数比如:用户的 quey 和 请求 URL…,这些参数 NGINX 是如何传递给 PHP-FPM 的呢?

在 NGINX 有 fastcgi_param 配置,通过此配置,可以将 PHP-NPM 所需参数传递给 PHP-FPM。

fastcgi_param 常见参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;

fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name;
fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
fastcgi_param   PATH_INFO               $fastcgi_path_info;
fastcgi_param   PATH_TRANSLATED         $document_root$fastcgi_path_info;
fastcgi_param   REQUEST_URI             $request_uri;
fastcgi_param   DOCUMENT_URI            $document_uri;
fastcgi_param   DOCUMENT_ROOT           $document_root;
fastcgi_param   SERVER_PROTOCOL         $server_protocol;

fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR             $remote_addr;
fastcgi_param   REMOTE_PORT             $remote_port;
fastcgi_param   SERVER_ADDR             $server_addr;
fastcgi_param   SERVER_PORT             $server_port;
fastcgi_param   SERVER_NAME             $server_name;

fastcgi_param   HTTPS                   $https;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS         200;

NGINX 通过 fastcgi_param 将 PHP-FPM 所需要的参数传给 PHP-FPM。PHP 代码通过 $_SERVER 全局变量获取 NGINX 传入的参数。

这其中 SCRIPT_FILENAME 是比较重要的一个参数,他将决定 PHP-FPM 去哪里找我们的 PHP 代码。PHP-FPM 找到对应的文件后,执行相关代码然后将处理结果返回给 NGINX。NGINX 再将处理的返回值返回给浏览器。

参考连接

PHP FastCGI Example

What are the differences from running PHP-FPM over an Unix Socket vs a TCP/IP Socket?

How to Connect NGINX to PHP-FPM Using UNIX or TCP/IP Socket