V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
codeboy18
V2EX  ›  ZooKeeper

Zookeeper Go Client 原理总结

  •  
  •   codeboy18 · 2021-02-24 19:55:12 +08:00 · 1000 次点击
    这是一个创建于 1127 天前的主题,其中的信息可能已经有所发展或是发生改变。

    更多精彩内容,请关注微信公众号:后端技术小屋

    〇、环境

    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 相关的状态,或者主动退出。

    推荐阅读

    更多精彩内容,请扫码关注微信公众号:后端技术小屋。如果觉得文章对你有帮助的话,请多多分享、转发、在看。
    二维码

    1 条回复    2021-02-24 19:57:09 +08:00
    AngryPanda
        1
    AngryPanda  
       2021-02-24 19:57:09 +08:00   ❤️ 1
    不错,终于看到了二维码
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4906 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 09:51 · PVG 17:51 · LAX 02:51 · JFK 05:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.