如何解决nginx - no live upstreams while connecting to upstream client?

32

目前我正在使用JMeter对我们基于Grails 3构建的运行在Tomcat上的系统进行负载测试。在每秒发送20k请求后,我的nginx错误日志中出现了“连接到上游客户端时没有活动的上游”错误。由于我们的应用程序是多租户基础,所以我需要执行高负载测试。以下是我的nginx配置。

worker_processes  16;
worker_rlimit_nofile 262144;
error_log  /var/log/nginx/error.log;

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


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  600;
    keepalive_requests 100000;
    access_log off;
    server_names_hash_max_size  4096;
    underscores_in_headers  on;
    client_max_body_size 8192m;
    log_format vhost '$remote_addr - $remote_user [$time_local] $status "$request" $body_bytes_sent "$http_referer" "$http_user_agent" "http_x_forwarded_for"';

    proxy_connect_timeout      120;
    proxy_send_timeout         120;
    proxy_read_timeout         120;


    gzip  on;
    gzip_types text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss image application/javascript;
    gzip_min_length  1000;
    gzip_static on;
    gzip_vary on;
    gzip_buffers 16 8k;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_disable "msie6";

    proxy_intercept_errors on;
    recursive_error_pages on;

    ssl_prefer_server_ciphers On;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA;
    include /etc/nginx/conf.d/*.conf;
}

如何配置以处理高并发负载?

2个回答

36

对我来说,问题出在我的proxy_pass条目上。我有

location / {
        ...
        proxy_pass    http://localhost:5001;
    }

这导致上游请求使用IP4本地主机IP或IP6本地主机IP,但偶尔会使用没有端口号的本地主机DNS,从而导致上游错误,如下面的日志所示。

[27/Sep/2018:16:23:37 +0100] <request IP> - - - <requested URI>  to: [::1]:5001: GET /api/hc response_status 200
[27/Sep/2018:16:24:37 +0100] <request IP> - - - <requested URI>  to: 127.0.0.1:5001: GET /api/hc response_status 200
[27/Sep/2018:16:25:38 +0100] <request IP> - - - <requested URI>  to: localhost: GET /api/hc response_status 502
[27/Sep/2018:16:26:37 +0100] <request IP> - - - <requested URI>  to: 127.0.0.1:5001: GET /api/hc response_status 200
[27/Sep/2018:16:27:37 +0100] <request IP> - - - <requested URI>  to: [::1]:5001: GET /api/hc response_status 200

正如您所看到的,在“localhost:”上我得到了502状态。

将我的proxy_pass更改为127.0.0.1:5001意味着现在所有请求都使用IP4和端口。

这个StackOverflow的回答对于发现问题非常有帮助,因为它详细说明了更改日志格式以便能够看到问题。


1
听起来像是DNS故障,但解决方法的信息很棒,另请参阅https://dev59.com/Emcs5IYBdhLWcg3wSiFo#58924751。 - rogerdpack

21

我在性能测试期间多次看到这种行为。

在高负载下,您的上游服务器的性能可能不足,并且上游模块可能会将上游服务器标记为不可用。

相关参数(server指令)为:

max_fails=number

设置在由fail_timeout参数设置的时间内与服务器通信失败次数,以考虑服务器不可用的持续时间。默认情况下,不成功尝试的次数设置为1。零值禁用了尝试的计数。什么被认为是不成功的尝试是由proxy_next_upstream指令定义的。

fail_timeout=time

集合:

  • 在考虑服务器不可用之前,应发生指定次数的未成功尝试与服务器进行通信的时间;

  • 以及服务器被视为不可用的时间段。

默认情况下,该参数设置为10秒。


我更加深入地诊断了系统,发现MySQL无法打开文件,因为open_file_limit的限制。然后我暂时增加了这个限制,问题得到了解决。但是不要认为这就是问题的根本原因。 - Torikul Alam
4
你很有趣 - 在你的帖子中哪里提到了MySQL?但无论如何,这是后端问题,并且上游被nginx列入黑名单。 - Alexander Altshuler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接