Nginx下请求本机另外Host很慢怎么办
这篇文章给大家分享的是有关Nginx下请求本机另外Host很慢怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
现象
在本机安装了一个Discuz!X3.4的论坛,其使用UCenter作为统一用户登录,在其应用管理页面,通信情况一直提示为"正在连接":
原因
关于这个问题,网上绝大多数的说法是nginx服务器在Windows上有问题,建议更换为Apache,我更换到Apache下,也确实是问题解决了,但是我还是觉得nginx不至于有这种问题,一定有解决的办法。
再继续查找,发现nginx日志里有报告499错误,网上说499错误的原因是客户端主动断开了与服务器的连接,可是看ucenter的代码,貌似并没有断开连接的操作,倒是看日志报告的时间,发现一点端倪:
127.0.0.1 - - [18/Jul/2018:22:35:48 +0800] "GET /uc_server/admin.php?m=app&a=ls&… 127.0.0.1 - - [18/Jul/2018:22:36:19 +0800] "GET /api/uc.php?code=434eRMR%2FD%2FtjZ357V3sA9RLPqp0rpGfi7ryntpyVEEYay3xgen8Oqk9ETjgEXNbyEbKItHYPZqs HTTP/1.0" 499 … 127.0.0.1 - - [18/Jul/2018:22:36:19 +0800] "GET /uc_server/admin.php?m=app&a=ping&inajax=1&url=… |
第1行日志,是ucenter应用管理中心页面的链接,在这个页面里,ucenter向本机的Discuz服务器发出通信验证请求(第3行日志),而第2行日志,就是Discuz服务器收到的通信验证请求,499错误就是出现在此行。
仔细查看这3条日志的时间,发现第2、3条与第1条间隔差不多29秒,我们知道,PHP默认的超时时间为30秒,算上点误差,29秒也差不多。因此可以认为这个499错误是因为ucenter服务器发起了ping请求(第3行日志),一直没有接收到返回值,结果超时断开连接,从而导致discuz服务器出现499错误。
整个流程如下图:
知道是499错误,于是又查找如何解决499问题,结果大多数提出要在nginx服务器中添加如下配置:
proxy_ignore_client_abort on; fastcgi_ignore_client_abort on; |
在Discuz的配置项中添加了上述配置:
location ~ \.php$ { root C:/PHPackage/workspace/github/DiscuzX/bbs; fastcgi_pass 127.0.0.1:9090; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; proxy_ignore_client_abort on; fastcgi_ignore_client_abort on; } |
再运行服务器,发现499问题果然没了,但是通信问题依然没有解决,只是日志变为如下了:
127.0.0.1 - - [18/Jul/2018:22:35:48 +0800] "GET /uc_server/admin.php?m=app&a=ls&… 127.0.0.1 - - [18/Jul/2018:22:36:19 +0800] "GET /api/uc.php?code=434eRMR%2FD%2FtjZ357V3sA9RLPqp0rpGfi7ryntpyVEEYay3xgen8Oqk9ETjgEXNbyEbKItHYPZqs HTTP/1.0" 200 … 127.0.0.1 - - [18/Jul/2018:22:36:19 +0800] "GET /uc_server/admin.php?m=app&a=ping&inajax=1&url=… |
配置生效了,但是有个毛用啊,通信还是不成功。第1条日志和下面两条日志还是差了差不多30秒左右。回过头来仔细分析上面的两个配置项,应该是让nginx服务器忽略客户端断开的错误,注意,仅仅是让服务器忽略这个错误,也就是说,当ucenter请求超时,断开连接的时候,discuz服务器忽略了这个错误,从而返回200,可是ucenter实际上已经断开了,也收不到discuz的返回值,所以实际上还是通信失败。
不过再进一步分析上面的流程,从nginx与php的关系来看,发现整个请求处理如下图:
nginx收到请求后,发现是需要执行PHP代码,于是将请求就转给了PHP-CGI进程,由该进程找到PHP代码并执行,但是在PHP代码中,又再次向本机的另一个服务器发出HTTP请求,nginx收到后,发现同样要执行PHP代码,于是将请求又转回给PHP-CGI进程,但是系统中PHP-CGI进程只开了一个,后面的PHP代码要等到上面的执行完毕才能执行,而后面的PHP代码却又是上面的代码请求产生的,于是就阻塞了。
1.1.3 解决
分析至此,解决的思路就已经很清晰了,既然一个PHP-CGI线程处理不过来,那么就增加一个线程好了,修改启动nginx服务器的批处理代码如下,仅修改一个数字,见红色字体部分:
@echo off REM Windows 下无效 REM set PHP_FCGI_CHILDREN=5 REM 每个进程处理的最大请求数,或设置为 Windows 环境变量 set PHP_FCGI_MAX_REQUESTS=1000 echo Starting PHP FastCGI... rem RunHiddenConsole C:/PHPackage/PHP/php-cgi.exe -b 127.0.0.1:9090 -c C:/PHPackage/PHP/php.ini RunHiddenConsole xxfpm "C:/PHPackage/PHP/php-cgi.exe -c C:/PHPackage/PHP/php.ini" -n 2 -i 127.0.0.1 -p 9090 echo Starting nginx... RunHiddenConsole C:/PHPackage/nginx-1.15.1/nginx.exe -p C:/PHPackage/nginx-1.15.1 |
该数字原来是1,现在改为2,重新启动服务器,看任务管理器,果然有两个PHP-CGI进程:
再回到ucenter的应用管理页面,刷新,结果如下:
啥情况?我们上面折腾了半天,只是从"正在连接"变成了"通信失败",问题还是没有解决啊!
不过呢,跟踪代码可以验证,499的问题的确是彻底解决了,至于为什么还是"通信失败",那是另外一个问题了。
感谢各位的阅读!关于"Nginx下请求本机另外Host很慢怎么办"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!