赞
踩
这其实也不只是宝塔的问题,在windows下nginx+fastcgi模式的php,都会发生这个问题。本文以在宝塔windows5.4版中修改为例说明此问题解决方法。
一、发生问题的环境
操作系统: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窗口。(pielin.com)下载地址: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。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。