利用 ZOO_EPHEMERAL 節點特性:會話斷開/過期 → 節點自動刪除。多節點搶佔同一路徑(如 /master/test),創建成功者成為 Master,其餘為 Standby。
bool init_zookeeper() {
_zhandle = zookeeper_init(zk_hosts, zk_watcher, 5000, _clientid, this, 0);
// 異步調用,返回非NULL不代表連接成功
// 真正成功:watcher 中 type=ZOO_SESSION_EVENT, state=ZOO_CONNECTED_STATE
}
bool run() {
while (true) {
millisleep(1000); // 備機輪詢間隔,或改用 Watch 機制
if (!is_master() && !change_to_master()) continue;
do_work(); // 只有 Master 執行業務邏輯
}
}
bool change_to_master() {
int rc = zoo_create(_zhandle, _zk_path, _myip, _myip.size()+1,
&ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, NULL, 0);
if (rc != ZOK) { _is_master=false; return false; }
_is_master=true;
millisleep(2000); // 緩衝,讓舊 Master 完成收尾
return true;
}
ZOO_SEQUENCE 生成有序臨時節點,實現「最小序號當選」,避免驚群。void zk_watcher(zh, type, state, path, ctx) {
X* x = (X*)ctx;
if (type==ZOO_SESSION_EVENT && state==ZOO_CONNECTED_STATE)
x->on_zookeeper_connected(path); // 重新搶佔
else if (type==ZOO_SESSION_EVENT && state==ZOO_EXPIRED_SESSION_STATE)
x->on_zookeeper_expired(); // 會話過期,需重新 init 或進程重啟
}
zoo_set_log_stream() 接入統一日誌;zoo_set_debug_level() 動態調整級別。zoo_wexists() 監聽節點刪除事件,事件觸發時立即搶佔,降低延遲;ZOO_EPHEMERAL_SEQUENTIAL 實現公平選舉;tickTime * 2)權衡。