先上一段fast_cgi的配置代码
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
大部分网上的配置都是这种配置,查询nginx相关资料看到
Nginx和PHP-FPM的进程间通信有两种方式,一种是TCP,一种是UNIX Domain Socket.
其中TCP是IP加端口,可以跨服务器.而UNIX Domain Socket不经过网络,只能用于Nginx跟PHP-FPM都在同一服务器的场景.用哪种取决于你的PHP-FPM配置:
第一种:
[root@mysql etc]# pwd
/usr/local/php/etc
[root@mysql etc]# ls
pear.conf php-fpm.conf php-fpm.conf.default php.ini
[root@mysql etc]#
这是我的php环境中的
php-fpm.conf文件配置: listen = 127.0.0.1:9000
nginx环境中的nginx.conf文件配置:fastcgi_pass 127.0.0.1:9000
第二种:
php-fpm.conf文件配置: listen = /tmp/php-fpm.sock
nginx环境中的nginx.conf文件配置: fastcgi_pass unix:/tmp/php-fpm.sock;
其中php-fpm.sock是一个文件,由php-fpm生成,类型是srw-rw—
UNIX Domain Socket可用于两个没有亲缘关系的进程,是目前广泛使用的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIX Domain Socket通讯的.这种通信方式是发生在系统内核里而不会在网络里传播.UNIX Domain Socket和长连接都能避免频繁创建TCP短连接而导致TIME_WAIT连接过多的问题.对于进程间通讯的两个程序,UNIX Domain Socket的流程不会走到TCP那层,直接以文件形式,以stream socket通讯.如果是TCP Socket,则需要走到IP层,对于非同一台服务器上,TCP Socket走的就更多了.
UNIX Domain Socket:
Nginx <=> socket <=> PHP-FPM
TCP Socket(本地回环):
Nginx <=> socket <=> TCP/IP <=> socket <=> PHP-FPM
TCP Socket(Nginx和PHP-FPM位于不同服务器):
Nginx <=> socket <=> TCP/IP <=> 物理层 <=> 路由器 <=> 物理层 <=> TCP/IP <=> socket <=> PHP-FPM
而此次出现问题的原因在于,我使用的是php配置的UNIX Domain Socket而我的nginx配置的却是tcp方式 配置如下:
location / {
root /home/wwwroot/default/;
index index.htm index.html index.php;
if (!-e $request_filename) {
#地址作为将参数rewrite到index.php上。tp框架接收s参数为controller和action,不少框架都利用这种方式来实现伪pathinfo模式(pathinfo为php功能,nginx并不支持)
rewrite ^/(.*)$ /index.php?s=$1 last;
break;
}
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php(.*)$ {
fastcgi_pass 127.0.0.1:9000; #tcp的方式
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
fastcgi_pass 127.0.0.1:9000是tcp方式的
而我的nginx中有进行引入
location ~ [^/]\.php(/|$)
{
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
导致 php-cgi.sock socket方式和tcp方式共同存在,由于以上配置是通过外不文件引入导致location ~ \.php(.*)$ fast-cgi不生效
所以将php-fpm.conf文件配置: listen = /tmp/php-fpm.sock 和 nginx引入的外部文件配置去除
如果我们使用socket协议方式对应的php--------->nginx
php-fpm.conf
[global]
pid = /usr/local/php/var/run/php-fpm.pid
error_log = /usr/local/php/var/log/php-fpm.log
log_level = notice
[www]
listen = /tmp/php-cgi.sock
listen.backlog = -1
listen.allowed_clients = 127.0.0.1
listen.owner = www
listen.group = www
listen.mode = 0666
user = www
group = www
pm = dynamic
pm.max_children = 80
pm.start_servers = 40
pm.min_spare_servers = 40
pm.max_spare_servers = 80
pm.max_requests = 1024
pm.process_idle_timeout = 10s
request_terminate_timeout = 100
request_slowlog_timeout = 0
slowlog = var/log/slow.log
nginx.conf
location ~* \.php$ {
fastcgi_index index.php;
#fastcgi_pass 127.0.0.1:9000; 注释掉tcp方式
fastcgi_pass unix:/tmp/php-cgi.sock;#使用UNIX Domain Socket
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
如果我们使用tcp协议方式对应的php--------->nginx
php-fpm.conf
[global]
pid = /usr/local/php/var/run/php-fpm.pid
error_log = /usr/local/php/var/log/php-fpm.log
log_level = notice
[www]
listen = 127.0.0.1:9000
user = www
group = www
pm = dynamic
pm.max_children = 80
pm.start_servers = 40
pm.min_spare_servers = 40
pm.max_spare_servers = 80
pm.max_requests = 1024
pm.process_idle_timeout = 10s
request_terminate_timeout = 100
request_slowlog_timeout = 0
slowlog = var/log/slow.log
nginx.conf
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
修改完配置重启php-fpm和nginx -s reload
注:
nginx+php运行原理
nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。
nginx一般是把请求发fastcgi(php-fpm就是其中的一种)管理进程处理,fascgi管理进程选择cgi子进程处理结果并返回被nginx
同样php-fpm程序也如同nginx一样,需要监听端口,并且有master和worker进程。worker进程直接管理每一个php进程