1

nginx 的 proxy_next_upstream 工作很奇怪。

当上游到其他国家/地区的代理无法返回请求时,我想传递到下一个服务器。所以我像这样设置上游(代理到其他国家)。

upstream proxy-to-other-country {
    server de1-test.com max_fails=0;
    server de1-test.com:81 max_fails=0 backup;  # for proxy_next_upstream
    keepalive 60;
    keepalive_requests 1000;
    keepalive_timeout 300s;
}

它运作良好。但是连接tomcat的上游也会在失败时重试。

上游tomcat配置

upstream tomcat {
    server 127.0.0.1:8080 max_fails=0;
    keepalive 30;
}

我认为只有当上游有两个以上的服务器时,nginx 才会尝试下一个上游。

但即使上游有一台服务器,它也会尝试两次以上。

我使用 nginx、tomcat 和 java spring。

有我的nginx的配置、访问日志和错误日志。

代理配置

proxy_pass_header Server;
proxy_set_header Host $http_host;
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 $x_forward_protocol_scheme;
proxy_http_version 1.1;
proxy_set_header Connection "";
 
proxy_buffering off;  #default on
proxy_request_buffering off;  #default on
proxy_buffer_size 32k;  #default 4k|8k
proxy_buffers 20 32k;  #default 8 4k|8k
proxy_busy_buffers_size 64k; # default 8k|16k
proxy_temp_file_write_size 64k; # default 8k|16k;
proxy_connect_timeout 75s;  #default 60s
proxy_read_timeout 1800s;  #default 60s
proxy_send_timeout 1800s;  #default 60s

proxy_next_upstream error timeout invalid_header non_idempotent http_502 http_504;
proxy_next_upstream_tries 2;

日志格式

[$time_local] "$request" [$status] $body_bytes_sent $request_time "$http_referer" "$http_user_agent" $upstream_addr $upstream_connect_time $upstream_header_time $upstream_response_time $upstream_bytes_sent $upstream_bytes_received {$upstream_status}

访问日志

[31/Jul/2020:10:14:32 +0900] "GET /sections/a?lc=ko&ts=20200730144337&lm=1595927500 HTTP/1.1" [502] 552 0.510 "https://test.com/main" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763" 127.0.0.1:8080, 127.0.0.1:8080 0.000, - -, - 0.509, 0.000 3494, 0 0, 0 {502, 502}
[31/Jul/2020:10:14:32 +0900] "POST /ajax/a?ts=1596158072677&rl=14101 HTTP/1.1" [502] 552 0.135 "https://test.com/main" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Whale/2.7.98.24 Safari/537.36" 127.0.0.1:8080, 127.0.0.1:8080, 127.0.0.1:8080, 127.0.0.1:8080 0.000, 0.000, 0.000, - -, -, -, - 0.126, 0.000, 0.001, 0.005 4840, 4840, 4840, 0 0, 0, 0, 0 {502, 502, 502, 502}

错误日志

2020/07/31 10:14:32 [error] 111509#0: *108712 upstream prematurely closed connection while reading response header from upstream, client: xx.xx.xx.xxx, server: test.com, request: "POST /ajax/a?ts=1596158072677&rl=14101 HTTP/1.1", upstream: "http://127.0.0.1:8080/ajax/a?ts=1596158072677&rl=14101", host: "test.com", referrer: "https://test.com/main"
2020/07/31 10:14:32 [error] 111509#0: *108712 upstream prematurely closed connection while reading response header from upstream, client: xx.xx.xx.xxx, server: test.com, request: "POST /ajax/a?ts=1596158072677&rl=14101 HTTP/1.1", upstream: "http://127.0.0.1:8080/ajax/a?ts=1596158072677&rl=14101", host: "test.com", referrer: "https://test.com/main"
2020/07/31 10:14:32 [error] 111511#0: *108612 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: yy.yy.yy.yyy, server: test.com, request: "GET /sections/a?lc=ko&ts=20200730144337&lm=1595927500 HTTP/1.1", upstream: "http://127.0.0.1:8080/sections/a?lc=ko&ts=20200730144337&lm=1595927500", host: "test.com", referrer: "https://test.com/main"
2020/07/31 10:14:32 [error] 111511#0: *108612 connect() failed (111: Connection refused) while connecting to upstream, client: yy.yy.yy.yyy, server: test.com, request: "GET /sections/a?lc=ko&ts=20200730144337&lm=1595927500 HTTP/1.1", upstream: "http://127.0.0.1:8080/sections/a?lc=ko&ts=20200730144337&lm=1595927500", host: "test.com", referrer: "https://test.com/main"
2020/07/31 10:14:32 [error] 111509#0: *108712 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xxx, server: test.com, request: "POST /ajax/a?ts=1596158072677&rl=14101 HTTP/1.1", upstream: "http://127.0.0.1:8080/ajax/a?ts=1596158072677&rl=14101", host: "test.com", referrer: "https://test.com/main"

如您所见,我将 proxy_next_upstream_tries 设置为 2。但它重试了两次以上。(访问日志:{502、502、502、502} -> 这意味着上游尝试第四次代理到下一个服务器)

我对此有疑问。

  1. 我希望上游 tomcat 不会重试通过下一个服务器。可能吗?
  2. 为什么上游只有一台服务器时会重试?
  3. 为什么它重试两次以上?
  4. 当upstream返回502时,为什么暂时无法连接?(发生时,服务器状态正常)

如果您知道我的问题之一的答案,请告诉我。

谢谢你。

4

0 回答 0