使用php-fpm还是php-cgi?使用tcp还是socket?

什么是php-fpm?

公共网关接口(CGI),是使得应用程序(称为 CGI 程序或 CGI 脚本)能够与 Web 服务器以及客户端进行交互的标准协议。这些 CGI 程序可以用 Python、PERL、Shell、C 或 C++ 等进行编写。

CGI是一个协议,浏览器的请求到服务器web server(比如nginx) ,比如test.php, nginx 配置发现其是php文件格式的,nginx找到php.ini, 初始化执行环境。nginx启动php解析器(CGI程序php-cgi), CGI协议把url参数,header,POST参数之类的信息以规定的格式传给CGI程序执行,处理完之后,以规定的格式返回web server。CGI退出进程。web server 返回结果给浏览器。

服务器接受请求,分发资源。
CGI以规定的格式接受参数,返回结果。
php-cgi php执行程序。

Fastcgi会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker, 当请求过来时,分配worker去执行请求,有多个空闲worker时,也会杀死worker。节约资源,提高php执行效率。

fastcgi也是一种执行协议;php-cgi 和php-fastcgi都是php的执行程序。两种不同的执行方式,他们只接收参数,返回结果,但是并不管理进程。
PHP拓展包里面的php-fpm,php-cgi拓展包都是能管理php进程。php-fpm是以php-fastcgi方式执行的。php-cgi是以原始的单线程方式执行的。

PHP-CGI是PHP自带的FastCGI管理器。
当php.ini 修改之后php-cgi 需要重新启动才能生效,php-cgi重启,php程序会中断。

PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理协议整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可以使用。

php-fpm常驻内存,同时开启多个php-cgi等待任务,php-fpm是多进程的,而一个php-cgi基本消耗7-25M内存,因此如果连接过多就会导致内存消耗过大,引发一些问题,例如nginx里的502错误。php.ini 配置发生更改时,php-fpm不需要重启,新的php-cgi延用新的配置,正在执行的php-cgi延用旧的配置直到进程结束。

默认的nginx配置有以下两种通信方式
使用tcp方式,使php-cgi与nginx通信,端口9000
location ~ \.php$ {
        include snippets/fastcgi-php.conf;
#
#       # With php-fpm (or other unix sockets):
#        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
#       # With php-cgi (or other tcp sockets):
       fastcgi_pass 127.0.0.1:9000;
}
使用php-fpm sock 方式,使php与nginx 通信。
location ~ \.php$ {
        include snippets/fastcgi-php.conf;
#
#       # With php-fpm (or other unix sockets):
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
#       # With php-cgi (or other tcp sockets):
#      fastcgi_pass 127.0.0.1:9000;
}   
tcp 方式和sock方式的优缺点
unix socket方式

优点:
unix socket方式要比tcp的方式快,而且消耗资源少,因为socket之间在nginx和php-fpm的进程之间通信,而tcp需要经过本地回环驱动,还要申请临时端口和tcp相关资源。

会有很多linux傻瓜面板,他们可能会有很多中 php-fpm的版本,那么如果是不同版本去开不同的端口,然后nginx去配置的话,你要记住很多端口,sock文件便是解决这个问题最简单的方法。

Socket是使用unix domain socket连接套接字/dev/shm/php-cgi.sock(很多教程使用路径/tmp,而路径/dev/shm是个tmpfs,速度比磁盘快得多)

缺点:
unix socket会显得不是那么稳定,当并发连接数爆发时,会产生大量的长时缓存,在没有面向连接协议支撑的情况下,大数据包很有可能就直接出错并不会返回异常。

虽然sock有更少的数据拷贝和上下文切换,更少的资源占用,但是如果数据都是错的,那还有什么用呢。另外使用sock的话,必须nginx和fpm在同一台机器上

tcp方式

优点:
从稳妥的考虑肯定是使用tcp,tcp协议能保证数据的正确性,sock不能保证。

可以跨服务器,当nginx和php-fpm不在同一台机器上时,只能使用这种方式

缺点:
性能不如unix socket

结论

在服务器压力不大的情况下,tcp和socket差别不大,但在压力比较满的时候,用套接字方式,效果确实比较好。
(未亲测)

常见问题

502错误
使用tcp,是否开启9000端口
#php 是否开启
ps aux | grep php
#9000端口是否被监听
netstat -antp | grep 9000
#开启9000
php-cgi -b 127.0.0.1:9000
#PHP是否使用tcp形式
#查看 /etc/php/7.0/fpm/pool.d/www.conf
;listen = /var/run/php/php7.0-fpm.sock
listen = 127.0.0.1:9000
使用socket
#文件路径是否正确,文件是否存在
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
#查看 /etc/php/7.0/fpm/pool.d/www.conf
#listen是否正确,listen owner是否正确
listen = /var/run/php/php7.0-fpm.sock
;listen = 127.0.0.1:9000
;listen.owner = www-data
;listen.group = www-data
;listen.mode = 0666

https://www.cnblogs.com/luoahong/articles/9139888.html

你可能感兴趣的:(使用php-fpm还是php-cgi?使用tcp还是socket?)