zookeeper go客戶端原理總結

〇、環境

zk client: github.com/samuel/go-zookeepernode

1、zk client狀態

zookeeper是一款流行的分佈式協調組件,被普遍用於leader選舉、分佈式鎖、服務發現、名稱服務、配置中心等場景。git

1. 狀態含義

zk client與zk server在創建鏈接、保持鏈接、斷開鏈接的過程當中,會經歷各類狀態。以下所示github

const (
    // 暫未使用
    StateUnknown           State = -1
    // 與zk server之間的鏈接斷開(也包含初始狀態),此時zk client會不斷重連
    StateDisconnected      State = 0
    // 與zk server創建鏈接以前的暫時狀態,表示即將connect zk server
    StateConnecting        State = 1
    // 暫未使用
    StateAuthFailed        State = 4
    // 暫未使用
    StateConnectedReadOnly State = 5
    // 暫未使用
    StateSaslAuthenticated State = 6
    // 在和zk server從新創建TCP鏈接以後,握手階段發現session超時
    StateExpired           State = -112
    // 在和zk server成功創建TCP鏈接以後的狀態
    StateConnected  = State(100)
    // 和zk server成功創建TCP鏈接,而且成功握手(即成功建立session)
    StateHasSession = State(101)
)

2. 狀態轉換

2、超時時間

超時時間很大程度上影響了上述狀態的轉換,有三個超時時間值得關注:後端

  • sessionTimeout: session超時。當client與某個zk server鏈接異常時,會重連鏈接其餘zk server。只要在sessionTimeout以內成功創建TCP鏈接並握手成功,臨時節點、watcher都會做爲已有session的資源獲得保留。特別要注意的是,sessionTimeout並不是徹底由client端設置,它由client和server端協商肯定:它必須介於server端配置的sessionTimeout上限和下限之間。
  • pingInterval: 是zk client和server保持心跳的時間間隔,默認1/3 * sessionTimeout
  • recvTimeout:默認2/3 * sessionTimeout。client端發送請求和接收響應(包含心跳)的超時時間。另外client握手階段的讀寫超時爲10 * recvTimeout。
  • connectTimeout: client端與zk server創建TCP鏈接的超時
func (c *Conn) setTimeouts(sessionTimeoutMs int32) {
    c.sessionTimeoutMs = sessionTimeoutMs
    sessionTimeout := time.Duration(sessionTimeoutMs) * time.Millisecond
    c.recvTimeout = sessionTimeout * 2 / 3
    c.pingInterval = c.recvTimeout / 2
}

3、異常處理

// Connect establishes a new connection to a pool of zookeeper
// servers. The provided session timeout sets the amount of time for which
// a session is considered valid after losing connection to a server. Within
// the session timeout it's possible to reestablish a connection to a different
// server and keep the same session. This is means any ephemeral nodes and
// watches are maintained

若是client和server端鏈接發生異常,可分爲三種狀況:微信

  • 一直沒法成功創建鏈接。此時zk client在connect()中死循環,此時zk服務處於不可用狀態。用戶可根據業務的具體狀況,讓應用或退出,或降級,或死循環直到zk服務恢復。
  • sessionTimeout內成功創建鏈接。臨時節點和watcher得以保留,不作任何處理
  • sessionTimeout內沒有成功創建鏈接,可是後來成功了。此時應用應當重置內部與zk相關的狀態,或者主動退出。

推薦閱讀session

更多精彩內容,請掃碼關注微信公衆號:後端技術小屋。若是以爲文章對你有幫助的話,請多多分享、轉發、在看。
二維碼分佈式

相關文章
相關標籤/搜索