Nginx下,请求本机另外Host很慢

现象

在本机安装了一个Discuz!X3.4的论坛,其使用UCenter做为统一用户登陆,在其应用管理页面,通讯状况一直提示为“正在链接”:php

  image.png

缘由

关于这个问题,网上绝大多数的说法是nginx服务器在Windows上有问题,建议更换为Apache,我更换到Apache下,也确实是问题解决了,可是我仍是以为nginx不至于有这种问题,必定有解决的办法。nginx

 

再继续查找,发现nginx日志里有报告499错误,网上说499错误的缘由是客户端主动断开了与服务器的链接,但是看ucenter的代码,貌似并无断开链接的操做,却是看日志报告的时间,发现一点端倪:git

127.0.0.1 - - [18/Jul/2018:22:35:48   +0800] "GET /uc_server/admin.php?m=app&a=ls&…github

127.0.0.1 - - [18/Jul/2018:22:36:19   +0800] "GET   /api/uc.php?code=434eRMR%2FD%2FtjZ357V3sA9RLPqp0rpGfi7ryntpyVEEYay3xgen8Oqk9ETjgEXNbyEbKItHYPZqs   HTTP/1.0" 499ajax

127.0.0.1 - - [18/Jul/2018:22:36:19   +0800] "GET /uc_server/admin.php?m=app&a=ping&inajax=1&url=…api

 

1行日志,是ucenter应用管理中心页面的连接,在这个页面里,ucenter向本机的Discuz服务器发出通讯验证请求(第3行日志),而第2行日志,就是Discuz服务器收到的通讯验证请求,499错误就是出如今此行。服务器

 

仔细查看这3条日志的时间,发现第23条与第1条间隔差很少29秒,咱们知道,PHP默认的超时时间为30秒,算上点偏差,29秒也差很少。所以能够认为这个499错误是由于ucenter服务器发起了ping请求(第3行日志),一直没有接收到返回值,结果超时断开链接,从而致使discuz服务器出现499错误。app

 

整个流程以下图:socket

image.png

知道是499错误,因而又查找如何解决499问题,结果大多数提出要在nginx服务器中添加以下配置:
ide

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的返回值,因此实际上仍是通讯失败。

 

不过再进一步分析上面的流程,从nginxphp的关系来看,发现整个请求处理以下图:

image.png

 

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进程:

image.png

 

再回到ucenter的应用管理页面,刷新,结果以下:

image.png

 

啥状况?咱们上面折腾了半天,只是从“正在链接”变成了“通讯失败”,问题仍是没有解决啊!

不过呢,跟踪代码能够验证,499的问题的确是完全解决了,至于为何仍是“通讯失败”,那是另一个问题了,请参见《Unable to find the socket transport "http"》。

相关文章
相关标签/搜索