最近无论是校招还是社招,都进行的如火如荼,我也承担了很多的面试工作,在一次面试过程中,和候选人聊了一些关于Dubbo的知识。

Dubbo是一个比较著名的RPC框架,很多人对于他的一些网络通信、通信协议、动态代理等等都有一定的了解,这位候选人也一样。

但是,我接下来问了他一个问题:你们在使用Dubbo的时候,应用如果重启,怎么保证一个请求不会被中断处理的呢?

他没怎么说的上来,我以为他不理解我的问题,我接着问他:我就是想问下Dubbo是如何做优雅上下线的你知道吗?

接着他问我:优雅上下线是啥??

好吧。

这篇文章,我来介绍一下这个知识点吧。

优雅上下线

关于"优雅上下线"这个词,我没找到官方的解释,我尝试解释一下这是什么。

首先,上线、下线大家一定都很清楚,比如我们一次应用发布过程中,就需要先将应用服务停掉,然后再把服务启动起来。这个过成就包含了一次下线和一次上线。

那么,"优雅"怎么理解呢?

先说什么情况我们认为不优雅:

1、服务停止时,没有关闭对应的监控,导致应用停止后发生大量报警。

2、应用停止时,没有通知外部调用方,很多请求还会过来,导致很多调用失败。

3、应用停止时,有线程正在执行中,执行了一半,JVM进程就被干掉了。

4、应用启动时,服务还没准备好,就开始对外提供服务,导致很多失败调用。

5、应用启动时,没有检查应用的健康状态,就开始对外提供服务,导致很多失败调用。

以上,都是我们认为的不优雅的情况,那么,反过来,优雅上下线就是一种避免上述情况发生的手段。

一个应用的优雅上下线涉及到的内容其实有很多,从底层的操作系统、容器层面,到编程语言、框架层面,再到应用架构层面,涉及到的知识很广泛。

其实,优雅上下线中,最重要的还是优雅下线。因为如果下线过程不优雅的话,就会发生很多调用失败了、服务找不到等问题。所以很多时候,大家也会提优雅停机这样的概念。

本文后面介绍的优雅上下线也重点关注优雅停机的过程。

操作系统&容器的优雅上下线

关于操作系统,我之前有一篇文章专门介绍过这个话题,可能大家没有注意到,那时候介绍的主题是为什么不能在线上机器中随便执行kill -9。

其实,这背后的思考就是优雅上下线。

我们知道,kill -9之所以不建议使用,是因为kill -9特别强硬,系统会发出SIGKILL信号,他要求接收到该信号的程序应该立即结束运行,不能被阻塞或者忽略。

这个过程显然是不优雅的,因为应用立刻停止的话,就没办法做收尾动作。而更优雅的方式是kill -15

当使用kill -15时,系统会发送一个SIGTERM的信号给对应的程序。当程序接收到该信号后,具体要如何处理是自己可以决定的。

kill -15会通知到应用程序,这就是操作系统对于优雅上下线的最基本的支持。

以前,在操作系统之上就是应用程序了,但是,自从容器化技术推出之后,在操作系统和应用程序之间,多了一个容器层,而Docker、k8s等容器其实也是支持优雅上下线的。

如Docker中同样提供了两个命令, docker stopdocker kill

docker stop就像kill -15一样,他会向容器内的进程发送SIGTERM信号,在10S之后(可通过参数指定)再发送SIGKILL信号。

docker kill就像kill -9,直接发送SIGKILL信号。

JVM的优雅上下线

在操作系统、容器等对优雅上下线有了基本的支持之后,在接收到docker stopkill -15等命令后,会通知应用进程进行进程关闭。

而Java应用在运行时就是一个独立运行的进程,这个进程是如何关闭的呢?

Java程序的终止运行是基于JVM的关闭实现的,JVM关闭方式分为正常关闭、强制关闭和异常关闭3种。

这其中,正常关闭就是支持优雅上下线的。正常关闭过程中,JVM可以做一些清理动作,比如删除临时文件。

当然,开发者也是可以自定义做一些额外的事情的,比如通知应用框架优雅上下线操作。

而这种机制是通过JDK中提供的shutdown hook实现的。JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子。

例子如下:

package com.hollis;public class ShutdownHookTest {public static void main(String[] args) {boolean flag = true;Runtime.getRuntime().addShutdownHook(new Thread(() -> {System.out.println("hook execute...");}));while (flag) {// app is runing}System.out.println("main thread execute end...");}
}

执行命令:

➜ jps
6520 ShutdownHookTest
6521 Jps
➜ kill 6520

控制台输出内容:

hook execute...
Process finished with exit code 143 (interrupted by signal 15: SIGTERM)

可以看到,当我们使用kill(默认kill -15)关闭进程的时候,程序会先执行我注册的shutdownHook,然后再退出,并且会给出一个提示:interrupted by signal 15: SIGTERM

Spring的优雅上下线

有了JVM提供的shutdown hook之后,很多框架都可以通过这个机制来做优雅下线的支持。

比如Spring,他就会向JVM注册一个shutdown hook,在接收到关闭通知的时候,进行bean的销毁,容器的销毁处理等操作。

同时,作为一个成熟的框架,Spring也提供了事件机制,可以借助这个机制实现更多的优雅上下线功能。

ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制。

开发者可以实现ApplicationListener接口,监听到 Spring 容器的关闭事件(ContextClosedEvent),来做一些特殊的处理:

@Component
public class MyListener implements ApplicationListener<ContextClosedEvent> {@Overridepublic void onApplicationEvent(ContextClosedEvent event) {// 做容器关闭之前的清理工作}}

Dubbo的优雅上下线

因为Spring中提供了ApplicationListener接口,帮助我们来监听容器关闭事件,那么,很多web容器、框架等就可以借助这个机制来做自己的优雅上下线操作。

如tomcat、dubbo等都是这么做的。

这里简答说一下Dubbo的,在Dubbo的官网中,有关于优雅停机的介绍:

应用在停机时,接收到关闭通知时,会先把自己标记为不接受(发起)新请求,然后再等待10s(默认是10秒)的时候,等执行中的线程执行完。

那么,之所以他能做这些事,是因为从操作系统、到JVM、到Spring等都对优雅停机做了很好的支持。

关于Dubbo各个版本中具体是如何借助JVM的shutdown hook机制、或者说Spring的事件机制昨的优雅停机,我的一位同事的一篇文章介绍的很清晰,大家可以看下:

https://www.cnkirito.moe/dubbo-gracefully-shutdown/

在从Dubbo 2.5 到 Dubbo 2.7介绍了历史版本中,Dubbo为了解决优雅上下线问题所遇到的问题和方案。

目前,Dubbo中实现方式如下,同样是用到了Spring的事件机制:

public class SpringExtensionFactory implements ExtensionFactory {public static void addApplicationContext(ApplicationContext context) {CONTEXTS.add(context);if (context instanceof ConfigurableApplicationContext) {((ConfigurableApplicationContext) context).registerShutdownHook();DubboShutdownHook.getDubboShutdownHook().unregister();}BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER);}
}

总结

本文从操作系统开始,分别介绍了Linux、Docker、JVM、Spring、Dubbo等对优雅停机的支持。

可以看到,一个简单的优雅停机功能,上下游需要这么多底层基础设施和上层应用的支持。

相信通过学习本文,你一定对优雅上下线有了更多的了解。

除此之外,我还希望你,通过本文以后,遇到一些实际问题的时候,可以想到文中提到的shutdown hook机制、Spring的event机制。很多时候,这些机制都能帮助我们解决很多问题。

我在工作中,就有很多次使用过这样的机制的实例,后面有机会给大家介绍几个实例。

参考 :

https://zhuanlan.zhihu.com/p/29093407

https://www.cnkirito.moe/dubbo-gracefully-shutdown/

面试官:你知道Dubbo怎么做优雅上下线的吗?你:优雅上下线是啥?相关推荐

  1. 【分享】面试官:简单表述怎么做接口测试

    其实我感觉如果面试官如果问这个问题,他更想考察的是你是不是知道大概的操作流程,用个接口测试工具套下面的流程就好了,我这里拿Eolinker来举例. 1)看接口文档,看看接口的定义,看看是http协议还 ...

  2. dubbo原理和机制_面试官几个 Dubbo 微服务框架问题,把我整懵了?

    Dubbo本身并不复杂,而且官方文档写的非常清楚详细,面试中dubbo的问题一般不会很多,从分层到工作原理.负载均衡策略.容错机制.SPI机制基本就差不多了,最大的一道大题一般就是怎么设计一个RPC框 ...

  3. 面试官:“同学,你做过真实落地项目吗?”​

    今年受疫情影响,大部分企业对应届生的招聘需求直线下降,随着毕业季的到来,很多同学还没来得及憧憬未来,就成了待业人群,说「失业」也不为过. #2020应届生求职太难了# 相比平时,企业招聘明显更加谨慎, ...

  4. (最全laravel面试必备)面试官问:你对laravel 框架了解多少,为什么说是优雅的框架?

    下面是自己的一些总结,面试的时候可以适用回答. laravel 框架的特点和优秀是集合了php语言的特点,和很多的设计模式.loc模式.依赖注入形成了自己的特定特性. 第一点:Laravel 的亮点 ...

  5. 面试官:你在工作做遇到过什么难以解决的bug或者技术难题,说说你是什么解决的?

    雪花算法long型数据精度丢失 mybatis的xml文件中 ·· 符号的运用.type关键字

  6. 面试官:Mysql 中主库跑太快,从库追不上怎么整?

    作者|莱乌 写这篇文章是因为之前有一次删库操作,需要进行批量删除数据,当时没有控制好删除速度,导致产生了主从延迟,出现了一点小事故. 今天我们就来看看为什么会产生主从延迟以及主从延迟如何处理等相关问题 ...

  7. java面试中mysql_面试官:Mysql 中主库跑太快,从库追不上怎么整?

    作者|莱乌 写这篇文章是因为之前有一次删库操作,需要进行批量删除数据,当时没有控制好删除速度,导致产生了主从延迟,出现了一点小事故. 今天我们就来看看为什么会产生主从延迟以及主从延迟如何处理等相关问题 ...

  8. mysql读数据为什么快_面试官:Mysql 中主库跑太快,从库追不上怎么整?

    图注:思维导图 主从常见架构 随着日益增长的访问量,单台数据库的应接能力已经捉襟见肘.因此采用主库写数据,从库读数据这种将读写分离开的主从架构便随之衍生了出来. 在生产环境中,常见的主从架构有很多种, ...

  9. 某程序员吐槽:面试时题做得又快又好,却被面试官挂掉,就因为不承认刷题!...

    为了通过面试,许多人都会大量刷题,但把题都做出来,面试就一定能通过吗? 也未必,一位程序员就因为题做得太好太快,被面试官给挂了-- 他的故事是这样的:面试mid算法题,直接bugfree(无缺陷),面 ...

  10. 刷道谷歌泄漏的面试题:面试官想从中考察你什么?

    这是"谷歌面试题解析"系列的又一篇文章.在这一系列文章中,我介绍了谷歌面试当中经常用到的一些面试题,不过这些面试题已经被泄露,并禁止在面试中使用.不过,我的损失就是你的收获,因为它 ...

最新文章

  1. Gym - 102082G
  2. function 多个函数用一个_一列转多行多列,用INDIRECT函数,给你一个可套用的公式模板...
  3. 神经网络架构搜索_神经网络架构
  4. 用户体验改善案例_优化用户体验案例研究的五种方法
  5. Django实战(6):对比RoR和Django的模板系统
  6. SDI在自定义的工具栏上添加下拉控件
  7. Java之Socket实现文件传输
  8. 用USBOOT软件修复U盘
  9. t分布 u分布 卡方分布_t分布曲线和正太分布,和z分布,和卡方分布,和方差分析的f分布曲线有什么区别?...
  10. 图片怎么转化word文档?分享一个实用的方法。
  11. 30年的Hello world
  12. 比MySQL快839倍!揭开分析型数据库JCHDB的神秘面纱
  13. 计算机机房学生上机制度,学生上机管理制度
  14. 【概率论与数理统计】猴博士 笔记 p29-32 均匀分布、泊松分布、指数分布、几何分布
  15. SouthernBiotech Annexin V染色方案
  16. python中的zip()方法
  17. jmeter怎么读(jmeter怎么读)
  18. Knoppix Bug
  19. JS逆向steam登录
  20. Hulu新剧预告|女版乔布斯上演《辍学生》

热门文章

  1. dgi数据治理_银行数据治理方法浅析
  2. 诛仙哪里炼器服务器最稳定,告别炼器难 《诛仙2》顶级炼器师云集诛仙电台
  3. HTTP 协议中GET和POST到底有哪些区别
  4. Polkit权限提升漏洞(CVE-2021-4034)利用及修复
  5. 手机上流行的各类谜语(大揭密)
  6. LAMP[Discuz论坛]
  7. 递归方法 求4的阶乘
  8. 什么样的工作轻松又赚钱?真的有这样的工作吗?
  9. 【CCF】公共钥匙盒
  10. DTO DAO VO BO PO POJO区别