当springboot遇到dubbo优雅停机

JVM优雅停机机制

关于优雅停机,JVM提供了一个叫做ShutdownHook的东东,什么意思呢?就是说我们的应用程序只要在程序中向JVM注册了这个东东,JVM就会在收到关机信号(非kill -9)时,JVM就会在真正调用关机之前执行你注册在ShutdownHook里的东东,以达到程序在关闭前释放掉各种资源的目的。

注册方式:

注册ShutdownHook

Runtime.getRuntime().addShutdownHook(Thread thread)

解决的问题
dubbo在其类AbstractConfig里面注册了ShutdownHook:

在这里插入图片描述
SpringBoot中则在应用run之后刷新上下文时注册ShutdownHook:
在这里插入图片描述
在这里插入图片描述
故应用程序在收到关机信号(非kill -9)时,JVM会同时启动两个线程来分别运行Dubbo和SpringBoot的停机工作,Dubbo和SpringBoot自身都实现了自身的优雅停机,但是由于Dubbo和SpringBoot的整合,使得如果dubbo在优雅停机过程中处理未处理完请求时SpringBoot已完成关机时服务端和客户端就会产生大量错误,我们的优雅停机就是要解决这样的问题。

解决思路
由于Dubbo自身优雅停机过程中可能会依赖SpringBoot的组件,SpringBoot在SpringBootApplication中提供了取消自身注册ShutdonwHook的机制,如下:
在这里插入图片描述
那么,大体思路就是取消掉SpringBoot自身的ShutdownHook注册,为SpringBoot注册一个ShutdownHook,让SpringBoot在等待一定时间(等待Dubbo先关闭)后,在关闭SpringBoot容器。

具体代码

package com.xyy.crm.query.consumer.shutdown;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
 
import javax.annotation.PostConstruct;
 
 
/**
 * @author gelong
 */
@Component
public class GracefullyShutdownHook {
 
   private final Logger logger = LoggerFactory.getLogger(GracefullyShutdownHook.class);
    
   @Autowired
   private ConfigurableApplicationContext configurableApplicationContext;
 
   @Value("${spring.dubbo.service.shutdown.wait}")
   private long dubboShutdownWait;
 
   @PostConstruct
   public void registerShutdownHook() {
      logger.info("[SpringShutdownHook] Register ShutdownHook....");
      Runnable shutdownHook = () -> {
         try {
            logger.info("[SpringShutdownHook] Application need sleep {} seconds to wait Dubbo shutdown", (double)dubboShutdownWait / 1000.0D);
            Thread.sleep(dubboShutdownWait);
            logger.info("[SpringShutdownHook] ApplicationContext closed start, Application shutdown doing");
            this.configurableApplicationContext.close();
            logger.info("[SpringShutdownHook] ApplicationContext closed, Application shutdown");
         } catch (InterruptedException var2) {
            logger.error(var2.getMessage(), var2);
         }
      };
      Runtime.getRuntime().addShutdownHook(new Thread(shutdownHook));
   }
}

注:

dubboShutdownWait为配置的等待Dubbo关闭时长,单位为ms,此值Dubbo官网给出的缺省值是10000ms,具体自定。

参考文档
https://blog.csdn.net/liubenlong007/article/details/79958076

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值