基于k8s的java应用的优雅停机方法总结

501 阅读1分钟

最近生产环境k8s环境中部署spring boot应用中会出现因为pod缩容的过程中出现线程中断导致业务处理异常的情况, 经过查阅相关资料,总结下面三种场景

1. 针对http请求场景

结合spring boot在2.3.0版本后,新增了优雅停机的特性 docs.spring.io/spring-boot…

image.png 仅限: Tomcat 9.0.33 以及以上版本

新增配置:

spring:
  lifecycle:
    timeout-per-shutdown-phase: 60s
server:
  shutdown: graceful

2. 针对Mq场景

可以实现Spring容器中SmartLifecycle接口的stop方法中,调用MQ的Consumer的实例的shutdown方法实现pod停机时,停止mq的消费。

3. 针对dubbo场景

Dubbo 2.7.5以后版本,通过JDK的Runtime的addShutdownHook的钩子方法,执行DubboBootstrap的destroy方法

下面是2.7.8版本的实现

private DubboBootstrap() {
    configManager = ApplicationModel.getConfigManager();
    environment = ApplicationModel.getEnvironment();

    DubboShutdownHook.getDubboShutdownHook().register();
    ShutdownHookCallbacks.INSTANCE.addCallback(new ShutdownHookCallback() {
        @Override
        public void callback() throws Throwable {
            DubboBootstrap.this.destroy();
        }
    });
}

DubboShutdownHook#register方法实现Runtime的注入shutdownHook,实现停机的callback

public void register() {
    if (registered.compareAndSet(false, true)) {
        DubboShutdownHook dubboShutdownHook = getDubboShutdownHook();
        Runtime.getRuntime().addShutdownHook(dubboShutdownHook);
        dispatch(new DubboShutdownHookRegisteredEvent(dubboShutdownHook));
    }
}

还有spring的容器、 redis连接池、 数据库连接等等,