Java 如何利用钩子函数实现优雅停服?刨根问底( 二 )


 
呜呼!结果不会骗人的,当用 kill -9 的时候,就显得很粗暴了,压根不管什么资源释放,不管三七二十一,就是终止程序 。
估计很多同学,都擅长用 kill -9 进行杀进程,为了线上的应用安全,还是用 kill -15 命令杀进程吧,这样会给应用留点时间去打扫一下战场,释放一下资源 。
好了,通过仔细品味,借助 JDK 自带的 addShutdownHook 来助力应用,确实能让线上服务跑起来很优雅 。
有思想才是硬道理!
2. addShutdownHook 的使用场景?通过代码试验,能够感知 addShutdownHook(new Thread(){}) 是 JVM 销毁前要执行的一个线程,那么只要是涉及到资源回收的场景,应该都可以满足,下面简单列举几个 。

a)数据同步神器 Canal 借助它,来进行关闭 socket 链接、释放 canal 的工作节点、清理缓存信息等;
 
b)海量日志收集 Flume 借助它,来实现线程池资源关闭、工作线程停止等;
 
c)在应用正常退出时,执行特定的业务逻辑、关闭资源等操作 。
 
d)在 OOM 宕机、 CTRL+C、或执行 kill pid,导致 JVM 非正常退出时,加入必要的挽救措施成为可能 。
其实,在 Java 的世界里遨游,只有想不到的,没有做不到的!
3. addShutdownHook 钩子函数是个啥?刨根还要问到底!
Java 如何利用钩子函数实现优雅停服?刨根问底

文章插图
 
Hook 翻译过来是「钩子」的意思,那顾名思义就是用来挂东西的 。
Java 如何利用钩子函数实现优雅停服?刨根问底

文章插图
 
如图所示,在现实生活中,要制作腊肉,首先用钩子把肉勾住,然后挂在竹竿上,这应该是钩子的作用 。
生活如此,一切设计理念都源于生活,在 Java 的世界里,亦是如此 。
Java 如何利用钩子函数实现优雅停服?刨根问底

文章插图
 
如上图 Runtime 的源码所示,遵循 Java 的核心思想「一切皆是对象」,那么可以把 addShutdownHook 方法可以视作挂钩子,其实称之为钩子函数会好一些,而现实生活中的肉就可以抽象为释放资源的线程 。
只要有这个钩子函数,对外就提供了扩展能力,研发人员就可以往钩子上挂各种自定义的场景实现,这种设计你细品那绝对是香!这也就是 Canal、Flume、Tomcat 等不同应用,在优雅停服时有着不同的实现的原因吧 。
大白话,钩子函数有了,想挂什么东西,根据心情自己定就好了 。
再深入去刨会发现,由于底层数据结构采用 Map 来进行存储,那么就支持研发人员挂多个 shutdownHook 的实现,又带来了无限的可能性(又带来了无限的「刺激」,自己好好去体会) 。
Java 如何利用钩子函数实现优雅停服?刨根问底

文章插图
 
好了,避免头大,就刨到这儿吧,感兴趣的可自行顺着思路继续刨下去 。
4. 寄语,写在最后作为研发人员:要拥有一双善于发现的眼睛,要善于发现代码之美 。
作为研发人员:要时常思考面对当前的项目,是否能够简单重构让程序跑的更顺溜 。
作为研发人员:要多看、多悟、多提炼、多实践 。
作为研发人员:请不要放弃代码,因为程序终会铸就人生 。
本次分享就到这里,希望对你有所帮助吧 。
一起聊技术、谈业务、喷架构,少走弯路,不踩大坑 。欢迎关注「一猿小讲」,会持续输出原创精彩分享,敬请期待!




推荐阅读