java关闭服务_实现优雅地关闭Docker中的java服务

时至今日,Docker在项目中的应用越来越普遍了,但往往会遭遇一些麻烦,比如说,有几个请求至Docker中的服务,发起了事务处理业务,但每个事务完成可能需要1-5分钟,而此时我们正要将Docker停机准备发布新版本,那如何在不影响当前业务执行的停止服务呢?有人会说,用docker stop,默认10秒延迟关停,加个延时参数-t 300,完美!有一说一,确实,但问题又来了,当前服务中的业务处理满足了,如何防止新的请求产生?所以,如何优雅地停机成了开发者关注的问题。好了,不多BB,直接开整铁汁们。

思路:执行docker stop -t 360,Java服务会收到容器发出的SIGTERM信号,监听到此信号并执行相关操作,如注销MQ或Eureka,关闭Controller或ThreadPool等。

先贴一段代码,关于如何监听SIGTERM,并关闭RabbitMQ。

public classXXXApplication {************

private static boolean stopHandle = false;

public static voidmain(String[] args) {

SpringApplication springApplication= new SpringApplication(XXXApplication.class);************ApplicationContext context=springApplication.run(args);

ApplicationParam appParam= context.getBean(ApplicationParam.class);

// 监听信号

handleSignal("TERM", context);

************

}private static void handleSignal(String name, ApplicationContext context) {

Signal signal = new Signal(name);

signal.handle(signal,Signal -> {

logger.info("signal received: "+ signal.getName());

if("TERM".equals(signal.getName())){

shutdown(context);

stopHandleApi = true;

}

});

}

private static void shutdown(ApplicationContext context) {

// 关闭rabbit mq

logger.info("shutdown rabbitMQ listener! ");

RabbitListenerEndpointRegistry rer = context.getBean(RabbitListenerEndpointRegistry.class);

rer.stop();

}

}

这里将stopHandle这个静态常量设为true的目的是表明程序即将停止,这样也能在其它地方应用,比如,写一个拦截器,当接收到新的请求时拦截,判断stopHandle是否为true,如果是则说明服务要停止了,不再接受新请求,同时返回404给客户端。

public class RestApiInterceptor extendsHandlerInterceptorAdapter {private static final Logger logger = LogManager.getLogger(RestApiInterceptor.class);

@Overridepublic booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throwsException {

logger.info("isStopHandleApi = "+FintechEkycApplication.isStopHandleApi());if(ShortenLinkSysApplication.isStopHandleApi()){

response.setStatus(404);

response.setContentType("text/html");

response.setCharacterEncoding("UTF-8");

response.getWriter().println("application is stopping! Please wait minutes and request after it restart !");return false;

}else{return true;

}

}

测试效果如图:

a2215e4159237b371cc0d6bbf0c355b0.png

总结:如果希望代码更优雅一点可以利用事件驱动,写个继承TomcatConnectorCustomizer的类来处理像Thread Pool、Web servlet等。这里就不整活了铁汁们,今天就到这里,拜拜。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
01_尚硅谷_Docker_前提知识要求和课程简介.avi 02_尚硅谷_Docker_为什么会出现.avi 03_尚硅谷_Docker_理念.avi 04_尚硅谷_Docker_是什么.avi 05_尚硅谷_Docker_能干什么.avi 06_尚硅谷_Docker_三要素.avi 07_尚硅谷_Docker_CentOS6安装Docker.avi 08_尚硅谷_Docker_CentOS7安装Docker简介(补充知识请看34集).avi 09_尚硅谷_Docker_阿里云镜像加速器配置.avi 10_尚硅谷_Docker_helloworld镜像.avi 11_尚硅谷_Docker_运行底层原理.avi 12_尚硅谷_Docker_帮助命令.avi 13_尚硅谷_Docker_镜像命令.avi 14_尚硅谷_Docker_容器命令(上).avi 15_尚硅谷_Docker_容器命令(下).avi 16_尚硅谷_Docker_镜像原理.avi 17_尚硅谷_Docker_镜像commit.avi 18_尚硅谷_Docker_容器数据卷介绍.avi 19_尚硅谷_Docker_容器数据卷用V命令添加.avi 20_尚硅谷_Docker_容器数据卷用DockerFile添加.avi 21_尚硅谷_Docker_容器数据卷volumes-from.avi 22_尚硅谷_Docker_Dockerfile是什么.avi 23_尚硅谷_Docker_DockerFile构建过程解析.avi 24_尚硅谷_Docker_DockerFile保留字指令.avi 25_尚硅谷_Docker_DockerFile案例-自定义镜像mycentos.avi 26_尚硅谷_Docker_DockerFile案例-CMD-ENTRYPOINT命令案例.avi 27_尚硅谷_Docker_DockerFile案例-ONBUILD命令案例.avi 28_尚硅谷_Docker_DockerFile案例-自定义的tomcat9.avi 29_尚硅谷_Docker_DockerFile案例-自定义的tomcat9上发布演示.avi 30_尚硅谷_Docker_DockerFile小总结.avi 31_尚硅谷_Docker_安装mysql.avi 32_尚硅谷_Docker_安装Redis.avi 33_尚硅谷_Docker_本地镜像推送到阿里云.avi

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值