首页 > 解决方案 > 当上游服务器再次被代理时,Nginx 健康检查会起作用吗?

问题描述

我有以下 Nginx 设置:


# nginx load balancer
upstream web_app {
    server localhost:7021; # nginx1
    server localhost:7031; # nginx2
}

server {
  listen 7777 ssl;
  server_name localhost 0.0.0.0;;

  client_max_body_size 25m;
  gzip on;
  gzip_vary on;
  gzip_min_length 10240;
  gzip_proxied expired no-cache no-store private auth;
  gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/javascript application/xml;
  gzip_disable "MSIE [1-6]\.";

 location / {
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_set_header   Host             $http_host;

    proxy_pass https://web_app;
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    proxy_connect_timeout 600s;
    send_timeout 600s;
  }

}



# nginx1
server {
  listen 7021 ssl;
  server_name localhost 0.0.0.0;


  client_max_body_size 25m;
  gzip on;
  gzip_vary on;
  gzip_min_length 10240;
  gzip_proxied expired no-cache no-store private auth;
  gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/javascript application/xml;
  gzip_disable "MSIE [1-6]\.";

  location / {
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_set_header   Host             $host;

    proxy_pass http://localhost:7001; # process1
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    proxy_connect_timeout 600s;
    send_timeout 600s;
  }
}


# nginx2
server {
  listen 7031 ssl;
  server_name localhost 0.0.0.0;


  client_max_body_size 25m;
  gzip on;
  gzip_vary on;
  gzip_min_length 10240;
  gzip_proxied expired no-cache no-store private auth;
  gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/javascript application/xml;
  gzip_disable "MSIE [1-6]\.";

  location / {
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_set_header   Host             $http_host;

    proxy_pass http://localhost:7011; # process2
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    proxy_connect_timeout 600s;
    send_timeout 600s;
  }
}

负载均衡器有一个上游组,它也是 Nginx 进程每个 Nginx 进程代理到一个应用程序进程

                   Nginx Load Balancer
                           /     \
                          /       \
                       Nginx1   Nginx2
                         |         |
                       Process1   Process2

这里的问题是,即使其中一个进程没有运行,负载均衡器也会向上游服务器发送请求,从而导致问题。我认为这种情况正在发生,因为 Nginx 运行状况检查仅对直接上游服务器而不是任何代理执行检查。

即如果 process2 停止,负载均衡器只检查 localhost:7031 的 Nginx 进程的健康状况,而不检查来自 localhost:7031 的任何代理

我希望在应用程序进程级别进行健康检查,即@ localhost:7001 和 localhost:7011

标签: nginxnginx-reverse-proxynginx-config

解决方案


想通了这个问题。健康检查没有像我预期的那样发生,因为在我的情况下应用程序进程返回 502。

我必须设置proxy_next_upstream error timeout http_502 来处理 502

https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream

最终的 Nginx LB 配置

# nginx load balancer
upstream web_app {
    server localhost:7021; # nginx1
    server localhost:7031; # nginx2
}

server {
  listen 7777 ssl;
  server_name localhost 0.0.0.0;;

  client_max_body_size 25m;
  gzip on;
  gzip_vary on;
  gzip_min_length 10240;
  gzip_proxied expired no-cache no-store private auth;
  gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/javascript application/xml;
  gzip_disable "MSIE [1-6]\.";

 location / {
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_set_header   Host             $http_host;

    proxy_pass https://web_app;
    proxy_next_upstream error timeout http_502;
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    proxy_connect_timeout 600s;
    send_timeout 600s;
  }

}

推荐阅读