java signal handler_JAVA优雅停机的实现
最近在項目中需要寫一個數據轉換引擎服務,每過5分鐘同步一次數據。具體實現是啟動engine server后會初始化一個ScheduledExecutorService和一個ThreadPoolExecutor線程池。schduel executor每過5分鐘將dataTransformList中每一個tranform加入到線程池中運行。每一個數據轉化器負責轉換一組數據庫數據。在執行過程中存在服務重啟并且此時tranform正在轉換數據并且數據沒有全部操作完,此時希望正在執行的work能正常完成作業后再退出。優雅停機在服務重啟,服務關閉顯得比較重要了(盡管不能解決服務器突然斷電導致服務瞬間不可用等原因)。
普通的優雅停機:當使用kill PID的時候jvm會收到服務停止信號并執行shutdownHook的線程
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
synchronized (EngineBootstrap.class) {
EngineServer.getInstance().shutdown();
running = false;
EngineBootstrap.class.notify();
}
}
});
EngineServer的shutdown方法
public void shutdown() {
this.transformExecutor.shutdown();
this.scheduledExecutorService.shutdown();
}ThreadPoolExecutor的shutdown方法會中斷所有的空閑任務,保持正在運行中的任務執行完畢,但是由于kill PID一段時間后jvm就退出了導致正在執行的任務還沒有完成就停止了。
改進后的優雅停機:
Signal sig = new Signal(getOSSignalType());
Signal.handle(sig, new SignalHandler() {
public void handle(Signal signal) {
synchronized (EngineBootstrap.class) {
EngineServer.getInstance().shutdown();
running = false;
EngineBootstrap.class.notify();
}
}
});
private static String getOSSignalType() {
return System.getProperties().getProperty("os.name").
toLowerCase().startsWith("win") ? "INT" : "USR2";
}
linux下通過kill -l查看 31 對應于 SIGUSR2?執行kill -31 PID, SignalHander會接收到signal number為31的信號并執行server shutdown,此時jvm并不會退出直到線程池所有正在執行的線程全部執行完畢才會安全退出。
java -jar data-engine-1.0.0-SNAPSHOT.jar
sh shutdown.sh
可以看到主線程安全退出后,線程池中的work執行完畢后java進程才結束
chenbanghongs-MacBook-Pro:nbugs-data-engine sylar$ java -jar target/data-engine-1.0.0-SNAPSHOT.jar.zip
1
2
3
4
5
31
優雅停機
主線程安全退出
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
transform
總結
以上是生活随笔為你收集整理的java signal handler_JAVA优雅停机的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BugkuCTF-Misc:隐写
- 下一篇: 光盘隐藏文件夹 linux,linux常