Подтвердить что ты не робот

Что должна слушать Java-программа, чтобы быть хорошей службой Linux?

В Linux вы можете дать следующие команды:

service <someService> start
service <someService> stop

В отличие от убийства процесса с помощью kill -9 <someService>. Как я узнал в более раннем вопросе, это разница между отправкой процесса a SIGTERM (прежний) и SIGKILL (последним).

Итак, как можно "регистрировать" (и кодировать) обычный JAR или WAR в качестве службы/демона, который можно запустить и остановить с помощью этих команд? Я бы предположил, что Java должен иметь некоторый API для обработки SIGTERM s?

Спасибо заранее!

4b9b3361

Ответ 1

Если вы просто хотите запустить определенный код завершения работы, способ "надлежащего Java" справиться с этим не будет использовать сигналы, но вместо этого добавит общий "крюк остановки", который будет запускаться, когда ваше приложение вот-вот завершится. Это одна из тех проблем с наименьшим общим знаменателем, от которой иногда страдает Java. (Так как не все платформы поддерживают SIGINT, в Java нет поддержки платформы SIGINT.)

К сожалению, вы не получаете много контекста в ShutdownHook, но он может быть полезен:

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    public void run()
    {
        // cleanup
    }
}));

Если вам действительно нужно различать полученный сигнал или вы хотите поддерживать сигналы, которые обычно игнорируют Java (например, USR1), или вы хотите прекратить выключение на основе сигнала, тогда ShutdownHook будет в основном бесполезно для вас, к сожалению.

Существует не поддерживаемый, плохо документированный способ захвата сигналов в Sun JVM, используя класс sun.misc.SignalHandler. Это сомнительно переносимо, хотя кажется, что IBM JVM также поддерживает это.

Например, вы можете подключить обработчик сигнала для прослушивания SIGHUP перезагрузить конфигурацию вашего сервера, которая была настроена в init.d script как reload глагол:

Signal.handle(new Signal("HUP"), new SignalHandler() {
    public void handle(Signal signal)
    {
        reloadConfiguration();
    }
});

Что касается настройки приложения Java, которое будет управляться с помощью команды system, вы должны написать программу оболочки script в init.d, которая запустит ее. Это просто нужно ответить на глаголы start и stop и принять действие appopriate. Например, это может быть ваш /etc/init.d/my-java-program:

#!/bin/sh

case "$1" in
start)
    java /path/to/my/java/program.jar &
    echo $! > /var/run/my-java-program.pid
    ;;

stop)
    if [ ! -f /var/run/my-java-program.pid ]; then
        echo "my-java-program: not running"
        exit 1
    fi

    kill -TERM `cat /var/run/my-java-program.pid`
    ;;

reload)
    if [ ! -f /var/run/my-java-program.pid ]; then
        echo "my-java-program: not running"
        exit 1
    fi

    kill -HUP `cat /var/run/my-java-program.pid`
    ;;

*)
    echo "Usage: /etc/init.d/my-java-program {start|stop|reload}"
    exit 1
    ;;

esac

exit 0

Теперь вы можете запустить свое приложение, запустив /etc/init.d/my-java-program start или в CentOS, вы также можете запустить сервис my-java-program start.

Ответ 2

Вы не можете определить обработчики сигналов для разных сигналов в чистой Java, как в бывшей программе Unix. Это означает, что вы не можете следовать общим соглашениям, например. чтобы программа перезагрузила свою конфигурацию на SIGHUP и выполнила чистое завершение работы на SIGINT или SIGTERM.

Что вы можете сделать, это определить завершение работы. Они запускаются, когда виртуальная машина будет закрыта, например. после получения SIGTERM. Вот пример:

Runnable myShutdownHook = new Runnable() {
    void run() {
        System.out.println("I'm melting! What a world...");
    }
};

Runtime.getRuntime().addShutdownHook(new Thread(myShutdownHook));