11.4.2 SessionTimeout与心跳机制
SessionTimeout与心跳机制#
ZooKeeper 会话由客户端与服务端共同维护,sessionTimeout 决定服务端在多长时间未收到心跳后判定会话失效。会话过期会删除临时节点并触发 Expired 事件。下图展示会话续租与过期流程:
sequenceDiagram
participant C as Client
participant S as ZooKeeper Server
C->>S: connect(sessionTimeout)
S-->>C: sessionId/sessionPasswd
loop 心跳(约 sessionTimeout/3)
C->>S: ping
S-->>C: pong(续租)
end
Note over C,S: 心跳中断 > sessionTimeout
S-->>C: Expired(会话过期)
关键参数与行为要点:
- 客户端提出 sessionTimeout,服务端根据 minSessionTimeout 与 maxSessionTimeout 校正。
- 会话过期由服务端判定,客户端断线后在超时前可重连继续使用旧会话。
- 超时过短会导致频繁过期;过长会延迟故障检测。
配置示例(含安装与参数说明):
1) 安装与准备(单机示例)
# 以 CentOS/RHEL 为例
sudo yum install -y java-1.8.0-openjdk
# 下载并解压 ZooKeeper
cd /opt
sudo curl -LO https://archive.apache.org/dist/zookeeper/zookeeper-3.8.3/apache-zookeeper-3.8.3-bin.tar.gz
sudo tar -xzf apache-zookeeper-3.8.3-bin.tar.gz
sudo mv apache-zookeeper-3.8.3-bin zookeeper
# 创建数据目录
sudo mkdir -p /data/zookeeper
2) zoo.cfg 参数配置
/opt/zookeeper/conf/zoo.cfg
tickTime=2000
dataDir=/data/zookeeper
clientPort=2181
minSessionTimeout=4000
maxSessionTimeout=40000
tickTime:基础心跳单位(ms)minSessionTimeout:最小会话超时(ms),通常为2*tickTimemaxSessionTimeout:最大会话超时(ms),通常为20*tickTime
3) 启动与验证
/opt/zookeeper/bin/zkServer.sh start
/opt/zookeeper/bin/zkServer.sh status
命令示例:查看会话信息与心跳影响
1) 使用 zkCli.sh 创建临时节点,并观察超时删除
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
# 会话内创建临时节点
create -e /svc/ephemeral "node1"
get /svc/ephemeral
2) 断开客户端并等待 sessionTimeout 后确认节点删除
# 退出客户端,等待超过 maxSessionTimeout
quit
sleep 45
# 重新连接查看节点是否删除
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
get /svc/ephemeral
预期结果:Node does not exist(临时节点随会话过期删除)
故障排查与调优示例
1) 客户端频繁 Expired
# 查看服务端日志
tail -f /opt/zookeeper/logs/zookeeper.out
排查方向:
- 检查网络抖动、丢包、延迟。
- 调整 JVM GC:避免长时间 STW(尤其是 Java 客户端)。
- 适当增大 sessionTimeout 与 tickTime。
2) 查看连接与会话
# 四字命令(需在 zoo.cfg 启用 4lw)
echo stat | nc 127.0.0.1 2181
练习
1) 将 tickTime 设置为 1000ms,并设置 minSessionTimeout=2000、maxSessionTimeout=20000,观察临时节点失效时间。
2) 使用两个客户端同时连接,分别创建临时节点,关闭其中一个客户端,验证只删除对应临时节点。
3) 通过人为制造网络延迟(如 tc qdisc)让心跳延迟,记录会话过期触发时间并与 sessionTimeout 对比。