【问题标题】:How to process SIGTERM signal gracefully in Java?如何在 Java 中优雅地处理 SIGTERM 信号?
【发布时间】:2017-11-18 11:54:13
【问题描述】:

假设我们有这样一个用 java 编写的简单的守护进程:

public class Hellow {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        while(true) {
            // 1. do
            // 2. some
            // 3. important
            // 4. job
            // 5. sleep
        }

    }
}

我们使用start-stop-daemon 对其进行守护,默认情况下它在--stop 上发送SIGTERM (TERM) 信号

假设当前执行的步骤是#2。而此时我们正在发送 TERM 信号。

发生的情况是执行立即终止。

我发现我可以使用addShutdownHook() 处理信号事件,但问题是它仍然会中断当前执行并将控制权传递给处理程序:

public class Hellow {
    private static boolean shutdownFlag = false;
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        registerShutdownHook();

        try {
            doProcessing();
        } catch (InterruptedException ex) {
            System.out.println(ex);
        }
    }

    static private void doProcessing() throws InterruptedException {
        int i = 0;
        while(shutdownFlag == false) {
            i++;
            System.out.println("i:" + i);
            if(i == 5) {
                System.out.println("i is 5");
                System.exit(1); // for testing
            }

            System.out.println("Hello"); // It doesn't print after System.exit(1);

            Thread.sleep(1000);
        }
    }

    static public void setShutdownProcess() {
        shutdownFlag = true;
    }

    private static void registerShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                System.out.println("Tralala");
                Hellow.setShutdownProcess();
            }
        });
    }
}

所以,我的问题是 - 是否可以不中断当前执行,而是在单独的线程中处理 TERM 信号(?),以便我能够设置 shutdown_flag = True 以便 main 中的循环将有机会优雅地停下来吗?

【问题讨论】:

    标签: java process daemon sigterm start-stop-daemon


    【解决方案1】:

    我重写了registerShutdownHook() 方法,现在它可以按我的意愿工作了。

    private static void registerShutdownHook() {
        final Thread mainThread = Thread.currentThread();
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                try {
                    System.out.println("Tralala");
                    Hellow.setShutdownProcess();
                    mainThread.join();
                } catch (InterruptedException ex) {
                    System.out.println(ex);
                }
    
            }
        });  
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用 SignalHandler。请查看此示例:https://dumpz.org/2707213/

      它将赶上INTERRUPTED 信号并取消设置operating 标志,这反过来将允许应用程序正常关闭。

      【讨论】:

      • 是的,您的解决方案有效,但在编译时,编译器发誓SignalHandler 将来将不起作用。我找到了另一个解决方案,但谢谢)
      • @IslomkhodjaHamidullakhodjaev 你能分享你的解决方案吗?亲切的问候
      猜你喜欢
      • 2023-04-02
      • 1970-01-01
      • 2011-02-02
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 2016-01-20
      • 2020-03-19
      相关资源
      最近更新 更多