Windows 下搭建 Nginx + fastcgi + PHP 运行时间长卡死 / 并发阻塞卡死问题
2020年9月12日11:10:11 更新
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 是一个隐藏输出的工具程序,非常实用。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论