cpp-httplib默认不启用有效Keep-Alive连接池,需在#include 前定义CPPHTTPLIB_KEEPALIVE_MAX_COUNT、CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND等宏,且Client实例须复用、避免频繁构造析构,HTTPS还需启用TLS会话复用。

cpp-httplib 的 Keep-Alive 连接池默认行为很弱
默认编译下,cpp-httplib 的连接复用能力几乎等于没有:它只对单个 Client 实例内连续请求做简单复用,不跨实例、不保活、不清理失效连接。你发 100 个请求,大概率建立 100 次 TCP 连接——尤其在多线程场景下,每个线程 new 一个 httplib::Client,就等于放弃所有复用可能。
必须手动覆盖宏定义才能启用有效 Keep-Alive
关键不是调用某个函数,而是编译前改宏。否则所有运行时配置都白搭:
-
#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 200:控制每个 host:port 组合最多缓存多少空闲连接,低于 50 在高并发下很快耗尽 -
#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 30:连接空闲超时,设太短(如 5s)会导致刚建好就被关;设太长(>60s)则占用 fd 不释放 -
#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 10:建连超时,建议 ≤ 后端平均 RTT × 3,避免阻塞线程池
这些宏必须在 #include <httplib.h></httplib.h> 之前定义,且需全局生效(比如放在 config.h 头最顶行)。漏掉任一,cpp-httplib 就退化为短连接模式。
连接池实际复用依赖 Client 实例生命周期
cpp-httplib 的连接池是绑定在 Client 对象上的,不是进程级单例。这意味着:
立即学习“C++免费学习笔记(深入)”;
- 每次
new httplib::Client("api.example.com", 443)都创建独立连接池,彼此不共享 - 推荐用静态或单例方式持有
Client实例(尤其 HTTPS 场景,TLS 握手开销大) - 若必须动态构造,至少复用同一
Client实例发多个请求,别写成Client("x").Get("/a"); Client("x").Get("/b")
另外,Client 析构时会同步关闭所有空闲连接——所以别让它被频繁创建/销毁。
HTTPS 场景下 TLS 会话复用比 HTTP Keep-Alive 更关键
对 HTTPS 上游,TCP 层的 Keep-Alive 只解决了一半问题。真正耗时的是 TLS 握手。你需要额外启用会话复用:
- 确保服务端支持
TLS session tickets或session IDs - 在
Client初始化时传入自定义 SSL 上下文,并开启set_ssl_context_callback - 检查日志里是否出现
SSL reused session类提示,没有说明复用失败
没做 TLS 复用,就算 TCP 连接复用了,每次请求仍要花 50–200ms 做完整握手——这比连接池失效还伤性能。
Keep-Alive 池不是开了宏就自动高效,它极度依赖你如何组织 Client 生命周期、是否配合 TLS 复用、以及上游服务是否真正支持长连接。漏掉任意一环,连接数照样飙升,fd 耗尽只是时间问题。


















