Windows 下搭建 Nginx + fastcgi + PHP 运行时间长卡死 / 并发阻塞卡死问题

发布于 2020-09-08 21:40:42 字数 3065 浏览 2928 评论 0

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

qq_Yqvrrd

文章 0 评论 0

2503248646

文章 0 评论 0

浮生未歇

文章 0 评论 0

养猫人

文章 0 评论 0

第七度阳光i

文章 0 评论 0

新雨望断虹

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文