Nginx与php-fpm之间的通信机制

image.png

理解一个完整的PHP请求前,需要搞明白cgi、php-cgi、fastcgi、php-fpm的相关概念

cgi协议:

cgi协议是用来确定web服务器(如NGINX)和CGI应用程序(如PHP),是保证web server传递过来的数据是标准格式的,方便CGI程序编写。

php-cgi进程解释器:

php-cgi是php的cgi协议进程解释器,进程就是程序的工作单位。进程每次启动时,需要经历加载php.ini文件->初始化执行环境->处理请求->返回内容给web服务器->php-cgi进程退出的流程。

Fast-cgi协议:

Fast-cgi协议是对cgi协议效率提升的补充,主要是针对每次请求过来时都需要启动一个cgi解释器进程的优化,不需要cgi解释器进程每次收到web服务器请求后秋需要重新加载php.ini文件和初始化执行环境。

php-fmp进程管理器:

php-fpm是对fast-cgi协议的实现,是进程管理器,启动时包括master进程和work进程两部分,master进程负责监听端口,接收来自web服务器的请求,worker进程一般有多个,每个worker进程都有一个cgi进程解释器,用来执行php代码。

php-fpm即php-Fastcgi Process Manager。php-fpm是 FastCGI 的实现,并提供了进程管理的功能。进程包含 master 进程和 worker 进程两种进程。master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌入了一个PHP解释器,是PHP代码真正执行的地方。

php脚本执行原理过程:

启动php-fpm时,会启动master进程,加载php.ini文件,初始化执行环境,并启动多个worker进程。每次接收的web请求时,将会将web请求传递给work进程进行处理。

完整的流程:

用户访问URL地址->域名进行DNS解析->请求到对应的IP服务器和端口->NGINX监听对应的端口请求->NGINX对url进行location匹配->执行匹配location下的规则->NGINX转发请求给php->php-fpm的master进程监听到NGINX请求->master进程将请求分配给一个闲置的worker进程->worker进程执行请求->worker进程返回执行结果给NGINX->NGINX返回结果给用户

image.png

PHP-FPM+Nginx通信示意图

image.png

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

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

fastcgi_pass 172.0.0.1:9000

或者长这样:

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进程关闭连接,等待下一个连接

image.png

从配置的角度,再描述一下PHP和Nginx的通信

1、我们知道Nginx也是有master和worker进程的,worker进程直接处理每一个网络请求

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

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

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

fastcgi.conf和 fastcgi_params。

不同的nginx版本会有不同的配置文件,这两个配置文件有一个非常重要的区别:fastcgi_parames文件中缺少下列配置:

fastcgi_param SCRIPT_FILENAME document_rootfastcgi_script_name;

我们可以打开fastcgi_params文件加上上述行,也可以在要使用配置的地方动态添加。使得该配置生效。

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

我本机配置了能正常解析php程序的nginx配置,解释一下每一行配置的含义:

server{

listen 8080;

index index.php

root /work/html/;

location ~ [^/].php(/|$)

{

root /work/html/;

fastcgi_pass 127.0.0.1:9000;

fastcgi_param SCRIPT_FILENAME document_rootfastcgi_script_name;

include fastcgi_params;

}

access_log /work/html/logs/test.log;

}

1、第一个大括号 server{ }:代表一个独立的server

2、listen 8080:代表该server监听8080端口

3、location ~ [^/].php(/|$){ }:代表一个能匹配对应uri的location,用于匹配一类uri,并对所匹配的uri请求做自定义的逻辑、配置。这里的location,匹配了所有带.php的uri请求,例如:http://192.168.244.128:8011/test.php/asdasd http://192.168.244.128:8011/index.php

4、root /work/html/:请求资源根目录,告诉匹配到该location下的uri到/work/html/文件夹下去寻找同名资源。

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

6、fastcgi_param SCRIPT_FILENAME

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

7、include fastcgi_params; 引入fastcgi配置文件

fastcgi_pass

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

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

Tcp Socket方式:

nginx.conf中配置:fastcgi_pass 127.0.0.1:9000;

php-fpm.conf中配置:listen=127.0.0.1:9000;

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的通信过程如下:

Tcp Socket:

Nginx <=> socket <=> TCP/IP <=> socket <=> PHP-FPM

(上边画Nginx和PHP-FPM通信的图时就是这种方式,这种情况是Nginx和PHP-FPM在同一台机器上)

看一下Nginx和PHP-FPM不在同一台机器上的情况:

Nginx <=> socket <=> TCP/IP <=> 物理层 <=> 路由器 <=> 物理层 <=> TCP/IP <=> socket <=> PHP-FPM

Unix Socket:

Nginx <=> socket <=> PHP-FPM

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,667评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,361评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,700评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,027评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,988评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,230评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,705评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,366评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,496评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,405评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,453评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,725评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,803评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,015评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,514评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,111评论 2 341

推荐阅读更多精彩内容