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"
排错要点与常见现象#
- 临时节点频繁消失
- 检查 SessionTimeout 是否过短
- 检查客户端重连策略和网络稳定性
- 关注日志:Session expired、CloseSession - 大量 Disconnected 状态
- 检查 DNS/负载均衡、跨机房链路
- 查看 4lwstat中 queued 和 latency - 误判过期
- 检查服务器磁盘与网络延迟
- 评估tickTime与maxSessionTimeout配置
ZooKeeper 服务器日志路径示例:/opt/zookeeper/logs/zookeeper.out
关键日志关键字:Session expired, CloseSession, got session。
小练习#
- 调整客户端 SessionTimeout(例如 10s/30s),重复断连测试,观察临时节点回收速度差异。
- 通过
tc或iptables模拟网络抖动,观察Disconnected → Connected是否发生。 - 使用
echo stat | nc对比断连前后会话数变化。