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

done() 歸還。ConnectionString 分組管理多個 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 尾部
}

onCreate():新連接建立後調用(如設置 socket 選項)。onHandedOut():從池取出時調用(如重置事務狀態)。ConnectionHook 介面註冊,支援多 Hook 鏈式調用。ScopedDbConnection 確保異常安全歸還。// Balancer 中
ScopedDbConnection conn(config); // 從池取
conn->runCommand("config", cmd); // 使用
conn.done(); // 歸還(析構也會自動歸還)
MongoDB ConnPool 以 ScopedDbConnection + DBConnectionPool + PoolForHost 三層架構,結合 RAII、觀察者 Hook、LIFO 超時策略,實現了高性能、線程安全、易擴展的連接管理——值得在自研 RPC 框架中借鑑。