Java钩子函数的应用

本文介绍了如何利用Java的Hook机制在服务关闭时自动注销Nacos中的服务注册信息。通过Runtime的addShutdownHook方法添加钩子函数,在JVM关闭前执行注销操作,确保服务信息的准确性和系统稳定性。
摘要由CSDN通过智能技术生成

在自研RPC的框架中实现了服务的自动注册和发现,但是当你启动服务端后再把服务端关闭,Nacos中注册的服务信息并不会自动注销,这样就会导致客户端向Nacos请求服务时会获取已经关闭的服务端信息,最终导致连接不到服务器而调用失败。

那么就需要一种办法,在服务端关闭之前自动向 Nacos 注销服务。但是有一个问题,不知道什么时候服务器会关闭,也就不知道这个方法调用的时机,就没有办法手工去调用。这时,我们就需要钩子,由此引出本文。

Hook概念

Hook翻译成中文就是钩子的意思,在java中它表示在事件到达终点前进行监控和拦截的一种行为,Java提供注册钩子线程,在JVM进程关闭之前,会自动执行这个钩子线程。

应用场景

  • 应用程序正常退出,在退出时执行特定的业务逻辑,或者关闭资源等操作。
  • 虚拟机非正常退出,比如用户按下ctrl+c、OutofMemory宕机、操作系统关闭等。在退出时执行必要的挽救措施。

Hook基本用法

这个功能利用Runtime类实现,例子代码

public class HookTest {
    public static void main(String args[]){
        System.out.println("程序开始执行");
        try{
            Thread.sleep(100);
        }
        catch(Exception ex){
        }

        Runtime.getRuntime().addShutdownHook(new Thread(){
            @Override
            public void run() {
                System.out.println("执行钩子函数");
            }
        });

        System.out.println("程序执行完毕,退出main");
    }
}

运行结果:

程序开始执行
程序执行完毕,退出main
执行钩子函数

项目解决方法

利用钩子函数的特性,可以把项目中注销服务的方法写到关闭系统的钩子方法就可以了。

新建一个类,ShutdownHook:

public class ShutdownHook {

    private final ExecutorService threadPool = ThreadPoolFactory.createDefaultThreadPool("shutdown-hook");
    private static final ShutdownHook shutdownHook = new ShutdownHook();

    public static ShutdownHook getShutdownHook() {
        return shutdownHook;
    }

    public void addClearAllHook() {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            //服务注销函数
            NacosUtil.clearRegistry();
            threadPool.shutdown();
        }));
    }

}

使用了单例模式创建其对象,在 addClearAllHook 中,Runtime 对象是 JVM 虚拟机的运行时环境,调用其 addShutdownHook 方法增加一个钩子函数,创建一个新线程调用 clearRegistry 方法完成注销工作。这个钩子函数会在 JVM 关闭之前被调用。

这样在RpcServer启动之前只需要调用 addClearAllHook 就可以注册这个钩子了,启动服务端后再关闭,就会发现 Nacos 中的注册信息都被注销了。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值