Spring Boot微服务AKS部署:Liveness/Readiness探针最佳实践问询
这个问题提得非常好!直接把Actuator默认健康端点同时用在存活(Liveness)和就绪(Readiness)探针上是很多人的初始选择,但在服务依赖数据库这类外部资源的场景下,确实会遇到你说的那些坑。下面我来拆解下在AKS上部署Spring Boot微服务时,这类场景的最佳实践:
首先得明确这两个探针的设计目标完全不同:
- Liveness探针:用来判断容器本身是否陷入了不可恢复的状态(比如死锁、进程崩溃),如果探测失败,Kubernetes会重启容器。它的核心是「保活」,而不是检查服务可用性。
- Readiness探针:用来判断容器是否已经准备好处理请求,只有探测成功的Pod才会被加入服务的流量池。它的核心是「保证服务可用」,需要考虑依赖的状态。
把同一个端点用在两个探针上,就会出现你说的问题:数据库挂了导致Actuator健康状态为down,Liveness触发重启(解决不了数据库问题),Readiness把所有实例移出流量池(哪怕应用还有部分功能可用)。
Liveness探针绝对不能依赖外部服务,因为外部故障不是重启容器能解决的。推荐两种方案:
方案A:用Spring Boot自带的Liveness健康分组(2.3+版本支持)
Spring Boot 2.3之后,Actuator的健康端点支持分组功能,/actuator/health/liveness默认只检查应用自身的存活状态,不会包含数据库、MQ这类外部依赖的健康情况。
对应的Kubernetes配置示例:
livenessProbe: httpGet: path: /actuator/health/liveness port: 8080 initialDelaySeconds: 30 # 根据你的应用启动时间调整 periodSeconds: 10 failureThreshold: 3
方案B:自定义极简存活端点
如果你的Spring Boot版本较低,可以自己写一个简单的端点,只要应用进程还在运行就返回200 OK:
@RestController public class LivenessController { @GetMapping("/live") public ResponseEntity<String> live() { return ResponseEntity.ok("Alive"); } }
然后Kubernetes配置指向这个端点即可。
Readiness需要考虑外部依赖,但要根据你的业务需求灵活调整——毕竟数据库挂了不代表整个服务完全不可用。这里有两种常见思路:
思路A:自定义健康指示器,区分「核心依赖」和「可选依赖」
你可以自己实现HealthIndicator,根据业务逻辑判断哪些依赖是必须的,哪些是可选的。比如如果数据库只是用于部分功能,即使数据库挂了,依然标记服务为就绪,同时在健康详情里说明状态,配合应用内部的降级逻辑。
示例代码:
@Component public class CustomReadinessHealthIndicator implements HealthIndicator { private final DataSource dataSource; public CustomReadinessHealthIndicator(DataSource dataSource) { this.dataSource = dataSource; } @Override public Health health() { try (Connection conn = dataSource.getConnection()) { return Health.up() .withDetail("database", "connected") .build(); } catch (SQLException e) { // 这里根据业务决策:如果数据库不是核心依赖,返回up;否则返回down return Health.up() .withDetail("database", "unavailable") .withDetail("error", e.getMessage()) .build(); } } }
然后在application.yml里配置Readiness分组,只包含这个自定义指示器和必要的系统检查(比如磁盘空间):
management: endpoint: health: groups: readiness: include: customReadinessHealthIndicator, diskSpace
对应的Kubernetes配置:
readinessProbe: httpGet: path: /actuator/health/readiness port: 8080 initialDelaySeconds: 15 periodSeconds: 5 failureThreshold: 2
思路B:结合服务降级与流量控制
如果数据库挂了,应用可以返回降级响应(比如返回缓存的静态数据、默认值),这时候Readiness探针依然标记为up,但通过AKS的Ingress或者服务网格(比如Istio)来根据响应码调整流量,或者在应用内部实现降级逻辑,确保用户能得到可用的响应。
- 调优探针参数:根据应用的启动时间调整
initialDelaySeconds,避免启动过程中误判;periodSeconds(探测间隔)和failureThreshold(失败阈值)要结合业务场景设置——Readiness可以更频繁检查,Liveness可以稍慢一些。 - 完善监控告警:不要只依赖探针,搭配Prometheus+Grafana监控Actuator的健康指标,当数据库不可用时及时告警,让运维团队快速处理,而不是等探针触发Pod重启或流量移除。
- 故障演练:定期模拟数据库故障,测试探针配置和应用的降级逻辑,确保在真实故障时行为符合预期。
内容的提问来源于stack exchange,提问作者chinabuffet

