11.4.1 会话生命周期与状态转移

ZooKeeper 会话用于标识客户端与集群之间的逻辑连接,是临时节点、watch 触发与授权上下文的基础。会话生命周期以服务端为主导,客户端通过心跳维持连接,服务端依据超时与连接状态决定会话是否有效。理解会话状态转移对于排查临时节点丢失、服务漂移和连接抖动至关重要。

以下为会话生命周期与状态转移的原理草图(简化):

文章图片

关键阶段说明:
- 创建:客户端完成握手并获得 sessionId。
- 存续:客户端发送心跳或业务请求刷新 lastSeen。
- 失效:超时未收到任何活动,被判定过期。
- 清理:临时节点删除、watch 触发。

示例:观察会话与临时节点的绑定关系#

前置:已安装 ZooKeeper,并启动服务。客户端使用 zkCli.sh
目录示例:/opt/zookeeper/bin/zkCli.sh

# 1) 连接 ZooKeeper
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181

# 2) 创建临时节点
create -e /demo/ephemeral "hello"

# 3) 查看节点
ls /demo
get /demo/ephemeral

# 4) 关闭会话(模拟客户端主动关闭)
close

# 5) 重新连接并观察临时节点是否被删除
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
ls /demo

预期效果:/demo/ephemeral 在会话关闭后被删除。

示例:会话过期触发清理(模拟断连)#

使用两次连接模拟超时(SessionTimeout 默认 30000ms 或 40000ms,具体取决于客户端)。

# 终端A:建立会话并创建临时节点
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
create -e /demo/exp "tmp"

# 终端B:查看节点存在
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
ls /demo

# 终端A:强制断开(直接退出终端或断网)
# 等待超过 SessionTimeout

# 终端B:再次查看
ls /demo

预期效果:/demo/exp 被自动删除。

关键命令与参数解释#

# 查看当前连接状态和会话信息(stat 命令来自 4lw)
echo stat | nc 127.0.0.1 2181

# 输出中关注:
# - Client: /127.0.0.1:xxxxx[1](queued=0,recved=...,sent=...,sessionid=0x...)
# - Session timeout: 30000
# - Sessions: xx
# 查看会话与临时节点数(mntr)
echo mntr | nc 127.0.0.1 2181 | egrep "zk_num_ephemerals|zk_open_file_descriptor_count|zk_avg_latency"

排错要点与常见现象#

  1. 临时节点频繁消失
    - 检查 SessionTimeout 是否过短
    - 检查客户端重连策略和网络稳定性
    - 关注日志:Session expiredCloseSession
  2. 大量 Disconnected 状态
    - 检查 DNS/负载均衡、跨机房链路
    - 查看 4lw stat 中 queued 和 latency
  3. 误判过期
    - 检查服务器磁盘与网络延迟
    - 评估 tickTimemaxSessionTimeout 配置

ZooKeeper 服务器日志路径示例:/opt/zookeeper/logs/zookeeper.out
关键日志关键字:Session expired, CloseSession, got session

小练习#

  1. 调整客户端 SessionTimeout(例如 10s/30s),重复断连测试,观察临时节点回收速度差异。
  2. 通过 tciptables 模拟网络抖动,观察 Disconnected → Connected 是否发生。
  3. 使用 echo stat | nc 对比断连前后会话数变化。