一、初识Nginx与Php-fpm
Nginx是什么
Nginx (“enginex”) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。
Php-fpm是什么
1、cgi、fast-cgi协议
cgi的历史
早期的webserver只处理html等静态文件,但是随着技术的发展,出现了像php等动态语言。
webserver处理不了了,怎么办呢?那就交给php解释器来处理吧!
交给php解释器处理很好,但是,php解释器如何与webserver进行通信呢?
为了解决不同的语言解释器(如php、python解释器)与webserver的通信,于是出现了cgi协议。只要你按照cgi协议去编写程序,就能实现语言解释器与webwerver的通信。如php-cgi程序。
CGI的全称是Common Gateway Interface(通用网关接口),它使得任何一个拥有标准输入输出的程序拥有提供web server的能力,是服务器与后台语言交互的协议,有了这个协议,开发者可以使用任何语言处理服务器转发过来的请求,动态地生成内容,保证了传递过来的数据是标准格式的(规定了以什么样的格式传哪些数据(URL、查询字符串、POST数据、HTTP header等等)),方便了开发者。
fast-cgi的改进
有了cgi协议,解决了php解释器与webserver通信的问题,webserver终于可以处理动态语言了。但是,webserver每收到一个请求,都会去fork一个cgi进程,请求结束再kill掉这个进程。这样有10000个请求,就需要fork、kill php-cgi进程10000次。
有没有发现很浪费资源?
于是,出现了cgi的改良版本,fast-cgi。fast-cgi每次处理完请求后,不会kill掉这个进程,而是保留这个进程,使这个进程可以一次处理多个请求。这样每次就不用重新fork一个进程了,大大提高了效率。
2、php-fpm是什么
php-fpm即Php-Fastcgi Process Manager,php-fpm是 FastCGI 的实现,并提供了进程管理的功能。
进程包含 master 进程和 worker 进程两种进程。
master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。可以在终端上看一下php-fpm的进程。
从FPM接收到请求,到处理完毕,其具体的流程如下
- FPM的 master进程接收到请求。
- master进程根据配置指派特定的
- worker进程进行请求处理,如果没有可用进程,返回错误,这也是我们配合 Nginx遇到 502错误比较多的原因。
- worker进程处理请求,如果超时,返回 504错误。
- 请求处理结束
- 返回结果。
二、Nginx和Php-fpm的通信机制
我们知道,Nginx不仅仅是一个Web服务器,也是一个功能强大的代理服务器,除了进行http请求的代理,也可以进行许多其他协议请求的代理,Nginx就是通过反向代理功能将动态请求转向后端Php-fpm。下面是Nginx的相关配置。
server {
listen 80; #监听80端口,接收http请求
server_name www.test.com; #就是网站地址
root /www/wwwroot/test; # 准备存放代码工程的路径
#路由到网站根目录www.test.com时候的处理
location / {
index index.php; #跳转到www.test.com/index.php
autoindex on;
}
#当请求网站下php文件的时候,反向代理到php-fpm
location ~ \.php$ {
include fastcgi.conf; #加载nginx的fastcgi模块
fastcgi_intercept_errors on;
fastcgi_pass 127.0.0.1:9000; #nginx fastcgi进程监听的IP地址和端口
#还有一种方式是通过socket,例:fastcgi_pass unix:/tmp/php-cgi-73.sock;
}
}
上面提到了,Nginx和Php-fpm有两种通信方式,可以使用127.0.0.1:9000和unix:/tmp/php-cgi-73.sock这两种方式来调用php-fpm。它们有什么区别呢?
前者,一般带9000端口号的,是tcp形式的调用。也就是php-fpm启动了一个监听进程对9000端口进行监听。它会调起一个tcp/ip服务,nginx在调用的时候会走一次tcp请求流程,也就是3次握手4次挥手,会走到网络七层中的第四层传输层。相对来说这种方式性能会稍差一点,启动php-fpm后使用netstat查看端口中会出现9000端口的占用。
后者,使用的是unix套接字socket服务,通过sock文件来交换信息,性能相对好一些,因为它没有tcp连接过程,也不会有9000端口的占用。
对于高负载大访问量的网站还是推荐使用unix方式,对于普通小网站来说,无所谓使用哪个都可以,tcp方式反而更容易配置和理解,也是php-fpm.conf中默认的监听方式。
nginx与php-fpm的结合,完整的流程是这样的。
www.test.com
|
|
Nginx
|
|
路由到www.test.com/index.php
|
|
加载nginx的fast-cgi模块
|
|
fast-cgi监听127.0.0.1:9000地址
|
|
www.test.com/index.php请求到达127.0.0.1:9000
|
|
php-fpm 监听127.0.0.1:9000
|
|
php-fpm 接收到请求,启用worker进程处理请求
|
|
php-fpm 处理完请求,返回给nginx
|
|
nginx将结果通过http返回给浏览器
参考文件:
https://sunzhy.blog.csdn.net/article/details/52972699