PHP-FPM引入了CGI协议和FastCGI协议每种动态语言(PHP、Python等)的代码文件都需要通过相应的解析器才能被识别服务器,CGI协议使用使解释器和服务器能够相互通信。在服务器上解析PHP文件需要使用PHP解释器,加上相应的CGI协议,这样服务器才能解析到PHP文件。由于CGI的机制是每处理一个请求就fork一个CGI进程,请求完成后再kill进程,在实际应用中很浪费资源,所以出现了CGI的改进版本FastCGI。请求处理完成后,FastCGI不会Kill进程,而是继续处理多个请求,大大提高了效率。什么是PHP-FPM?PHP-FPM即PHP-FastCGIProcessManager,是FastCGI的实现,提供进程管理的功能。进程包括两种类型:master进程和worker进程;master进程只有一个,负责监听端口和接收服务器请求,而worker进程一般有多个(具体数量根据实际需要配置),每个进程都会嵌入一个PHP解释器,是实际执行代码的地方。Nginx与php-fpm通信机制当我们访问一个网站(比如www.test.com)时,处理流程是这样的: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||等待处理...Nginx与php-fpm的结合在Linux上,nginx与php-fpm的通信有两种方式:tcpsocket和unixsocket。tcpsocket的优点是可以跨服务器使用。这种方法只能在nginx和php-fpm不在同一台机器上的情况下使用。Unixsocket也叫IPC(inter-processcommunication)套接字,用于实现同一主机上的进程间通信。该方法需要在nginx配置文件中填写php-fpm的socket文件位置。两种方式的数据传输过程如下图所示:两者的区别:因为Unixsocket不需要经过网络协议栈,不需要打包解包,计算校验和,维护序列号和回复等,但只是将应用层数据从一个进程复制到另一个进程。所以它的效率比tcpsocket要高,可以减少不必要的tcp开销。但是unixsockets在高并发时不稳定,当连接数爆炸时,会产生大量的长期缓存。没有面向连接协议的支持,大数据包可能直接出错,不返回异常。tcp等面向连接的协议可以更好的保证通信的正确性和完整性。Nginx和php-fpm的结合只需要在各自的配置文件中设置:1.Nginx中的配置以tcpsocket通信为例server{listen80;#监听80端口,接收http请求server_namewww.test.com;#就是网站地址root/usr/local/etc/nginx/www/huxintong_admin;#准备存放代码项目的路径#路由到网站根目录时的处理www.test.comlocation/{indexindex.php;#jump转到www.test.com/index.phpautoindexon;}#在网站请求php文件时,反向代理到php-fpm所在位置~\.php${include/usr/local/etc/nginx/fastcgi.conf;#加载nginx的fastcgi模块fastcgi_intercept_errorson;fastcgi_pass127.0.0.1:9000;#tcp方式,php-fpm监听的IP地址和端口#fasrcgi_pass/usr/run/php-fpm.sock#unixsocket连接方式}}2.php-fpm的配置listen=127.0.0.1:9000#或者下面的listen=/var/run/php-fpm.sock注意在使用unixsocket连接时,由于socket文件本质上是一个文件,有一个问题的权限控制,所以需要注意nginx进程的权限和php-fpm的权限,否则会提示没有权限访问。(在各自的配置文件中设置用户)通过以上配置,即可完成php-fpm与nginx的通信。应用中的选择如果nginx和php-fpm运行在同一台服务器上,并发不高(不超过1000),选择unixsocket,提高nginx和php-fpm的通信效率。如果面对高并发业务,可以考虑使用更可靠的tcpsocket,以负载均衡、内核优化等运维方式保持效率。如果并发度很高但还是想使用unixsocket,可以通过以下方式提高unixsocket的稳定性。1)把sock文件放在/dev/shm目录下,在这个目录下把sock文件放在内存中,内存读写速度更快。2)将backlogbacklog的默认值增加到128,将1024的值替换成自己正常的QPS。配置如下。在nginx.conf文件中server{listen80defaultbacklog=1024;}php-fpm.conffilelisten.backlog=10243)添加sock文件和php-fpm实例在/dev/shm新建sock文件,传入nginxupstream模块将请求负载均衡到两个sock文件,映射两个sock文件分别到两组php-fpm实例。
