File size: 1,394 Bytes
c55968e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | //! 连接池:进程级单例 `reqwest::Client`。
//!
//! 每次新建 client = 每条请求都白付一次 TCP + TLS 握手(几十到几百 ms)。
//! 做成单例后,第二条请求起直接复用连接 → 流式首 token 明显提前。
//!
//! 注意:`reqwest::Client` 内部的连接池是**按 client 实例**管理的,
//! 所以一定要复用同一个实例,而不是每次请求 new 一个。
use std::sync::OnceLock;
use std::time::Duration;
/// 全局单例 HTTP 客户端(首次调用时懒初始化,之后复用)。
///
/// 失败会返回错误字符串——调用方可以降级为一次性 client。
pub fn shared_client() -> Result<reqwest::Client, String> {
static CLIENT: OnceLock<Result<reqwest::Client, String>> = OnceLock::new();
CLIENT
.get_or_init(|| {
reqwest::Client::builder()
// 保留空闲连接,供后续请求复用(keep-alive)
.pool_max_idle_per_host(8)
.pool_idle_timeout(Duration::from_secs(90))
.tcp_keepalive(Duration::from_secs(30))
// 启用压缩:减少下行字节,流式正文更早到
.gzip(true)
.brotli(true)
.deflate(true)
.build()
.map_err(|e| format!("初始化 HTTP 客户端失败:{e}"))
})
.clone()
}
|