前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >工具系列 | PHP-FPM+Nginx 通信详解

工具系列 | PHP-FPM+Nginx 通信详解

作者头像
Tinywan
发布2023-03-08 20:14:46
2.3K0
发布2023-03-08 20:14:46
举报
文章被收录于专栏:开源技术小栈开源技术小栈

PHP-FPM

PHP-FPM的全称是PHP FastCGI Process Manager,PHP-FPM是FastCGI的实现,并提供了进程管理的功能。FastCGI进程包含master进程和worker进程两种进程。master进程只有一个,负责监听端口,接收Nginx的请求,而worker进程则一般有多个(可配置),每个进程内部都嵌入了一个PHP解释器,是PHP代码真正执行的地方。

Nginx

Nginx (“engine x”) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。这里介绍一下什么是正向代理和反向代理

正向代理

反向代理

PHP-FPM+Nginx通信

FastCGI致力于减少Web服务器与CGI程序之间互动的开销,从而使服务器可以同时处理更多的Web请求。与CGI这种为每个请求创建一个新的进程不同,FastCGI使用持续的进程来处理一连串的请求。这些进程由FastCGI进程管理器管理,而不是web服务器。

通信图

(1)当Nginx收到http请求(动态请求),它会初始化FastCGI环境。(如果是Apache服务器,则初始化mode_fastcgi模块、如果是Nginx服务器则初始化ngx_http_fastcgi_module)。

(2)我们在配置nginx解析php请求时,一般会有这样一行配置:

代码语言:javascript
复制
fastcgi_pass   127.0.0.1:9000;

或者

代码语言:javascript
复制
fastcgi_pass  unix:/tmp/php-cgi.sock;

它其实是Nginx和PHP-FPM一个通信载体(或者说通信方式),目的是为了让Nginx知道,收到动态请求之后该往哪儿发。

(3)Nginx将请求采用socket的方式转给FastCGI主进程 (4)FastCGI主进程选择一个空闲的worker进程连接,然后Nginx将CGI环境变量和标准输入发送该worker进程(php-cgi) (5)worker进程完成处理后将标准输出和错误信息从同一socket连接返回给Nginx (6)worker进程关闭连接,等待下一个连接

不同配置通信

Nginx也是有master和worker进程的,worker进程直接处理每一个网络请求

其实在Nginx+PHP的架构里边,php可以看做是一个cgi程序的角色,因此出现了php-fpm进程管理器来处理这些php请求。php-fpm和nginx一样,也会监听端口(通过nginx.conf里的配置我们知道,nginx默认监听8080端口,php-fpm默认监听9000端口),并且有master和worker进程,worker负责处理每一个php请求

关于fastcgi:fastcgi是一个协议。市面上有多种实现了fastcgi协议的进程管理器,php-fpm就是其中的一种。php-fpm作为一种fastcgi进程管理服务,会监听端口,一般默认监听9000端口,并且是监听本机,也就是只接收来自本机的端口请求

关于fastcgi的配置文件,目前fastcgi的配置文件一般放在nginx.conf同级目录下,配置文件形式,一般有两种:

  • (1)fastcgi.conf。文件地址:/usr/local/openresty/nginx/conf/fastcgi.conf
  • (2)fastcgi_params。文件地址:nginx server的php配置项

当需要处理php请求时,nginx的worker进程会将请求移交给php-fpm的worker进程进行处理,也就是最开头所说的nginx调用了php,其实严格得讲是nginx间接调用php(反向代理的方式)。

代码语言:javascript
复制
location ~ \.php$ {
    try_files $fastcgi_script_name =404;
    include fastcgi_params;
    # fastcgi_pass unix:/var/run/php-fpm.sock;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

(1) include fastcgi_params; 引入fastcgi配置文件

(2) fastcgi_pass 127.0.0.1:9000; 这行代码的意思是,将进入到该location内的uri请求看做是cgi程序,并将请求发送到9000端口,交由php-fpm处理(php-fpm配置中会看见它监听了此端口)

(3) fastcgi_param SCRIPT_FILENAME document_rootfastcgi_script_name;。

这行配置意思是:动态添加了一行fastcgi配置,配置内容为SCRIPT_FILENAME,告知管理进程,cgi脚本名称。由于我的nginx中只有fastcgi_params文件,没有fastcgi.conf文件,所以要使php-fpm知道SCRIPT_FILENAME的具体值,就必须要动态的添加这行配置。

fastcgi_pass

Nginx和PHP-FPM的进程间通信有两种方式:一种是TCP Socket。一种是Unix Socket。

Tcp Socket方式是IP加端口,可以跨服务器,而UNIX Socket不经过网络,只能用于Nginx跟PHP-FPM都在同一服务器的场景。

Tcp Socket方式

  • nginx.conf中配置:fastcgi_pass 127.0.0.1:9000;
  • php-fpm.conf中配置:listen=127.0.0.1:9000;
  • Nginx和PHP-FPM在同一台机器上,通信过程:Nginx <=> socket <=> TCP/IP <=> socket <=> PHP-FPM
  • Nginx和PHP-FPM在同一台机器上,通信过程:Nginx <=> socket <=> TCP/IP <=> 物理层 <=> 路由器 <=> 物理层 <=> TCP/IP <=> socket <=> PHP-FPM

Unix Domain Socket方式

  • nginx.conf中配置:fastcgi_pass unix:/tmp/php-fpm.sock;
  • php-fpm中配置:listen = /tmp/php-fpm.sock; (php-fpm.sock是一个文件,由php-fpm生成)
  • Nginx和PHP-FPM的通信过:Nginx <=> socket <=> PHP-FPM

include fastcgi_params

在nginx中有很多的fasgcgi_*的配置,更多的配置可以在nginx.conf的同级目录中看到,在fastcgi.conffastcgi_params中,这两个的区别,上边有说明。看一下里边的内容:

代码语言:javascript
复制
$ cat fastcgi_params

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_NAME        $fastcgi_script_name;
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  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

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;

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

这里边的内容都会被传递给PHP-FPM所管理的fastcgi进程。为什么会传递这些呢?相信大家都用过$_SERVER这个全局变量,这里边的值就是从此配置中拿到的。我们可以在fastcgi_params中看到REMOTE_ADDR,就是客户端地址,PHP之所以能拿到客户端信息,就是因为Nginx的配置中的fastcgi_params

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PHP-FPM
  • Nginx
    • 正向代理
      • 反向代理
      • PHP-FPM+Nginx通信
        • 通信图
          • 不同配置通信
          • fastcgi_pass
            • Tcp Socket方式
              • Unix Domain Socket方式
              • include fastcgi_params
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档