文章目录
- 场景
- 环境
- 正文
- SignalHandler类的编写
- SignalHandler类的绑定
- 执行脚本
- 说明
- 结果
- 参考链接
- 总结
- 随缘求赞
场景
最近,开发的程序是对kafka
进行消费,程序开发完毕之后,发现程序的终止一直都是很简单粗暴的kill -9 pid
,然后存在数据处理到一半,然后就被干掉,导致最后的结果数据只入了一半便不见了。所以,就这样产生了一个需求:当要结束程序的时候,告知程序要结束了,并等待一些资源的处理完毕和稀缺资源的安全释放。
环境
软件 | 版本 |
JDK | 8 |
Centos | 7.2 |
正文
接下来就进去实操环节了,请各位看官接着往下看。
SignalHandler类的编写
我们需要编写一个类来继承sun.misc.SignalHandler
,并编写接收到Signal
的时候,需要执行的步骤。接下来我展示一个样例代码:
@Slf4j
public class MqKillHandler implements SignalHandler {
private ScanMain scanMain;
public MqKillHandler(ScanMain scanMain) {
this.scanMain= scanMain;
}
/**
* 注册信号
* @param signalName
*/
public void registerSignal(String signalName) {
Signal signal = new Signal(signalName);
Signal.handle(signal, this);
}
@Override
public void handle(Signal signal) {
if (signal.getName().equals("TERM")) {
// 程序关闭
try {
log.info("程序关闭,正在关闭相关资源");
startScanMain.closeAllThread();
log.info("程序关闭完毕");
// 退出程序
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
SignalHandler类的绑定
编写了SignalHandler
类之后,就需要在程序里面调用并绑定对应的Signal
的接收,代码如下:
log.info("绑定 程序关闭信号,实现程序正常关闭 ");
// 设置 程序关闭线程
MqKillHandler mqKillHandler = new MqKillHandler(this);
mqKillHandler.registerSignal("TERM");
执行脚本
接下来,启动脚本之后,我们等待运行一段时间之后,执行以下脚本:
kill -15 $pid
说明
15
就是对应的信号量
,代表SIGTERM
,就是本文程序里面指定的信号量。下面是官网的解释:
SIGTERM - This signal requests a process to stop running. This signal can be ignored. The process is given time to gracefully shutdown. When a program gracefully shuts down, that means it is given time to save its progress and release resources. In other words, it is not forced to stop. SIGINT is very similar to SIGTERM.
结果
执行kill
命令之后,从下面的截图可以得出,我们的程序是成功地达到了目标,有计划地将资源进行释放,比较完善地终止了我们的程序。
参考链接
man1/kill.1list-of-kill-signalssignalkill-commands-and-signals
总结
一些程序需要有步骤地进行资源结束,否则会造成资源浪费和数据丢失。根据linux
内部机制的信号量
和Java
提供的SignalHandler
类来处理这些事情,简单快捷高效。
随缘求赞
如果我的文章对大家产生了帮忙,可以在文章底部点个赞或者收藏;
如果有好的讨论,可以留言;