用 ZooKeeper 当配置中心实测:50 个实例推送延迟中位 12.4 ms、p99 25.2 ms、1500 次零漏推;200 次连发被合并成 121–143 次回调;断开重连后只收到最新值;整份 JSON 改 1 项 5526 字节 vs 每项一个节点 173 字节。
配置热更新的版本控制实测:带 version 的写被 BadVersionError 拒绝;10 客户端累加不带 version 丢更新(35/200)、带 version 重试 200/200;ZooKeeper 无历史,回滚要自己存;multi 原子写但分两次读会读到半新半旧(500/1372)。
用 ZooKeeper 配置节点做灰度发布:200 个实例按哈希分桶放量(5/20/50/100% → 7/38/94/200 个),143 ms 内全部切换、单调包含;回滚 84 ms;白名单实例灰度;错误上报触发自动回滚 95 ms。
用 ZooKeeper 临时节点做服务发现:上线 80 ms 可见;kill -9 与 SIGTERM 都要 3.1–3.5 s 才被摘除(期间请求失败 9/20 次,重试可挽回);主动注销 18 ms;会话过期后提供者必须重新注册(监听器里不能直接 create)。
注册中心的 znode 布局实测:1000 服务 × 5 实例,分层读一个服务 69 字节 vs 平铺 85,024 字节;100 次无关变更分层消费者回调 0 次 vs 平铺 104 次;URL 不能直接当节点名;元信息放名字 1 个 watch、放数据 201 个。
用 ZooKeeper 做任务调度:5 个无 master 的 worker 抢 300 个任务零重复;执行中被 kill -9 的任务 3.6 s 后被接手(至少一次执行);3 个实例抢 25 个定时 tick,无漏无重复,kill 一个实例无空窗。
kazoo 2.11.0 实测:异常对照;同步 307 vs 异步流水线 9,986 个/s;回调线程共享,一个睡 2 秒拖延另一个 2020 ms;连不上抛 KazooTimeoutError;服务端短重启会话保留、长中断会话丢失并经历 SUSPENDED → LOST → CONNECTED。
Curator 5.7.1 在真实 ZooKeeper 3.9.6 上的实测:namespace 的真实路径前缀;同步 324 vs 后台 25,405 个/s;服务端冻结 5 s 与 12 s 时 ConnectionStateListener 的 SUSPENDED / LOST / RECONNECTED 序列、重试策略托住中断期间的调用、PersistentNode 自动重建。
Curator 5.7.1 的 InterProcessMutex 实测:10 线程累加 200/200;可重入靠本地计数、SemaphoreMutex 不可重入;acquire 超时后排队节点被清理;读写锁按排队顺序、写者不被饿死;JVM 冻结超过会话超时后别人拿到锁、解冻的持有者仍以为持有。
Curator 5.7.1 的 LeaderLatch 与 LeaderSelector 实测:close() 切换 6–11 ms;服务端冻结时 SUSPENDED 立刻放弃领导权、RECONNECTED 后重新当选;LeaderSelector 严格轮转;5 个 JVM 进程 kill -9 leader 空窗 2.6–3.5 s、无双 leader。
Curator 5.7.1 的 CuratorCache 实测:1000 个节点 98 ms 加载完成;读缓存 0.14 µs vs 直读 ZooKeeper 119 µs(约 826 倍);事件类型与延迟;200 次快速更新合并成 150 次事件;断网 6 s 期间缓存一直返回旧值、恢复后 0.1 s 追上。
Curator DistributedAtomicLong 实测:10 线程 1000 次 increment 最终值 1000;重试只允许 1 次时 672 次 succeeded()=false 且不抛异常(最终值 328);PromotedToLock 保证 1000/1000;吞吐随线程数从 238 降到 131 次/s;顺序节点发号 1142 个/s。