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

アップストリームに2つ以上のサーバーがある場合にのみ、nginxは次のアップストリームを試みると思います。

ただし、アップストリームにサーバーが 1 つある場合でも、2 回以上試行します。

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 に設定しました。しかし、2 回以上リトライします。(アクセス ログ : {502, 502, 502, 502} -> アップストリームが次のサーバーへのプロキシを 4 回試行することを意味します)

それについて質問があります。

  1. アップストリームのTomcatが次のサーバーを通過するために再試行しないようにします。出来ますか?
  2. アップストリームにサーバーが 1 つあるのに再試行するのはなぜですか?
  3. 2回以上再試行するのはなぜですか?
  4. アップストリームが 502 を返すと、一時的に接続できないのはなぜですか? (発生時、サーバーの状態は正常でした)

私の質問の 1 つに対する答えを知っている場合は、お知らせください。

ありがとうございました。

4

0 に答える 0