更多精彩内容,请关注微信公众号:后端技术小屋
〇、环境
zk client: github.com/samuel/go-zookeeper
一、zk client 状态
zookeeper 是一款流行的分布式协调组件,被广泛用于 leader 选举、分布式锁、服务发现、名称服务、配置中心等场景。
1. 状态含义
zk client 与 zk server 在建立连接、保持连接、断开连接的过程中,会经历各种状态。如下所示
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. 状态转换
二、超时时间
超时时间很大程度上影响了上述状态的转换,有三个超时时间值得关注:
- 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
}
三、异常处理
// 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 相关的状态,或者主动退出。
推荐阅读
- STL 源码分析--内存分配器
- STL 源码分析--vector
- STL 源码分析--string
- STL 源码分析--list
- STL 源码分析--hashtable
- STL 源码分析--deque
- STL 源码分析--iterator
- STL 源码分析--traits
- STL 源码分析--rbtree
- STL 源码分析--bitset
- STL 源码分析--algorithm
- STL 源码分析--functional
更多精彩内容,请扫码关注微信公众号:后端技术小屋。如果觉得文章对你有帮助的话,请多多分享、转发、在看。
