Java學習系列:使用SignalHandler來處理Linux信號量,控制程序結束的步驟

場景

最近,開發的程序是對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.1
list-of-kill-signals
signal
kill-commands-and-signals

總結

一些程序需要有步驟地進行資源結束,否則會造成資源浪費和數據丟失。根據linux內部機制的信號量Java提供的SignalHandler類來處理這些事情,簡單快捷高效。
在這裏插入圖片描述

隨緣求贊

如果我的文章對大家產生了幫忙,可以在文章底部點個贊或者收藏;
如果有好的討論,可以留言;
如果想繼續查看我以後的文章,可以左上角點擊關注
拜拜

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章