You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring环境下如何仅将Liveness Probe移至独立端口或线程池?

解决方案

方案一:为Liveness端点分配独立线程池(无需修改端口)

这种方式无需额外端口,仅让Liveness探针请求使用独立线程池,避免被主线程池的高负载阻塞;同时Readiness探针仍使用主线程池,能准确反映应用的负载状态。

  1. 定义独立线程池Bean
    创建专门处理Liveness探针请求的线程池:
@Bean(name = "livenessTaskExecutor")
public TaskExecutor livenessTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2); // 根据实际需求调整核心线程数
    executor.setMaxPoolSize(5); // 最大线程数
    executor.setQueueCapacity(10); // 任务队列容量
    executor.setThreadNamePrefix("liveness-probe-"); // 线程名前缀,便于排查问题
    executor.initialize();
    return executor;
}
  1. 配置MVC路由,仅对Liveness端点应用该线程池
    通过WebMvc配置,限定只有Liveness端点的请求使用上述独立线程池:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    @Qualifier("livenessTaskExecutor")
    private TaskExecutor livenessTaskExecutor;

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setTaskExecutor(livenessTaskExecutor);
        // 拦截请求,仅对Liveness端点启用异步线程池
        configurer.registerCallableInterceptors(new CallableProcessingInterceptor() {
            @Override
            public <T> boolean isAsyncRequest(HttpServletRequest request, Callable<T> task) {
                return request.getRequestURI().equals("/actuator/health/liveness");
            }
        });
    }
}

配置后,主线程池高负载时,Readiness探针会因响应缓慢被判定为未就绪,Pod被移出流量池;而Liveness探针使用独立线程池,能快速响应,避免Pod被误杀。

方案二:将Liveness端点单独部署到独立端口

如果业务场景要求必须将Liveness探针放在独立端口,可通过Spring Boot多WebServer配置实现:主应用端口承载Readiness探针,独立端口仅提供Liveness端点服务。

  1. 添加自定义配置属性
    在application.properties中定义Liveness端口:
management.liveness.server.port=9091
  1. 配置独立WebServer用于Liveness端点
    创建配置类,启动第二个WebServer,仅注册Liveness相关的Actuator端点:
@Configuration
public class LivenessServerConfig {
    @Value("${management.liveness.server.port:9091}")
    private int livenessPort;

    @Bean
    public ServletWebServerFactory livenessServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(livenessPort);
        factory.addInitializers(servletContext -> {
            // 初始化仅用于Liveness端点的DispatcherServlet
            DispatcherServlet dispatcherServlet = new DispatcherServlet();
            AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
            context.register(LivenessEndpointConfig.class);
            dispatcherServlet.setApplicationContext(context);
            // 仅映射Liveness端点路径
            servletContext.addServlet("livenessDispatcher", dispatcherServlet)
                    .addMapping("/actuator/health/liveness");
        });
        return factory;
    }

    // 仅配置Liveness所需的Actuator组件
    @Configuration
    static class LivenessEndpointConfig {
        @Bean
        public HealthEndpoint healthEndpoint(HealthAggregator healthAggregator, HealthIndicatorRegistry registry) {
            return new HealthEndpoint(healthAggregator, registry);
        }

        @Bean
        public LivenessHealthIndicator livenessHealthIndicator() {
            return new LivenessHealthIndicator();
        }

        @Bean
        public EndpointMapping endpointMapping() {
            return new EndpointMapping("/actuator");
        }

        @Bean
        public WebMvcEndpointHandlerMapping webMvcEndpointHandlerMapping(EndpointMapping endpointMapping,
                                                                         List<ExposableEndpoint<?>> endpoints,
                                                                         EndpointMediaTypes endpointMediaTypes,
                                                                         CorsEndpointProperties corsProperties,
                                                                         WebEndpointProperties webEndpointProperties) {
            return new WebMvcEndpointHandlerMapping(endpointMapping, endpoints, endpointMediaTypes,
                    corsProperties.toCorsConfiguration(), webEndpointProperties);
        }
    }
}

配置完成后,Kubernetes的Readiness探针指向主应用端口的/actuator/health/readiness,Liveness探针指向9091端口的/actuator/health/liveness,两者完全独立,互不影响。


内容的提问来源于stack exchange,提问作者Shachar Levy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:15:16