如何判断Spring Boot应用已就绪?Docker Compose下配置服务启动时机检测
这问题我之前在团队部署微服务的时候也碰到过,Docker网络的特殊性确实让端口监听这种常规手段不好使,解析日志又太脆弱。给你几个靠谱的方案,都是基于Spring Boot本身的特性来判断启动完成时机,完全符合你的需求:
方案一:利用Spring Boot Actuator的健康/就绪端点做Docker健康检查
这是最推荐的方案,通过应用自身的就绪状态来告诉Docker它已经完全启动好、能处理请求了,docker-compose会自动等待Config Server就绪后再启动其他服务。
步骤1:给Config Server开启Actuator并配置就绪端点
首先在Config Server的pom.xml(Maven)或build.gradle(Gradle)中添加Actuator依赖:
<!-- Maven --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
然后在Config Server的application.yml或application.properties中暴露健康和就绪端点,并配置就绪状态的判断逻辑:
management: endpoints: web: exposure: include: health, readiness # 暴露健康和就绪端点 endpoint: readiness: enabled: true health: readiness-state: enabled: true
当Config Server完全初始化完成(包括配置仓库加载完成),/actuator/readiness端点会返回UP状态。
步骤2:在docker-compose.yml中配置健康检查和依赖
给Config Server服务添加healthcheck配置,然后让其他服务通过depends_on的service_healthy条件来依赖它:
version: '3.8' services: config-server: image: your-config-server-image:latest ports: - "8888:8888" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8888/actuator/readiness"] interval: 5s timeout: 3s retries: 10 start_period: 10s # 给应用留一点启动初始化的时间 user-service: image: your-user-service-image:latest depends_on: config-server: condition: service_healthy # 等待Config Server健康检查通过才启动 # 其他服务配置...
方案二:给其他微服务配置Spring Cloud Config重试机制
如果不想依赖Docker的健康检查,也可以让其他微服务在拉取配置失败时自动重试,直到Config Server可用。这种方式不需要等待,而是让服务自身具备容错能力。
步骤1:添加重试依赖
在需要拉取配置的微服务中添加Spring Retry和AOP依赖:
<!-- Maven --> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
步骤2:配置重试参数
在微服务的bootstrap.yml(注意是bootstrap不是application,因为配置加载优先级更高)中添加如下配置:
spring: cloud: config: fail-fast: true # 开启快速失败,触发重试 retry: max-attempts: 15 # 最大重试次数 initial-interval: 2000 # 初始重试间隔(毫秒) multiplier: 1.5 # 间隔乘数,每次重试间隔翻倍 max-interval: 10000 # 最大重试间隔(毫秒)
这样即使微服务比Config Server先启动,也会不断重试拉取配置,直到Config Server就绪。
方案三:自定义Spring Boot启动完成的标识
如果以上方案都不适用,还可以在Config Server中自定义一个端点,当应用完全启动完成后才返回成功。比如写一个简单的Controller:
@RestController public class ReadyController { private volatile boolean isReady = false; @EventListener(ContextRefreshedEvent.class) public void onApplicationReady() { // ContextRefreshedEvent触发时,说明Spring容器已经初始化完成 isReady = true; } @GetMapping("/ready") public ResponseEntity<String> isApplicationReady() { return isReady ? ResponseEntity.ok("READY") : ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("NOT READY"); } }
然后在docker-compose的健康检查中调用这个/ready端点,效果和Actuator的就绪端点类似,适合需要自定义启动完成判断逻辑的场景。
内容的提问来源于stack exchange,提问作者Artyom Karnov

