用宝塔windows面板建站时nginx+php并发阻塞(用curl请求本地文件无限超时)问题解决方法,提高性能

  这其实也不只是宝塔的问题,在windows下nginx+fastcgi模式的php,都会发生这个问题。本文以在宝塔windows5.4版中修改为例说明此问题解决方法。

  对于需要付费购买宝塔的朋友,可参加近期优惠活动:点此可以领取宝塔¥3188元礼包,券可直接用于抵扣。

一、发生问题的环境

  操作系统:windows

  Web软件:nginx

  脚本解析:php(以fastcgi模式运行,windows大多也只能以这个模式)

二、问题表现

  表现1:当浏览器打开1个php页面尚未打开时,再打开同项目网站第2页面会阻塞,浏览器一直在空白,转圈圈状态,直到第1个页完全打开后,第2个页面才会开始被执行并打开。

  表现2:curl去get本地文件时,表示为阻塞,直到超时。这个过程中,两个网站其它页全部被阻塞,表示为浏览器打开时为空白。

三、问题原因:

  Windows下PHP_FCGI_CHILDREN无效。

  一般情况下Windows下Nginx对php的请求都是通过 fastcgi_pass 127.0.0.1:9000 处理,在宝塔中配置为 fastcgi_pass 127.0.0.1:4570(其中70是php版,本文以此版本为例,如php5.6则是监听端口4556,7.1是 4571,实际操作时请做相应修改),当新接受到多个cgi请求时,cgi不会自动产生新进程去处理并发请求,只能排队(而在Ubuntu等linux类操作系统中,则会自动利用子进程去处理并发的其它请求)。而curl本地文件时,curl本身要占用队列,curl请求的对象不可能得到新的队列,所以最后的结果就是陷入无限等待(卡死),直到超时。

四、解决方法:

  原理:利用nginx的upstream负载均衡功能,手动启动多个cgi进程的方法,监听不同的端口来解决。

  步骤:

  1、在宝塔安装目录中新建文件夹 php_proxy

  本文测试时的宝塔安装在 D:\BtSoft\WebSoft,所以文件夹位置就是 D:\BtSoft\WebSoft\php_proxy。当然这个文件夹名字可以任意改,但要和后续步骤中的名字对应。

  2、下载一个 RunHiddenConsole 的小工具到 php_proxy 文件夹中

  此工具用来隐藏cmd窗口。(本站(think3.cc)下载地址:RunHiddenConsole.rar    )

  3、建立php-cgi启动文件:

  在 php_proxy 目录下,新建一个php70_proxy.txt文件,将以下内容填入后,然后保存,然后将文件后缀修改为 bat,使其成为php70_proxy.bat 文件(双击此文件即可启动多个监听在不同端口的php-cgi进程):

D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45701 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"
D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45702 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"
D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45703 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"
D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45704 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"
D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45705 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"
D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45707 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"
D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45708 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"
D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45709 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"
D:\BtSoft\WebSoft\php_proxy\RunHiddenConsole.exe "D:/BtSoft/WebSoft/php/7.0/php-cgi.exe" -b 127.0.0.1:45700 -c "D:/BtSoft/WebSoft/php/7.0/php.ini"

  此bat文件运行后,将启动10个php-cgi进程,并监听在不同的端口:45700-45709,(端口也可以自己定义,范围为10000-65535之间),运行后再也不会出现curl本地文件阻塞的问题了。

  4、在宝塔中添加关联启动:修改 D:\BtSoft\WebSoft\wwwroot\default\config.php 文件,在

if($result) ajax_return($result);

  前面添加一句,成为以下样子:

exec('D:\BtSoft\WebSoft\php_proxy\php70_proxy.bat');
if($result) ajax_return($result);

  这样,在你每次通过宝塔面板重启nginx时,都能再次自动执行此bat文件,以便启动多个php-cgi进程。

  5、在nginx配置文件中添加一个upstream,名为 php70_proxy

    upstream php70_proxy {
        server 127.0.0.1:4570;
        server 127.0.0.1:45701;
        server 127.0.0.1:45702;
        server 127.0.0.1:45703;
        server 127.0.0.1:45704;
        server 127.0.0.1:45705;
        server 127.0.0.1:45706;
        server 127.0.0.1:45707;
        server 127.0.0.1:45708;
        server 127.0.0.1:45709;
        server 127.0.0.1:45700;
    }

  修改后如下图:

  6、所有使用php的网站,在网站->配置->配置文件中将 

fastcgi_pass 127.0.0.1:4570;

  改为

fastcgi_pass   php70_proxy;

  修改后如下图:

  7、重启nginx后,以上设置就全部生效了

  8、将 D:\BtSoft\WebSoft\php_proxy\php70_proxy.bat 添加到开机启动中,以便在服务器重启后也能生效。

  题后话:

  在windows下要运行php,建议使用apache,php的并发支持更好一些,虽然nginx并发能力强,但在windows中由于这个限制的存在,并不能完全发挥,如果要使用高并发能力的,操作系统使用linux系列比较好(如Centos,Ubuntu等版本)。

  并不建议在实际环境中使用windows+nginx的方案,虽然按上面优化后,有好转,但实际使用中,还是会产生卡的情况。也就是说windows对nginx的这个性能原生支持并不好。windows平台上,实际使用环境,还是只能使用apache或IIS。

欢迎加入 SEO建站技术交流群 SEO建站技术交流 905633541 群里可以讨论交流建站话题

欢迎转载,请注明来源:https://www.think3.cc/?id=11

评论列表: (共0条评论)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。