當我們連接到一個失敗的后端時,通常希望不要立即重試(以避免泛濫的網絡或服務器的請求),而是做某種形式的指數backoff。
我們有幾個參數:
- INITIAL_BACKOFF (第一次失敗重試前后需等待多久)
- MULTIPLIER (在失敗的重試后乘以的倍數)
- JITTER (隨機抖動因子).
- MAX_BACKOFF (backoff上限)
- MIN_CONNECT_TIMEOUT (最短重試間隔)
建議backoff算法
以指數形式返回連接嘗試的起始時間,達到MAX_BACKOFF的極限,並帶有抖動。
1 |
ConnectWithBackoff() |
參數默認值MIN_CONNECT_TIMEOUT=20sec INITIAL_BACKOFF=1sec MULTIPLIER=1.6 MAX_BACKOFF=120sec JITTER=0.2
根據的確切的關注點實現(例如最小化手機的喚醒次數)可能希望使用不同的算法,特別是不同的抖動邏輯。
備用的實現必須確保連接退避在同一時間開始分散,並且不得比上述算法更頻繁地嘗試連接。
重置backoff
backoff應在某個時間點重置為INITIAL_BACKOFF,以便重新連接行為是一致的,不管連接的是新開始的還是先前斷開的連接。
當接收到SETTINGS幀時重置backoff,在那個時候,我們確定這個連接被服務器已經接受了。
grpc-go
源碼位於google.golang.org/grpc/backoff,代碼不多,直接在代碼上分析。
1 |
|
如果默認的backoff算法不滿足需求的時候,還可以自定義backoff算法,通過實現backoffStrategy接口。
1 |
func withBackoff(bs backoffStrategy) DialOption { |
