城市直播房产教育博客汽车
快传网
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

不懂优雅停机,搞挂了线上服务该咋办?

9月13日 栀璃鸢投稿
  公司项目是用consul进行注册的,在发布微服务的时候,总是会导致调用方出现一定几率的调用失败。一开始百思不得其解,后来咨询了资深的同事才知道:原来是服务下线的时候没有优雅停机,没有去consul将自己下线再停机,导致调用方拿到了旧的调用地址,导致调用失败!看来优雅停机还是一个蛮重要的知识点,可不能忽略,今天就让我们来盘盘它吧!
  一、什么是优雅停机?
  在Linux世界里,一切都是资源。当我们启动一个JVM的时候,我们就加载了许多的资源。而当我们关闭JVM的时候,JVM只会释放内存这个资源,而其他资源是不会释放的,例如:网络连接、文件句柄等等。
  Linux的网络连接数、文件句柄数都是有限的,如果我们没有及时释放,时间久了就会导致一些奇怪的问题。那么如何在JVM关闭的时候,释放这些资源呢?答案就是:利用Java提供的ShutdownHook接口。我们所说的优雅停机,就是利用Java提供的ShutdownHook接口注册一个钩子,让JVM在关闭之前执行钩子函数的代码,让其关闭对应的资源。
  二、适用场景
  在学会怎么使用优雅停机之前,我们需要弄清楚优雅停机适用于哪些场景,那我们就需要先弄清楚JVM关闭的几种情况了。JVM关闭的情况可以分为3大类11个情况,如下图所示:
  JVM关闭的场景
  在JVM关闭的3大类场景中,只有正常关闭与异常关闭是支持优雅停机的,而强制关闭则是不支持的。下面我们通过三个例子来验证一下。
  1、JVM正常关闭
  JVM正常关闭这种情况,我们只需要正常运行一个main函数,然后为其注册一个ShutdownHook即可,其代码如下所示。publicclassNormalShutdownTest{publicvoidstart(){Runtime。getRuntime()。addShutdownHook(newThread(()System。out。println(钩子函数被执行,可以在这里关闭资源。)));}publicstaticvoidmain(String〔〕args){newNormalShutdownTest()。start();System。out。println(主应用程序在执行,正常关闭。);}}
  输出结果为:主应用程序在执行,正常关闭。钩子函数被执行,可以在这里关闭资源。
  可以看到钩子函数的代码正常执行了。如果你在main函数增加System。exit(0)代码,执行之后的结果也还是一样。这说明JVM正常关闭情况下,是支持优雅停机的。
  2、异常关闭
  JVM异常关闭这种情况,我们尝试制造内存溢出。只需要声明一个500MB的数组,然后设置JVM堆最大为20MB即可(Xmx20M),其代码如下所示。publicclassOomShutdownTest{publicvoidstart(){Runtime。getRuntime()。addShutdownHook(newThread(()System。out。println(钩子函数被执行,可以在这里关闭资源)));}publicstaticvoidmain(String〔〕args)throwsException{newOomShutdownTest()。start();System。out。println(主应用程序在执行,内存溢出关闭。);byte〔〕bnewbyte〔50010241024〕;}}
  执行结果为:主应用程序在执行,内存溢出关闭。Exceptioninthreadmainjava。lang。OutOfMemoryError:Javaheapspaceattech。shuyi。javacodechip。shutdownhook。OomShutdownTest。main(OomShutdownTest。java:13)钩子函数被执行,可以在这里关闭资源
  可以看到JVM抛出了OOM错误,但是钩子函数还是被执行了。如果你在main函数中自行抛出RuntimeException,钩子函数也还是会被执行。感兴趣的朋友可以自行尝试一下。
  3、强制关闭
  JVM强制关闭这种情况,我们可以使用Runtime。getRuntime()。halt(1)进行测试,其代码如下所示。publicclassForceShutdownTest{publicvoidstart(){Runtime。getRuntime()。addShutdownHook(newThread(()System。out。println(钩子函数被执行,可以在这里关闭资源。)));}publicstaticvoidmain(String〔〕args)throwsException{newForceShutdownTest()。start();System。out。println(主应用程序在执行,强制关闭。);Runtime。getRuntime()。halt(1);}}
  执行结果:主应用程序在执行,强制关闭。
  可以看到钩子函数并没有被执行,所以JVM强制关闭这种场景不支持优雅停机。
  三、最佳实践
  看了上面的例子,看起来优雅停机没那么复杂嘛。实际上,优雅停机用不好,很可能出现一些其他问题。这里给出几个最佳实践原则,帮助大家用好优雅停机!
  1、只注册一个钩子
  我们都知道JVM可以注册多个钩子,而钩子本质上是一个线程,可以并发执行。那么就很可能出现钩子之间相互依赖,这样就会导致依赖死锁了。另外,也可能因为多个钩子操作同一个资源,导致资源竞争出现死锁。因此,较好的一种方式就是只注册一个钩子,所有的资源释放都在这个钩子中操作。
  2、确保线程安全
  因为钩子本质上也是一个线程,JVM可能会并发执行多个钩子,JVM并不保证它们的执行顺序,因此需要保证钩子中的操作是线程安全的。当然了,如果你只有一个钩子的话,那这个提示可以忽略了。
  3、不要做耗时的操作
  在钩子中,不要做耗时的操作。因为当我们要关闭JVM时,用户肯定是希望尽快关闭,因此钩子中主要用于关闭残留资源,不应该再做其他耗时的操作。
  4、不要做注册、移除钩子的操作
  在关闭钩子中,不能执行注册、移除钩子的操作,否则JVM抛出IllegalStateException。
  5、不要调用System。exit()操作
  也不能调用System。exit()操作,但是调用Runtime。halt()操作是可以的。我想,这是因为调用System。exit()操作会导致循环进入钩子,导致死循环吧。
  6、需要考虑的资源
  除了上面一些代码上的操作需要考虑,我们还需要注意下面这些场景的处理:池化资源的释放:数据库连接池、HTTP连接池、线程池。在处理线程的释放:已经被连接的HTTP请求。MQ消费者的处理:正在处理的消息。隐形受影响的资源的处理:Zookeeper、Nacos实例下线等。
  四、应用案例
  Java提供的优雅停机机制,可以说是许多框架的基础。诸如Spring、Consul等中间件框架,都是利用Java提供的这个机制进行优雅停机的。
  1、Spring的优雅停机
  例如Spring是基于Java语言开发的框架,那其也势必依赖于JVM的ShutdownHook。Spring关于优雅停机的代码在org。springframework。context。support。AbstractApplicationContextregisterShutdownHook处,代码如下图所示。OverridepublicvoidregisterShutdownHook(){if(this。shutdownHooknull){Noshutdownhookregisteredyet。this。shutdownHooknewThread(SHUTDOWNHOOKTHREADNAME){Overridepublicvoidrun(){synchronized(startupShutdownMonitor){doClose();}}};增加ShutdownHook钩子Runtime。getRuntime()。addShutdownHook(this。shutdownHook);}}
  可以看到Spring在registerShutdownHook()函数里,注册了一个关闭的钩子,钩子中调用了doClose()方法。
  2、服务治理的优雅停机
  不论是Dubbo还是SpringCloud的分布式服务框架,需要关注的是怎么能在服务停止前,先将提供者在注册中心进行反注册,然后在停止服务提供者,这样才能保证业务系统不会产生各种503、timeout等现象。为了实现上述说到的效果,那么我们就必须关注优雅停机这件事情。
  彩蛋
  我们都知道通过kill15可以让JVM优雅停机,那我们是否可以监听特定的信号量,从而让程序做特定的操作呢?例如:让JVM监听第12信号量,然后打印一条日志,随后优雅停机。
  答案是当然可以啦!我们只需要利用Signal类,并实现一个SignHandler类就可以了。其实现代码如下所示:publicclassCustomShutdownTest{publicvoidstart(){Runtime。getRuntime()。addShutdownHook(newThread(()System。out。println(钩子函数被执行,可以在这里关闭资源。)));}publicstaticvoidmain(String〔〕args){customsignalkillSignalsgnewSignal(USR2);kill12pidSignal。handle(sg,newSignalHandler(){Overridepublicvoidhandle(Signalsignal){System。out。println(接收到信号量:signal。getName());监听信号量,通过System。exit(0)正常关闭JVM,触发关闭钩子执行收尾工作System。exit(0);}});otherlogicnewCustomShutdownTest()。start();System。out。println(主应用程序在执行,正常关闭。);try{Thread。sleep(30000);}catch(InterruptedExceptione){e。printStackTrace();}}}
  我们启动该类后,先让其休眠30秒,随后用jps命令找到进程ID,随后运行killUSR2PID即可,如截图所示。
  随后可以看到控制台打印出如下消息:主应用程序在执行,正常关闭。接收到信号量:USR2钩子函数被执行,可以在这里关闭资源。
  从上面消息我们知道,JVM成功接收到了USR2信号量,也成功执行了钩子函数。搞定!
  提示:其实USR2是Linux第12个信号量,是留给用户使用的一个信号量。我们可以通过该信号量做一些定制化操作,从而实现更加复杂的功能。
  好了,本期就先分享到这里,关注我下次见
投诉 评论 转载

作业帮学习手表X9,助力孩子高效学习千盼万盼,神兽终于回归校园了,终于等到孩子要开学的爸妈们已经快憋不住笑了吧,所以开学礼物也准备起来咯,什么样的礼物让孩子爱不释手,爸爸妈妈又可以放心呢?爸妈的心思总在孩子的学习……奥运冠军罕见晒全家福!37岁再婚生女,赛场成就高两度执教均下近日,国羽奥运冠军张宁罕见地晒出了全家福,并且在5月20日和5月21日连续两天更新社交平台,晒出了与父母、女儿以及老公的合影,这也是张宁与丈夫李昂结婚后首度晒出家庭合影。照片虽……力挺弟子!吴金贵扬科维奇不用刘若钒是损失抗衡日韩需代代努力本赛季,上海申花取得6胜4平1负的战绩,积22分排名中超第四位。在接受采访时候,申花主帅吴金贵谈到了中国足球的相关话题,称自己非常欣赏刘若钒,国足选拔队不用刘若钒是扬科维奇的损……汽车软件行业研究智驾软件率先爆发,座舱软件紧随其后(报告出品方作者:浙商证券,程兵)1、汽车智能化时代来临,软件市场乘风起势1。1、域架构的引入弥补智能汽车等级进阶的关键一环分布式架构阻碍汽车智能化升级:传统的汽车……不懂优雅停机,搞挂了线上服务该咋办?公司项目是用consul进行注册的,在发布微服务的时候,总是会导致调用方出现一定几率的调用失败。一开始百思不得其解,后来咨询了资深的同事才知道:原来是服务下线的时候没有优雅停机……vivoS15Pro性能实测,王者荣耀和平精英轻松跑满帧率自从2019年推出首款机型至今,vivoS系列的累计销量已经接近3000万。换句话来说,每年大约有1000万用户,选择了vivoS系列手机。那么vivoS系列到底有着怎样……54岁周海媚和54岁李若彤,一个水嫩如少女一个干瘪吓人在娱乐圈中,很多女明星的保养都是出了名的,甚至当同龄的素人与明星们站在一起,差距都非常的大,作为明星,首先工作比较轻松,赚钱也很多,这些都足以维持她们好的生活,不需要发愁,也不……拒24分逆转!约基奇276穆雷122,7人得分上双,湖人送你北京时间10月20日爵士主场对阵掘金,全场比赛结束爵士以123102成功击败了掘金。本赛季的掘金是备受瞩目,毕竟本赛季的掘金引援到了波普不说,更重要的是穆雷和波特的回归让掘金实……昨夜今晨全球大公司动态中国恒大行政总裁夏海钧辞职。阿斯麦警告向中国停售设备将威胁半导体供应链。投资者预计半导体行业将会走下坡路。大众集团CEO迪斯意外提前离职。德国政府150亿欧元救助能源巨头Uni……三伏贴脾胃调理周天灸,升阳理气肚腹通任督二脉,即指周天之意义,人体前为任脉,为阴,为经气下降之意。后为督脉,为阳,为经气上升之意,身中之气,前降后升,经气周流,即为一个周天,但身中之气,无时无刻,均在升降。阳气不……震撼比银河系大20倍!中国天眼新发现近日,中国科学院国家天文台利用中国天眼FAST对致密星系群斯蒂芬五重星系及周围天区的氢原子气体进行了成像观测发现了1个尺度大约为200万光年……6月,一波新店打卡进入六月,夏天的日光,睁开眼就已经悄悄爬上楼房,也透过斑驳的树影零星洒下,阳光烘烤过的泥土气蒸腾,墙面、窗台、生活的每一个缝隙,都安插阳光留下的印记。没有调休的假期才是真……
我的爱,都在时光里学生党购机清单价格不贵体验极佳分身跨年晚会,歌手本尊只在江苏卫视,直播和录播立见高下末伏吃5宝,入秋身体好,进入伏末,建议多吃5宝,秋冬少受苦适合打工者用的宇通经济型房车!空间大,用途多,日常吃住很简单男人过了60岁,该如何生活?两个男人说出心里话1500元价位手机推荐,高性能长续航,这4款闭眼入手无路可退,广东宏远赢球收噩耗,季后赛奇兵或伤退,杜锋如何应对女人们听我的,今年早春流行穿鲨鱼裤,时髦百搭,还特显身材离婚还是亲人!李小璐贾乃亮和好,佟丽娅陈思诚家庭地位发生转变气传导和骨传导的区别,SANAG塞那气传导运动耳机开箱中国制造的成就,高新技术出口连续17年居全球第一,占比持续上
小米手机图案密码解锁忘了怎么办男人的精子形成后到底储存在哪里我叫神舟号苏教版语文教学反思范文天秤座男人配射手坐才是绝配(金牛座和射手座配吗)当小三还这么理直气壮?职场大拦路虎你有几个久保田万寿清酒怎么样日常大牌口红颜色推荐(10款日常口红推荐)最好的情人节礼物哺乳期妈妈的自我修养这些东西少去吃哦李克用有几个弟弟唐代名将李克用弟弟的简介古诗词名句赞美长江

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找江西南阳嘉兴昆明铜陵滨州广东西昌常德梅州兰州阳江运城金华广西萍乡大理重庆诸暨泉州安庆南充武汉辽宁