首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

基於 ZooKeeper 臨時節點實現主備切換:核心代碼與原理圖解

     編輯:Java 綜合教學

基於 ZooKeeper 臨時節點實現主備切換:核心代碼與原理圖解

核心原理

利用 ZOO_EPHEMERAL 節點特性:會話斷開/過期 → 節點自動刪除。多節點搶佔同一路徑(如 /master/test),創建成功者成為 Master,其餘為 Standby。

完整實現流程

1. 初始化連接

bool init_zookeeper() {
    _zhandle = zookeeper_init(zk_hosts, zk_watcher, 5000, _clientid, this, 0);
    // 異步調用,返回非NULL不代表連接成功
    // 真正成功:watcher 中 type=ZOO_SESSION_EVENT, state=ZOO_CONNECTED_STATE
}

2. 主備切換主循環

bool run() {
    while (true) {
        millisleep(1000);  // 備機輪詢間隔,或改用 Watch 機制
        if (!is_master() && !change_to_master()) continue;
        do_work();         // 只有 Master 執行業務邏輯
    }
}

3. 搶佔 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;
}
  • 創建成功 → 成為 Master;
  • 節點已存在(ZNODEEXISTS)或連接斷開 → 繼續備機;
  • 可結合 ZOO_SEQUENCE 生成有序臨時節點,實現「最小序號當選」,避免驚群。

4. Watcher 回調處理

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 或進程重啟
}

日誌輸出建議

  • 默認輸出 stderr,生產用 zoo_set_log_stream() 接入統一日誌;
  • zoo_set_debug_level() 動態調整級別。

優化方向

  1. 輪詢 → Watch 機制:zoo_wexists() 監聽節點刪除事件,事件觸發時立即搶佔,降低延遲;
  2. 引入 ZOO_EPHEMERAL_SEQUENTIAL 實現公平選舉;
  3. Master 宕機檢測:心跳機制或會話超時時間(tickTime * 2)權衡。
  4. 適用場景

    • 單點寫入服務(如定時任務調度、配置推送、單消費者隊列);
    • 需強一致性、自動故障轉移、無中心協調的分布式系統。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved