健康检查失败时应设 timeout=(3,3)、禁用重试、verify=false 并禁用警告;http/2 需显式启用;urllib3 要配 maxsize、block=true、retries=0;须校验响应内容而非仅 status_code。

健康检查失败时 requests.get() 报 ConnectionError 怎么办
多数 Python 负载均衡器(如 HAProxy + 自研健康检查脚本、或用 urllib3 驱动的自定义探测)依赖 HTTP 请求判断后端存活,但直接用 requests.get() 默认不设超时,一卡就是 60 秒,拖垮整个检查周期。
- 必须显式传
timeout=(3, 3)—— 第一个 3 是连接超时,第二个 3 是读取超时,避免单点阻塞 - 禁用重试:
requests.adapters.HTTPAdapter(max_retries=0),健康检查不该自动重试,失败就该立刻上报 - 不要用
verify=True检查生产环境自签名证书,会报SSLError;改用verify=False并加requests.packages.urllib3.disable_warnings() - 如果后端是 gRPC 或 TCP 端口,
requests完全不适用,得换socket.connect_ex()或asyncio.open_connection()
用 httpx 做异步健康检查要注意什么
httpx.AsyncClient 能并发打多个后端,但默认复用连接池,容易在高频率探测下耗尽文件描述符,尤其在容器里跑着跑着就 OSError: [Errno 24] Too many open files。
- 限制连接池大小:
AsyncClient(limits=httpx.Limits(max_connections=20, max_keepalive_connections=10)) - 每次请求必须
await client.get(url, timeout=2.0),不能漏掉await,否则返回的是 coroutine 对象,后续调用会报TypeError: object Response can't be used in 'await' expression - 别在循环里反复创建
AsyncClient实例,连接池开销大;应复用 client,用完调await client.aclose() - HTTP/2 支持默认关闭,若后端强制 HTTP/2,需加
http2=True,否则降级为 HTTP/1.1 后可能触发服务端 421 错误
urllib3 的 PoolManager 和 connection_pool_kw 参数怎么配
很多负载均衡器底层用 urllib3(比如 requests 就是它封装的),直接调 PoolManager 更可控,但参数名晦涩,容易配错。
-
maxsize是每个 host 的最大连接数,不是全局总数;想控制总并发请算清楚:比如 5 个后端 ×maxsize=4= 最多 20 连接 -
block=True必须设为True,否则连接池满时直接抛MaxRetryError,而不是排队等待 -
retries=0关闭重试,和requests一样,健康检查失败就该立即反馈 -
timeout=urllib3.Timeout(connect=2.0, read=2.0)比用浮点数更明确,且支持Timeout(total=3.0)控制总耗时
为什么健康检查接口返回 200 却被判定为失败
常见于后端返回 {"status": "ok"} 但没设 Content-Type: application/json,或者返回了 200 但 body 是空字符串,而检查逻辑却要求非空 JSON 且含特定字段。
立即学习“Python免费学习笔记(深入)”;
- 别只看
response.status_code == 200,要加response.text.strip()判空,空响应应视为失败 - 若校验 JSON 字段,先 try
response.json(),捕获JSONDecodeError直接标失败,别让异常穿透到上层 - 注意重定向:默认
allow_redirects=True,302 到维护页也返回 200,建议关掉重定向或显式检查response.is_redirect - 某些 LB(如 Nginx Plus API)要求健康检查带特定 header,比如
X-Healthcheck: true,漏了就返回 403
健康检查真正难的不是发请求,而是把「瞬时网络抖动」「后端假死但 TCP 连接未断」「证书过期但 HTTPS 握手成功」这些边界情况,翻译成可配置、可观察、可收敛的判定逻辑。参数调得再细,漏掉一次 strip() 或少设一个 timeout,就可能让整组实例被错误摘除。










