健康检查要贴近真实业务流量,看后端协议说话:HTTP服务用HTTP探测最贴肉,MySQL、Redis、TCP长连接或纯四层服务用TCP探测更合理。 硬给HTTP服务上TCP探测,业务已经502了负载均衡还往里转发,就是常见翻车现场。
先分清TCP探测和HTTP探测到底在干啥
很多运维把TCP探测理解成“能连上端口就行”,HTTP探测理解成“能返回200才算活”,这个理解没毛病,但落到数据包里,区别比想象中更具体。
TCP健康检查发起的是一次标准的TCP三次握手:
- 负载均衡向后端IP和端口发SYN
- 后端回SYN-ACK
- 负载均衡再回ACK,连接建立成功,立刻判定后端存活
- 探测结束会发送RST或FIN断开,不产生业务数据
HTTP健康检查则在TCP连接建立之后还会走完整应用层请求:
- 负载均衡向后端发起HTTP GET请求
- 后端返回状态码、响应头、响应体
- 只有状态码匹配预设范围,才判定后端存活
- 如果后端返回502、503、404,或响应超时,判定为不健康
用命令行模拟最直观:
nc -zv 10.0.0.10 3306:这就是标准TCP探测思路,只看端口通不通curl -I --max-time 5 http://10.0.0.10/health:这是HTTP探测,看路径返回的是不是200
所以问题不在于谁高级,而在于你的后端服务认不认应用层状态。
TCP健康检查和HTTP探测区别:不止是状态码那么简单
拿一个Nginx后面挂PHP-FPM的站点举例,PHP-FPM进程全挂,Nginx本身还活着,80端口正常监听,这时TCP探测会一直认为后端健康,因为Nginx完全能完成TCP握手,但用户打开网页看到的是Nginx返回的502,负载均衡继续把请求转发到这台已经不能处理动态请求的机器上。
这就是“端口活着但业务死了”的典型场景。
| 对比维度 | TCP健康检查 | HTTP健康检查 |
|---|---|---|
| 探测层次 | 四层传输层 | 七层应用层 |
| 判断依据 | 三次握手是否成功 | 状态码、响应内容、超时时间 |
| 能发现的故障 | 端口关闭、网络不通、内核拒绝连接 | 应用返回5xx、服务进程假死、超时 |
| 误判风险 | 较高,四层通不代表业务活着 | 较低,靠近用户真实请求 |
| 资源开销 | 小,只发握手包 | 稍大,每次完整HTTP请求 |
| 适用后端 | MySQL、Redis、SMTP、自定义TCP服务 | Nginx、Tomcat、API服务、微服务 |
TCP健康检查和HTTP探测区别”这个老问题,核心答案就一句:TCP只看路通不通,HTTP看货到没到。
负载均衡健康检查配置TCP还是HTTP?跟着协议走
配置健康检查之前,先问自己三个问题:
- 后端监听的是不是HTTP或HTTPS协议?
- 后端有没有一个能正常返回200或301的固定路径?
- 应用层错误会不会导致服务不可用?

如果三个都是“是”,别犹豫,直接上HTTP探测,原因是HTTP探测能覆盖TCP探测看不到的故障层,比如Nginx配置错误、后端应用崩溃但端口没释放、数据库连接池耗尽导致接口超时,这些都是线上最常发生的“半死不活”状态。
如果后端是MySQL、Redis、Kafka、SMTP这类非HTTP协议,HTTP探测根本无从下手,只能选TCP,硬要这些服务解析HTTP请求,协议不对会直接断开,探测结果反而不可信。
还有一类HTTP服务,虽然监听80端口,但开发不提供健康检查路径,或者根路径返回302跳转,这时HTTP探测可能因为状态码不匹配把好机器摘掉,怎么办?可以:
- 让开发补一个
/health接口,返回200和空body - 把健康检查状态码范围加上302、301,避免跳转误判
- 暂时降级为TCP探测,保持基本可用
行业共识认为,健康检查的最终目标不是探测本身多高级,而是用最小化的探测请求,提前把无法服务真实流量的节点踢出去。
健康检查探测间隔设置多少合适?用故障恢复目标倒推
很多人配置健康检查时直接选默认值,从不去想探测间隔和阈值意味着什么,这里用一个具体场景说明。
假设你的一套API服务部署在云负载均衡后面,后端有两台云服务器,故障恢复目标要求是:一台后端宕机后,业务最多受影响20秒,那么健康检查间隔、超时、不健康阈值怎么配?
多数云厂商默认值通常是:
- 探测间隔:2秒到5秒
- 探测超时:1秒到3秒
- 健康阈值:2次到3次
- 不健康阈值:2次到3次
如果间隔取5秒,超时取3秒,不健康阈值取3次,那么从后端开始异常到负载均衡把它摘除,最坏耗时大约是:
- 第一次探测超时:3秒
- 第二次探测超时:3秒
- 第三次探测超时:3秒
- 触发不健康阈值后摘除
总计约9到15秒,还没算调度和状态同步,这样能满足20秒目标。
如果故障恢复目标要求5秒内摘除,只能把间隔调到1秒、超时调到1秒、不健康阈值改成2次,但代价是:
- 探测频率增加,负载均衡和后端CPU开销上升
- 偶发网络抖动可能导致误摘除
- 健康节点频繁上下线,引发流量重分配
健康检查探测间隔设置多少合适”没有固定答案,要用业务能接受多长的故障暴露时间去倒推,高可用要求越严,间隔和阈值越激进,但误判风险也越高。
北京地域云服务器健康检查优化:安全组和跨可用区不能漏
不少用户搜“北京地域云服务器健康检查优化”,其实卡点往往不在探测类型,而在安全组和地域网络细节。
北京地域的云负载均衡通常跨多个可用区部署,健康检查流量从负载均衡的内网地址发出,访问后端云服务器的监听端口,如果你的安全组只放行了业务客户端网段,却把负载均衡的内网健康检查源IP挡在门外,后端会全部显示异常。
实际操作路径以通用云平台为例:
- 登录云控制台,找到负载均衡实例
-

进入监听器管理,找到健康检查配置页
- 查看控制台给出的健康检查源IP网段
- 在后端云服务器安全组入方向,放行这些源IP到后端端口
- 不要把健康检查源IP网段和负载均衡公网出口IP混为一谈
如果后端只开启了内网监听,没有公网IP,健康检查仍然能通过内网进行,不需要额外暴露公网端口,这点在多可用区部署时容易忽略。
还有个价格相关的疑问常被一起搜到,就是负载均衡健康检查收费吗,多数云平台健康检查功能本身不单独计费,探测产生的内网流量很小,会并入负载均衡实例或云服务器的内网流量统计中,几乎不会成为独立成本项目,但如果探测间隔设到1秒,后端数十台机器,产生的累计内网流量和连接数也会上升,成本虽然不大,但也不能完全忽略。
用真实故障场景理解误判:TCP通过但业务已经死了
说一个线上比较常见的组合:Nginx作为反向代理,后端是Tomcat,Tomcat线程池被打满,端口8080监听正常,但每个新请求进来都排队超时,这时TCP探测三次握手完全正常,负载均衡认为后端健康,用户侧表现为大量请求卡死,连接不报错但一直等。
如果把TCP探测替换成HTTP探测,健康检查请求会进入Tomcat线程池排队,超过探测超时时间仍然拿不到200,负载均衡就会把该节点标记为不健康,摘除后流量转到正常节点,业务恢复。
还有一类隐蔽故障:Nginx配置了keep-alive,健康检查使用长连接复用,看似返回200,实际响应体是旧缓存,这种偏离真实请求的场景,HTTP探测比TCP多了一层验证能力,但也不能完全替代真实业务指标。
所以判断“健康检查用TCP还是HTTP探测更贴近真实”的结论依然清晰:真实用户走的是应用层协议,所以HTTP探测天然更贴近真实用户流量。 只有当后端协议本身不是HTTP时,TCP探测才是匹配的选择。
实操配置:在云负载均衡和自建Nginx上怎么改探测类型
云负载均衡控制台
以通用云控制台操作路径为例:
- 进入负载均衡实例,选择“监听器管理”
- 点击目标监听器,进入“健康检查”配置页
- 探测协议选择“TCP”或“HTTP”
- HTTP探测需填写健康检查路径,如
/health或/probe - 设置状态码范围,一般填
200或200-399 - 保存后等待健康检查策略下发,通常几十秒内生效
自建Nginx加HTTP探测
开源Nginx本身没有主动HTTP健康检查模块,需要借助第三方模块或切换为Nginx Plus:
- 开源Nginx可使用
nginx_upstream_check_module,编译后配置类似:
upstream backend {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
check interval=3000 rise=2 fall=3 timeout=2000 type=http;
check_http_send "GET /health HTTP/1.1rnHost: localhostrnrn";
check_http_expect_alive http_2xx http_3xx;
}
- Nginx Plus原生支持:
upstream backend {
zone backend 64k;
server 10.0.0.11:8080;
server 10.0.0.12:8080;
health_check interval=3s fails=3 passes=2 uri=/health;
}

HAProxy
HAProxy配置HTTP探测更加简单:
backend app_backend
balance roundrobin
option httpchk GET /health
server web1 10.0.0.11:8080 check inter 3s fall 3 rise 2
server web2 10.0.0.12:8080 check inter 3s fall 3 rise 2
这些命令和配置可以直接拿去验证,配置时注意健康检查路径不要让缓存层包装,保持后端真实处理逻辑。
选型建议:哪些场景必须上HTTP、哪些别硬上
-
必须用HTTP探测:
- 后端是HTTP/HTTPS API、微服务、前后端分离站点
- 需要优雅排空或按业务状态摘除节点
- 负载均衡做TLS卸载,后端只处理明文HTTP
- 后端程序可能返回5xx但进程不会退出
-
用TCP探测就够:
- MySQL、PostgreSQL、Redis、Memcached
- MQTT、Kafka自定义协议、Socket服务
- HTTP服务没有健康检查路径且短期无法改造
- 只关心端口级存活,不关心应用层状态
-
折中方案:
- HTTP探测指向一个静态文件路径,减少后端动态计算开销
- 用
/health?level=light做基础存活性检查,避免深依赖探测
常见误区和排障要点
- 安全组没放行健康检查源IP,导致所有后端健康检查失败
- HTTP健康检查路径404或302,状态码不匹配导致全量摘除
- 探测请求走公网域名绕一圈回来,时延和公网抖动影响判定
- 短连接探测频率过高,后端出现大量TIME_WAIT连接
- 后端只有一个节点时,健康检查失败后负载均衡直接502,要考虑摘除策略
排查时先看健康检查日志,确认负载均衡发出的源IP和请求路径是否到达后端,再看后端访问日志中健康检查路径的返回码,很多时候问题根本不在TCP或HTTP,而在安全组、状态码配置和探测源IP上。
健康检查不是为了证明系统活着,而是为了赶在用户感知到故障之前,把坏掉的节点从流量池里拿掉。贴近真实的探测,就是让健康检查请求尽量接近真实用户请求,协议对齐了,误判才会少。
Q&A
健康检查TCP和HTTP探测哪个更真实?
对HTTP业务来说,HTTP探测更真实,因为真实用户走的是HTTP请求,能发现应用层5xx、超时、假死等问题,对MySQL、Redis等非HTTP协议服务,TCP探测才是匹配真实业务协议的探测方式。
负载均衡健康检查配置TCP还是HTTP更省资源?
TCP探测比HTTP探测省资源,握手包很小,不会产生业务数据,HTTP探测每次要完整请求和响应,对高并发后端会产生额外连接和CPU开销,但省资源不能替代发现故障的能力,HTTP服务仍建议优先用HTTP探测。
健康检查探测间隔设置多少合适?
没有固定答案,要根据业务能接受的最大故障暴露时间倒推,多数场景下间隔2到5秒、超时1到3秒、不健康阈值2到3次可以满足一般高可用要求,如果要求秒级摘除,可以缩短间隔到1秒,但需评估误判和资源开销。