Windows 下 php-cgi 进程极其不稳定,此方法虽然能解决并发阻塞问题,但是不能根本上解决 网站访问问题,终极解决方法参见:Nginx 搭建 PHP 运行环境 在 Windows 环境下 php-cgi 不稳定经常自动关闭 xxfpm 一个小巧的 FastCGI 进程管理器
由于支付宝小程序和头条小程序 API 接口不支持端口,而我的接口是通过 eggjs 写的,通过 Nginx 反向代理对外访问,Apache 已经占用了 80 端口,所以只有换到 Nginx 来提供 Web 服务,通过 Nginx + fastcgi + PHP 运行网站,花了一天的时间才把运行环境搭建好,但是晚上的时候发现网站打不开了。
具体问题表现就是 PHP 的网站完全打不开,过会儿就是 502 状态,而反向代理的 API 服务完全没有问题,没有任何错误提示信息,日志也没有任何新记录。
重启 Nginx 后能暂时解决卡死的问题,但是过会儿又会出现这个问题,经过一番测试,我怀疑是不是配置的 Nginx 无法并发?
我访问服务 A 是一个请求,服务 A 访问服务 B 的接口则是第二个请求。在无法并发只能排队请求的情况下,第一个请求依赖于第二个请求的结果,第二个请求却排在后面一直等待第一个请求执行完毕。这就导致互相依赖产生死循环,并发阻塞卡死问题。
nginx以高并发闻名,怎么偏偏默认不支持并发?
谷歌找了很多关于 Nginx 并发的文章,挨个儿尝试设置,全都以失败告终。
无意间发现了这么一条信息:
Windows下 PHP_FCGI_CHILDREN 无效,参见:https://bugs.php.net/bug.php?id=49859
一般情况下 Windows 下 Nginx 的配置都是 fastcgi_pass 127.0.0.1:9000; ,也就是说 cgi 根本不会自动产生新进程去处理并发请求,只能排队,那要怎么办?既然不能自动生成,那就只好创建了。
我们额外启动多个 php-cgi 进程去处理并发请求,首先在nginx.conf中进行如下配置:
upstream phpfastcgi_proxy {
server 127.0.0.1:9000;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
server 127.0.0.1:9004;
server 127.0.0.1:9005;
server 127.0.0.1:9006;
server 127.0.0.1:9007;
server 127.0.0.1:9008;
server 127.0.0.1:9009;
server 127.0.0.1:9010;
server 127.0.0.1:9011;
server 127.0.0.1:9012;
}
再把所有
fastcgi_pass 127.0.0.1:9000;
改为
fastcgi_pass phpfastcgi_proxy;
保存配置文件,重启 Nginx,Nginx 会自动将请求转发给 9000-9012 其中一个空闲端口中,接下来我们还需要启动对应数量的 php-cgi 去监听端口:
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9000 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9001 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9002 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9003 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9004 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9005 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9006 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9007 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9008 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9009 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9010 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9011 -c %php_home%php.ini
RunHiddenConsole %php_home%php-cgi.exe -b 127.0.0.1:9012 -c %php_home%php.ini
上面代码是我的启动脚本里面的一段,RunHiddenConsole 是一个隐藏输出的工具程序,非常实用。