背景及簡要分析
前幾天一次故障定位的時候發現,后端服務(java)在從故障中恢復之后,會出現大量499,且會持續較長時間無法自行恢復。
根本原因是服務容量問題,處理太慢導致客戶端等不了了,主動斷開。不過分析一下直接原因大概有這幾點:
- nginx超時配置的比客戶端長,導致客戶端都499超時了,nginx還沒超時。
- nginx的重試機制和max_fails機制配置不當,在一定程度上加劇了后端的惡性循環。
在學習了解了nginx相關機制、參數的時候,和同事在 proxy_next_upstream 和 max_fails 這兩個參數之間產生了分歧。
- 從文檔的這兩句來看,我認為 max_fails 和 proxy_next_upstream 是強相關的,關閉了后者,前者會失效。
- 同事則認為,這兩者無關,即使關掉了重試也不會影響fails摘節點。
各執己見的情況下,自然就是上配置測試了。
nginx相關配置、參數
proxy_next_upstream
max_fails
proxy_connect_timeout
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds.
http://nginx.org/en/docs/http...
本次的大量499問題就是這個連接超時配置不當的鍋。
之前配置為3秒,也就是說如果一個上游服務有問題時,客戶端必須等3秒以上。這還只是建立連接的時間。
從日志中推測,客戶端的超時時間應該在3-6秒之間(應該是5s)【由於客戶端不是app所以和一般的客戶端超時不同】
nginx和服務如果都是內網的、同IDC,建立連接很快(ms級別),這個參數不必設置的太大。個人認為應該在500ms以下。當然,如果后端服務是外網的則另當別論了。
個人認為,服務端的超時時間應當是比客戶端短的,這樣在服務端某個節點有問題的時候,nginx還有時間去重試下一台。
proxy_[send/read]_timeout
測試過程
nginx版本: tengin 2.2.0
nginx參數: