当上游服务器再次被代理时,Nginx 健康检查会工作吗?

Will Nginx health check work when upstream servers are again being proxied?

我有以下 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

解决了问题。 健康检查并没有像我预期的那样发生,因为在我的案例中,应用程序进程返回 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 conf

# 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;
  }

}