Java程序优雅的退出

8 篇文章 1 订阅

背景

最近收到一个新需求,需要充kafka队列中那消息解析写到es中。要求不能漏写数据,或者重复写数据。‘

问题

如果程序中途需要手动停止,就需要把已经从kafka中拿到的数据,写进了es 才能停止程序。否则就会漏写数据或者重复写入数据

解决

钩子函数

ShutdownHook只是一个已初始化但为启动的线程。当JVM开始执行关闭序列时,它才开始已某种随机程序注册和并行执行shutdown hooks。

注意 这个对 kill -9 {pid} 无效,对 kill -15 及 Control +C 有效

  //注册钩子函数
  Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.info("开始停止任务");
            //停止标识位 为 true 停止从kafka 拿数据
            isStop = true;
            try {
            //阻塞 直到将已经拿到的数据处理完毕
                executorService.awaitTermination(1, TimeUnit.HOURS);
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("任务已经停止");
        }));

SignalHandler

实现sun.misc.SignalHandler 接口

public class SignalHandlerImp implements SignalHandler {

    public void handle(Signal signal) {
       //停止标识位 为 true 停止从kafka 拿数据
            isStop = true;
            try {
            //阻塞 直到将已经拿到的数据处理完毕
                executorService.awaitTermination(1, TimeUnit.HOURS);
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("任务已经停止");
        System.out.println(signal.getName()+":"+signal.getNumber());
    }

}

    	  // 注册要监听的信号
        SignalHandlerImp signalHandlerImp = new SignalHandlerImp();
        Signal.handle(new Signal("INT"), signalHandlerImp);// 2  : 中断(同 ctrl + c )
        Signal.handle(new Signal("TERM"), signalHandlerImp);// 15 : 正常终止
        Signal.handle(new Signal("USR2"), signalHandlerImp);// 12 : 用户自定义信号
  

总结

jvm 关闭的几种方式

jvm关闭

我们可以通过 钩子函数来 处理 正常关闭以及异常关闭的收尾工作。SignalHandler 只能处理正常关闭的收尾工作。所以钩子函数的应用要广泛一点的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值