首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

MongoDB 源碼分析:連接池 ConnPool 實現詳解

     編輯:關於C語言

為什麼需要連接池

Balancer 等後台任務頻繁連接 Config Server/Shard。每次 new Connection 開銷大(TCP 握手、TLS、認證)。池化復用連接,顯著降低延遲。

核心類圖

ConnPool Class Diagram

  • ScopedDbConnection:RAII 包裝器,構造時從池取連接,析構/ done() 歸還。
  • DBConnectionPool:池管理器,按 ConnectionString 分組管理多個 PoolForHost。
  • PoolForHost:單機連接棧(vector<StoredConnection>),LIFO 取用,空閒超時 1 小時自動釋放。

獲取連接流程

// ScopedDbConnection 構造
ScopedDbConnection::ScopedDbConnection(const Shard& shard)
    : _host(shard.getConnString()), _conn(pool.get(_host)) {}

// DBConnectionPool::get()
DBClientBase* DBConnectionPool::get(const ConnectionString& url) {
    DBClientBase* c = _get(url.toString()); // 從池取
    if (c) { onHandedOut(c); return c; }    // 呼叫 hook

    string errmsg;
    c = url.connect(errmsg);                // 新建連接
    uassert(13328, "connect failed", c);
    return _finishCreate(url.toString(), c); // 加入池並返回
}

// _get() -> PoolForHost::get()
DBClientBase* PoolForHost::get() {
    time_t now = time(0);
    while (!_pool.empty()) {
        StoredConnection sc = _pool.back(); _pool.pop_back();
        if (sc.ok(now)) return sc.conn;     // 空閒 < 1hr
        delete sc.conn;                     // 過期銷毀
    }
    return nullptr;
}

歸還連接

void ScopedDbConnection::done() {
    if (_conn) pool.return(_host, _conn); // 歸還池
    _conn = nullptr;
}

// DBConnectionPool::return()
void DBConnectionPool::return(const string& ident, DBClientBase* conn) {
    scoped_lock L(_mutex);
    PoolForHost& p = _pools[ident];
    p.return(conn); // push 到 vector 尾部
}

Hook 機制:觀察者模式

Observer Pattern in ConnPool

  • onCreate():新連接建立後調用(如設置 socket 選項)。
  • onHandedOut():從池取出時調用(如重置事務狀態)。
  • 通過 ConnectionHook 介面註冊,支援多 Hook 鏈式調用。

關鍵設計亮點

  1. RAII:ScopedDbConnection 確保異常安全歸還。
  2. 按宿主機分池:不同 Shard/Config Server 獨立池,避免連接錯亂。
  3. LIFO + 超時清理:熱連接優先復用,冷連接自動釋放,平衡復用率與資源佔用。
  4. Hook 擴展點:業務邏輯(如認證刷新、監控埋點)與池核心解耦。

使用示例

// Balancer 中
ScopedDbConnection conn(config); // 從池取
conn->runCommand("config", cmd); // 使用
conn.done(); // 歸還(析構也會自動歸還)

總結

MongoDB ConnPool 以 ScopedDbConnection + DBConnectionPool + PoolForHost 三層架構,結合 RAII、觀察者 Hook、LIFO 超時策略,實現了高性能、線程安全、易擴展的連接管理——值得在自研 RPC 框架中借鑑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved