Python 负载均衡器的健康检查

1次阅读

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

Python 负载均衡器的健康检查

健康检查失败时 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 错误

urllib3PoolManagerconnection_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,就可能让整组实例被错误摘除。

text=ZqhQzanResources