仅限特定连接的临时 Nginx 504 上游超时错误

仅限特定连接的临时 Nginx 504 上游超时错误

我在 nginx 错误日志中发现这个偶尔出现的错误(日志级别:错误):

2018/05/01 22:19:24 [error] 27520#27520: *753839613 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 77.85.205.153, server: *.mydomain.com, request: "GET / HTTP/1.1", upstream: "http://192.168.101.52:80/", host: "www2.mydomain.com" 2018/05/01 22:20:24 [error] 27520#27520: *753839613 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 77.85.205.153, server: *.mydomain.com, request: "GET / HTTP/1.1", upstream: "http://192.168.101.53:80/", host: "www2.mydomain.com" 2018/05/01 22:21:24 [error] 27520#27520: *753839613 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 77.85.205.153, server: *.mydomain.com, request: "GET / HTTP/1.1", upstream: "http://192.168.101.51:80/", host: "www2.mydomain.com"

Nginx 尝试上游块中定义的所有后端,超时时间为 60 秒。所有请求都失败,3 分钟后客户端收到 504 网关超时。奇怪的是:

  • 任何上游 IIS 服务器访问日志中均没有关于失败请求的条目(意味着该请求似乎从未到达后端服务器)
  • 上述错误是针对应用程序的 - 只是一个快速的初始页面(不慢也不重)
  • 该错误仅针对特定连接 - 同时成功处理了数百个对相同上游的请求。当它在我的浏览器中重现时,打开另一个浏览器可以正常工作,但无法从初始浏览器进行连接
  • 探测 wgethttp://192.168.101.51:80工作正常
  • 该错误也出现在离线时间,此时请求数量非常少
  • 在上游块中添加 keepalive 部分有帮助 - 添加后此类错误的数量非常少,但仍会出现。使用 16 或 128 为 keepalive 调整不同的值没有帮助。
  • 刚刚找到了一种重现此问题的方法 - 如果我发送几个缓慢的 POST 请求(由于服务器端处理缓慢而超时),之后问题就可以重现。问题在大约 5 分钟后消失。其他浏览器运行良好。这不是浏览器套接字问题,因为失败的 post 请求已经以 504 响应关闭。

    Virtualbox 机器上的 nginx/1.10.3 (Ubuntu),后端是 IIS。应用程序使用 signalR(无 websockets)。

配置

user www-data;
worker_processes auto; 
worker_rlimit_nofile 65535;
pid /var/run/nginx.pid;

events {
    worker_connections 65535; 
    use epoll; 
    multi_accept on;
}

http {

    sendfile off; 

    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_http_version 1.1; 
    proxy_set_header Connection '';

    proxy_next_upstream error timeout http_503; 

    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;


    proxy_buffer_size   256k; 
    proxy_buffers   16 256k;
    proxy_busy_buffers_size 256k;

    proxy_max_temp_file_size 20m;

    client_max_body_size 20m;
    client_body_buffer_size 20m;

    client_header_buffer_size 128k;
    large_client_header_buffers 4 128k;

    proxy_ignore_headers X-Accel-Expires;
    proxy_ignore_headers Expires;
    proxy_ignore_headers Cache-Control;

    # caching options
    proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=60m;
    proxy_temp_path /var/cache/nginx/tmp;
    proxy_cache_lock on;

    upstream backend_web { 
    hash $lb_key;
    server 192.168.101.51:80 max_fails=3 fail_timeout=10s weight=9;
    server 192.168.101.52:80 max_fails=3 fail_timeout=10s weight=9;
    server 192.168.101.53:80 max_fails=3 fail_timeout=10s weight=9 ;

    keepalive 128;

}

    error_log /var/log/nginx/mydomain.com_error.log error;

    server {

        proxy_cache_key $scheme|$proxy_host|$uri|$is_args|$args;                
        location / {    
            proxy_cache_bypass 1;
            proxy_no_cache 1;    
            proxy_pass http://backend_web;
        }

    }

}

答案1

正如 Tim 指出的那样,问题不在于 Nginx;使用网络工具Wireshark我能够看到请求已发送到 IIS,但 IIS 没有响应;因此 Nginx 的行为是正确的 - 似乎我的 ASP .net 应用程序没有打开与 mysql 服务器的第二个连接,而另一个连接仍处于待处理状态(对于同一会话),并且第二个请求挂起很长时间,直到第一个请求完成 - 但这与问题无关,我将在那里进一步研究。

相关内容