ShutdownHook介绍 在java程序中,很容易在进程结束时添加一个钩子,即ShutdownHook。...ShutdownHook的能力,如dubbo、spring等。...ShutdownHook原理 ShutdownHook的数据结构与执行顺序 当我们添加一个ShutdownHook时,会调用ApplicationShutdownHooks.add(hook),往ApplicationShutdownHooks...,并且系统级的ShutdownHook由一个数组构成,只能添加10个 系统级的ShutdownHook调用了thread类的run方法,所以系统级的ShutdownHook是同步有序执行的 private...总结 综上,我们得出一些结论 重写捕获信号需要注意主动退出进程,否则进程可能永远不会退出,捕获信号的执行是异步的 用户级的ShutdownHook是绑定在系统级的ShutdownHook之上,且用户级是异步执行
通过排查认后发现是在执行shutdownHook时死锁程序死锁。...} } 输出: Exiting Locking 原因 排查原因 分析一下 addShutdownHook 这个方法是怎么执行的,重点是 ApplicationShutdownHooks,每一个 shutdownHook...方法是:WAIT 状态 Thread-0是:RUNNING 状态,但是进入synchronized之后就会BLOCKED住 这里就对应上图的两个线程的状态 解决 即然已经知道原因了,那就好办: 移除 shutdownHook...中不必要的加锁,shutdown 场景中很不需要用到加锁 使用不同的加锁对象,如果一定需要加锁,可以在 shutdownHook 的线程内使用一把新的锁,这样即可以保证安全性,又不会死锁。
上期文章分享了ShutdownHook的API和基本使用,但是少了一些实际工作中的案例,总感觉没啥大用一样。 最近总结工作中可以用到ShutdownHook来解决一些实际问题的例子,分享给大家。...如果你想使用一种优雅的方法完成这个任务的话,那么ShutdownHook绝对是不二选择。...static { Runtime.getRuntime().addShutdownHook(new Thread(() -> closeScanner())); } 释放连接 ShutdownHook...PS:到这里,当我们需要添加超过1个ShutdownHook的时候,就可以非常明显地感受到daemon线程实现方案的差异,因为ShutdownHook可以到处写,多点开花。...一旦遇到异常,ShutdownHook中的方法会把已经创建好的用户ID存在文件中。每次执行,已创建好的用户ID集合会从文件中进行初始化。
序 本文主要研究一下logback的ShutdownHook ShutdownHook ch/qos/logback/core/hook/ShutdownHook.java /** * Interface...describing a logback shutdown hook implementation * * @author Mike Reinhold */ public interface ShutdownHook...extends Runnable, ContextAware { } ShutdownHook接口继承了Runnable、ContextAware接口 ShutdownHookBase ch/qos.../logback/core/hook/ShutdownHookBase.java /** * Base class for classes implementing a Logback ShutdownHook...class="ch.qos.logback.core.hook.DelayingShutdownHook"> 10
序本文主要研究一下logback的ShutdownHookShutdownHookch/qos/logback/core/hook/ShutdownHook.java/** * Interface describing...a logback shutdown hook implementation * * @author Mike Reinhold */public interface ShutdownHook extends...Runnable, ContextAware {}ShutdownHook接口继承了Runnable、ContextAware接口ShutdownHookBasech/qos/logback/core.../hook/ShutdownHookBase.java/** * Base class for classes implementing a Logback ShutdownHook via extension...class="ch.qos.logback.core.hook.DelayingShutdownHook"> 10
如果基于Java开发,往往采用ShutDownHook去做这件事情。...比如我们在tomcat关闭时,注册ServletContextListener,在上下文销毁时,进行ShutDownHook调用。...ServletContextEvent sce) { } @Override public void contextDestroyed(ServletContextEvent sce) { ShutDownHook.runHook...public class ShutDownHook extends Thread 我们清理的目标是一个集合对象: private ArrayList resourceList...比如我们在类中创建定时执行线程池,我们可以把这个线程池注册到我们要回收的集合中: ShutDownHook.registerShutdownHook(new Closable() {
Java程序中可以通过添加关闭钩子,实现在程序退出时关闭资源、平滑退出的功能。 同理关闭钩子是removeShutdownHook 使用Runtime.ad...
ps: 仔细品味,优雅停机这个词真好~ ShutdownHook Java 语言提供一种 ShutdownHook(钩子)进制,当 JVM 接受到系统的关闭通知之后,调用 ShutdownHook...但是需要注意的是,多个 ShutdownHook 之间并无任何顺序,Java 并不会按照加入顺序执行,反而将会并发执行。 所以尽量在一个 ShutdownHook 完成所有操作。...ShutdownHook 需要尽快执行结束 不要在 ShutdownHook 执行需要被阻塞代码,如 I/0 读写,这样就会导致应用短时间不能被关闭。...如果等待一定时间之后,ShutdownHook 还未完成,由脚本直接调用 kill -9 强制退出或者 ShutdownHook 代码中引入超时进制。...文章首发于studyidea.cn/shutdownHook
ps: 仔细品味,优雅停机这个词真好~ ShutdownHook# Java 语言提供一种 ShutdownHook(钩子)进制,当 JVM 接受到系统的关闭通知之后,调用 ShutdownHook 内的方法...但是需要注意的是,多个 ShutdownHook 之间并无任何顺序,Java 并不会按照加入顺序执行,反而将会并发执行。 所以尽量在一个 ShutdownHook 完成所有操作。...ShutdownHook 需要尽快执行结束 不要在 ShutdownHook 执行需要被阻塞代码,如 I/0 读写,这样就会导致应用短时间不能被关闭。...为了避免 ShutdownHook 线程被长时间阻塞,我们可以引入超时进制。...如果等待一定时间之后,ShutdownHook 还未完成,由脚本直接调用 kill -9 强制退出或者 ShutdownHook 代码中引入超时进制。
步骤 注册ShutdownHook: 在Java中,可以通过Runtime类的addShutdownHook(Thread hook)方法来注册ShutdownHook。...: 注册的ShutdownHook会按照注册的顺序依次执行。...但是不能保证所有的ShutdownHook都会被执行,因为在某些情况下,比如JVM崩溃,kill -9可能无法正常执行ShutdownHook。...注意事项 使用Java的ShutdownHook(注册在JVM层面的钩子)进行应用的优雅退出时,有几个重要的注意事项: ShutdownHook的执行不确定性:ShutdownHook并非在所有情况下都会被...ShutdownHook的执行顺序:JVM不保证ShutdownHook的执行顺序,如果在一个应用中注册了多个ShutdownHook,它们可能不会按照添加的顺序执行,因此不应该在ShutdownHook
(interrupted by signal 2: SIGINT) 加了优雅停机配置后,可明显发现的日志 Waiting for active requests to cpmplete,此时容器将在ShutdownHook...这样才会触发java内部ShutdownHook操作,kill -9不会触发ShutdownHook。 2、可以使用端点监控 POST 请求 /actuator/shutdown 来执行优雅关机。...添加ShutdownHook 通过上面的日志我们发现Druid执行了自己的ShutdownHook,那么我们也来添加下ShutdownHook,有几种简单的方式: 1、实现DisposableBean接口...if (this.shutdownHook !...= null) { try { Runtime.getRuntime().removeShutdownHook(this.shutdownHook); } catch
Graceful shutdown complete 接口请求执行完成 相关知识 1.关于此处执行kill -2 而不是 kill -9 kill -2 相当于快捷键 Ctrl + C 会触发 Java 的 ShutdownHook...this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) { @Override...} } }; Runtime.getRuntime().addShutdownHook(this.shutdownHook...); } } kill -9,暴力美学强制杀死进程,不会执行 ShutdownHook 2.通过 actuate 端点实现优雅停机 POST 请求 /actuator/shutdown...InterruptedException ex) { Thread.currentThread().interrupt(); } // 此处close 逻辑和上边 shutdownhook
Runtime.getRuntime().addShutdownHook(new Thread(){ @Override public void run() { System.out.println("do ShutdownHook...aProject/web/target$ kill 21470 lgj@lgj-Lenovo-G470:~/aProject/web/target$ 可以看到输出日志中输出了钩子函数中所打印的 do ShutdownHook...main] com.demo.web.WebApplication : Started WebApplication in 4.585 seconds (JVM running for 5.274) do ShutdownHook...2.kill pid 也就是kill -15 pid ,将会调用钩子函数ShutdownHook,一般ShutdownHook中会进行一些操作,比如保存数据,关闭连接等。...3.kill -9 pid.不会调用钩子函数ShutdownHook。
Graceful shutdown complete 4、接口请求执行完成 相关知识 关于此处执行kill -2 而不是 kill -9 kill -2 相当于快捷键 Ctrl + C 会触发 Java 的 ShutdownHook...优雅停机或者一些后置处理可参考以下源码) //ApplicationContext @Override public void registerShutdownHook() { if (this.shutdownHook...this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) { @Override public void run() {...); } } kill -9,暴力美学强制杀死进程,不会执行 ShutdownHook 通过 actuate 端点实现优雅停机 POST 请求 /actuator/shutdown 即可执行优雅关机...catch (InterruptedException ex) { Thread.currentThread().interrupt(); } // 此处close 逻辑和上边 shutdownhook
Graceful shutdown complete 接口请求执行完成 相关知识 关于此处执行kill -2 而不是 kill -9 kill -2 相当于快捷键 Ctrl + C 会触发 Java 的 ShutdownHook...优雅停机或者一些后置处理可参考以下源码) //ApplicationContext @Override public void registerShutdownHook() { if (this.shutdownHook...this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) { @Override public void run() {...); } } kill -9,暴力美学强制杀死进程,不会执行 ShutdownHook 通过 actuate 端点实现优雅停机 POST 请求 /actuator/shutdown 即可执行优雅关机...catch (InterruptedException ex) { Thread.currentThread().interrupt(); } // 此处close 逻辑和上边 shutdownhook
问题排查 怀疑ShutdownHook 由于这几天研究过ShutdownHook(见文末《ShutdownHook原理》),第一时间怀疑ShutdownHook可能有问题。...dubbo 2.7.3代码有关ShutdownHook的实现在DubboShutdownHook类,顺着代码梳理出如下关系 [h4ionf0ot6.png?...,更加怀疑这里是不是ShutdownHook注册重复了。...于是debug看看是否是注册重复了,这里给一个小经验,IntelliIDEA调试ShutdownHook执行时,要手动kill进程才会触发debug,点IDE上的关闭按钮不会触发 [aniy8w8alx.png...,但如果用到了spring框架,spring框架在初始化时注销了dubbo注册的ShutdownHook,这样就只保留了spring的ShutdownHook,真是秒啊!
. */ public boolean removeShutdownHook() { if (this.shutdownHook !...= this.shutdownHook) { Thread sdh = this.shutdownHook; this.shutdownHook = null...= null) { return; } this.shutdownHook = new Thread(this::shutdownFromJVM)...; Runtime.getRuntime().addShutdownHook(this.shutdownHook); } protected void shutdownFromJVM...extends NettyContext>,在它会在完成的时候,自己dispose nettyContext;blocking的话,startAndAwait方法会自动帮你注册shutdownHook来
每次都是本能执行如下步骤 jps kill -9 reboot 有一次发现代码中添加的 ShutdownHook没有生效,难道和 kill命令后面的数字有关?...Thread(){ @Override public void run() { System.out.println("do ShutdownHook...kill -9很暴力,不会调用钩子函数ShutdownHook。...kill也就是kill -15很柔和,将会调用钩子函数ShutdownHook,一般ShutdownHook中会进行一些操作,比如保存数据,关闭连接等。
关闭命令方面,一定要杜绝 kill -9 操作 多线程采用线程池实现,保证每个异步线程都可以随Spring的生命周期完成正常关闭操作 有服务注册与发现机制下的时候,通过Spring的应用关闭事件、Java应用的ShutdownHook...优雅停机或者一些后置处理可参考以下源码) //ApplicationContext @Override public void registerShutdownHook() { if (this.shutdownHook...this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) { @Override public void run() {...); } } kill -9,暴力美学强制杀死进程,不会执行 ShutdownHook 通过 actuate 端点实现优雅停机 POST 请求 /actuator/shutdown 即可执行优雅关机...catch (InterruptedException ex) { Thread.currentThread().interrupt(); } // 此处close 逻辑和上边 shutdownhook
领取专属 10元无门槛券
手把手带您无忧上云