健康检查
2026/1/15大约 4 分钟Consul健康检查Health Check
健康检查
一、健康检查概述
Consul 提供多种健康检查方式,确保只有健康的服务实例参与负载均衡。
1.1 检查类型
| 类型 | 说明 | 适用场景 |
|---|---|---|
| HTTP | 发送 HTTP 请求检查 | Web 服务 |
| TCP | TCP 连接检查 | 数据库、缓存 |
| gRPC | gRPC 健康检查 | gRPC 服务 |
| Script | 执行脚本检查 | 自定义检查 |
| TTL | 服务主动上报 | 特殊场景 |
| Docker | Docker 容器检查 | 容器化服务 |
1.2 检查状态
passing:健康warning:警告critical:不健康
二、HTTP 检查
2.1 基本配置
{
"service": {
"name": "user-service",
"port": 8080,
"check": {
"http": "http://localhost:8080/health",
"method": "GET",
"interval": "10s",
"timeout": "5s"
}
}
}2.2 带请求头的检查
{
"check": {
"http": "http://localhost:8080/health",
"header": {
"Authorization": ["Bearer token123"],
"Content-Type": ["application/json"]
},
"interval": "10s"
}
}2.3 TLS 检查
{
"check": {
"http": "https://localhost:8443/health",
"tls_skip_verify": false,
"tls_server_name": "user-service.example.com",
"interval": "10s"
}
}2.4 Spring Boot Actuator
# application.yml
management:
endpoints:
web:
exposure:
include: health
endpoint:
health:
show-details: always@Component
public class CustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// 自定义健康检查逻辑
boolean isHealthy = checkDatabase();
if (isHealthy) {
return Health.up()
.withDetail("database", "connected")
.build();
}
return Health.down()
.withDetail("database", "disconnected")
.build();
}
private boolean checkDatabase() {
// 检查数据库连接
return true;
}
}三、TCP 检查
3.1 基本配置
{
"service": {
"name": "mysql",
"port": 3306,
"check": {
"tcp": "localhost:3306",
"interval": "10s",
"timeout": "5s"
}
}
}3.2 Redis 检查示例
{
"service": {
"name": "redis",
"port": 6379,
"check": {
"tcp": "localhost:6379",
"interval": "5s",
"timeout": "2s"
}
}
}四、gRPC 检查
4.1 配置方式
{
"service": {
"name": "grpc-service",
"port": 9090,
"check": {
"grpc": "localhost:9090",
"grpc_use_tls": false,
"interval": "10s"
}
}
}4.2 gRPC 健康检查实现
// 实现 gRPC 健康检查协议
public class HealthServiceImpl extends HealthGrpc.HealthImplBase {
@Override
public void check(HealthCheckRequest request,
StreamObserver<HealthCheckResponse> responseObserver) {
HealthCheckResponse response = HealthCheckResponse.newBuilder()
.setStatus(HealthCheckResponse.ServingStatus.SERVING)
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}五、Script 检查
5.1 基本配置
{
"check": {
"args": ["/usr/local/bin/check-service.sh"],
"interval": "30s",
"timeout": "10s"
}
}5.2 检查脚本示例
#!/bin/bash
# check-service.sh
# 检查进程是否存在
if pgrep -x "java" > /dev/null; then
echo "Service is running"
exit 0 # passing
else
echo "Service is not running"
exit 2 # critical
fi5.3 退出码含义
| 退出码 | 状态 |
|---|---|
| 0 | passing |
| 1 | warning |
| 其他 | critical |
六、TTL 检查
6.1 配置方式
{
"service": {
"name": "batch-service",
"check": {
"ttl": "30s"
}
}
}6.2 服务主动上报
# 上报健康状态
curl -X PUT http://localhost:8500/v1/agent/check/pass/service:batch-service
# 上报警告状态
curl -X PUT http://localhost:8500/v1/agent/check/warn/service:batch-service
# 上报失败状态
curl -X PUT http://localhost:8500/v1/agent/check/fail/service:batch-service6.3 Java 实现
@Component
public class ConsulTTLHealthCheck {
@Autowired
private ConsulClient consulClient;
@Scheduled(fixedRate = 10000) // 每10秒上报一次
public void reportHealth() {
try {
// 执行健康检查逻辑
boolean healthy = performHealthCheck();
if (healthy) {
consulClient.agentCheckPass("service:batch-service");
} else {
consulClient.agentCheckFail("service:batch-service", "Health check failed");
}
} catch (Exception e) {
consulClient.agentCheckFail("service:batch-service", e.getMessage());
}
}
private boolean performHealthCheck() {
// 自定义检查逻辑
return true;
}
}七、多重检查
7.1 配置多个检查
{
"service": {
"name": "user-service",
"port": 8080,
"checks": [
{
"id": "http-check",
"name": "HTTP Health Check",
"http": "http://localhost:8080/health",
"interval": "10s"
},
{
"id": "tcp-check",
"name": "TCP Port Check",
"tcp": "localhost:8080",
"interval": "5s"
},
{
"id": "memory-check",
"name": "Memory Check",
"args": ["/scripts/check-memory.sh"],
"interval": "30s"
}
]
}
}7.2 检查聚合
所有检查都通过时,服务才被认为是健康的。
八、Spring Cloud Consul 健康检查
8.1 配置
spring:
cloud:
consul:
discovery:
health-check-path: /actuator/health
health-check-interval: 10s
health-check-timeout: 5s
health-check-critical-timeout: 30s8.2 自定义健康检查路径
spring:
cloud:
consul:
discovery:
health-check-url: http://${spring.cloud.client.ip-address}:${server.port}/custom-health8.3 禁用健康检查
spring:
cloud:
consul:
discovery:
register-health-check: false九、健康检查 API
9.1 查询服务健康状态
# 查询所有健康检查
curl http://localhost:8500/v1/health/checks/user-service
# 只返回健康的服务
curl "http://localhost:8500/v1/health/service/user-service?passing=true"
# 查询节点健康状态
curl http://localhost:8500/v1/health/node/node19.2 响应示例
[
{
"Node": "node1",
"CheckID": "service:user-service",
"Name": "Service 'user-service' check",
"Status": "passing",
"Output": "HTTP GET http://localhost:8080/health: 200 OK"
}
]十、最佳实践
10.1 检查间隔设置
10.2 超时设置
- 超时时间应小于检查间隔
- 建议:
timeout = interval / 2
10.3 故障转移时间
故障转移时间 = 检查间隔 + 超时时间 + 服务发现缓存时间10.4 检查建议
| 场景 | 推荐检查类型 | 间隔 |
|---|---|---|
| Web 服务 | HTTP | 10s |
| 数据库 | TCP | 10s |
| 消息队列 | TCP | 5s |
| 批处理 | TTL | 30s |
| gRPC 服务 | gRPC | 10s |
