這里只討論作反向代理時,當上游服務發生如介面超時、回傳指定狀態碼等狀況時而導致nginx超時重試,
這里使用的nginx版本為1.16.1,可通過nginx -V查看版本,
超時重試主要通過配置ngx_http_upstream_module和ngx_http_proxy_module模塊中欄位實作的,
這兩個模塊的官方檔案:
- https://nginx.org/en/docs/http/ngx_http_proxy_module.html
- https://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
準備的作業:
- 準備一個后臺服務,向外暴露訪問地址,服務收到請求后,處理的時間為5s(當然你可以設定為其它大小),隨后回傳結果,這是用來模擬nginx訪問上游服務介面時超時場景,
- 運行兩個這樣相同的后臺服務實體,對外暴露的埠分別為9090和9091,用來模擬nginx作負載均衡的場景,
- nginx配置一個server,暴露埠9000,用于接收請求,并把請求分發到9090和9091的兩臺實體上,
具體配置:
upstream RETRY_TEST_SERVER {
server 127.0.0.1:9090;
server 127.0.0.1:9091;
}
server {
listen 9000;
server_name localhost;
location / {
proxy_pass http://RETRY_TEST_SERVER;
proxy_next_upstream timeout;
proxy_read_timeout 3;
}
}
配置欄位解釋:
-
proxy_pass
即分發到哪個upstream上
-
proxy_next_upstream
用來配置哪些情景下會重試,當nginx收到請求,并把請求轉發到
RETRY_TEST_SERVER,upstream默認的負載均衡策略為輪詢,第一次請求轉到9090埠,若9090服務實體回應超時,那么將會將請求轉到9091,這個“回應超時”,就是這個欄位配置的觸發場景,可配置的欄位有:- timeout
- error
- http_500
默認的配置為
proxy_next_upstream error timeout;所有的配置串列及含義:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream
-
proxy_read_timeout
配置從上游服務讀取的超時時間,
官方解釋為:
Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed.
運行
由于設定了proxy_read_timeout為3秒,實體的回應時間為5秒,所以當訪問地址curl localhost:9000/test/delay(這是實體的介面測驗地址)時:
- 請求路由到9090埠,9090接收到請求,3秒后請求超時
- 由于配置了
proxy_next_upstream timeout,即在發生超時時,會路由到下一節點,這時請求會路由到9091 - 3秒過后請求再次超時,nginx回傳給客戶端錯誤資訊:Gateway Timeout;
注意
-
由于作測驗用,為方便會將多個相同的實體部署到本機通過埠作負載均衡測驗,如:
upstream RETRY_TEST_SERVER { server 127.0.0.1:9090; server 127.0.0.1:9091; }我在測驗時,server 后的
127.0.0.1一開始是寫成localhost,測驗9090發生超時時,沒有路由到9091,而是又在9090執行了一次,改成127.0.0.1后正常, -
upstream 的 server 模塊后還可以添加其它屬性欄位:
upstream RETRY_TEST_SERVER { server 127.0.0.1:9090 max_fails=2 fail_timeout=10s; server 127.0.0.1:9091 max_fails=2 fail_timeout=10s; }官方檔案:https://nginx.org/en/docs/http/ngx_http_upstream_module.html#server
-
max_fails和fail_timeoutmax_fails和fail_timeout須結合使用,意為“在多長時間內訪問server多少次不可用”時,標記這個server節點不可用,若不可用則在此周期內當該server收到請求后直接回傳錯誤,即nginx會直接回傳給客戶端 "Bad Gateway",等到下一個 "fail_timeout"周期,才會再次嘗試該server是否可用,(至于"如何判斷是否可用",則根據欄位proxy_next_upstream的配置,)這一點相當重要,如實體有兩個請求地址,一個耗時較長
/test/slow,一個耗時較短/test/fast;當介面/test/slow超時時,指定時間(fail_timeout)超過最大嘗試次數(max_fails)時,此時9090標記為不可用,此時請求/tset/fast路由到9090上時,nginx 會直接回傳錯誤(Bad Gateway),即超時介面影響了正常介面的呼叫,我建議有兩種方式:
-
提高檢測是否可用的頻率
即使 fail_timeout/max_fails變大,如
max_fails=5 fail_timeout=10要比max_fails=2 fail_timeout=10可靠 -
為耗時長的介面單獨配置upstream和server(推薦)
-
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/499753.html
標籤:其他
