Как демонизировать программу Java?


У меня есть программа Java, которую я хотел бы демонизировать в системе linux. Другими словами, Я хочу запустить его в оболочке и продолжить работу после выхода из системы. Я также хочу иметь возможность остановить программу чисто.

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

каков ваш предпочтительный метод демонизации Java программы на Linux?

11 69

11 ответов:

Apache Commons Daemon будет работать ваша программа Java как демон Linux или служба WinNT.

Если вы не можете положиться на Java Service Wrapper привел в другом месте (например, если вы работаете на Ubuntu, у которого нет упакованной версии SW), вы, вероятно, хотите сделать это старомодным способом: попросите вашу программу написать свой PID в /var/run/$progname.pid, и написать стандартный сценарий инициализации SysV (используйте, например, один для ntpd в качестве примера, это просто) вокруг него. Желательно также сделать его совместимым с LSB.

по существу, запуск функциональных тестов если программа уже запущена (путем тестирования if/var/run / $progname.pid существует, и содержимое этого файла является PID запущенного процесса), а если не запустить

logfile=/var/log/$progname.log
pidfile=/var/run/$progname.pid
nohup java -Dpidfile=$pidfile $jopts $mainClass </dev/null > $logfile 2>&1

функция stop проверяет /var/run / $progname.pid, проверяет, является ли этот файл PID запущенного процесса, проверяет, что это Java VM (чтобы не убить процесс, который просто повторно использовал PID из мертвого экземпляра моего демона Java), а затем убивает этот процесс.

при вызове, мой метод main () будет начните с записи его PID в файл, определенный в системе.getProperty ("pidfile").

одно главное препятствие: в Java нет простого и стандартного способа получить PID процесса, в котором работает JVM.

вот что я придумал:

private static String getPid() {
    File proc_self = new File("/proc/self");
    if(proc_self.exists()) try {
        return proc_self.getCanonicalFile().getName();
    }
    catch(Exception e) {
        /// Continue on fall-back
    }
    File bash = new File("/bin/bash");
    if(bash.exists()) {
        ProcessBuilder pb = new ProcessBuilder("/bin/bash","-c","echo $PPID");
        try {
            Process p = pb.start();
            BufferedReader rd = new BufferedReader(new InputStreamReader(p.getInputStream()));
            return rd.readLine();
        }
        catch(IOException e) {
            return String.valueOf(Thread.currentThread().getId());
        }
    }
    // This is a cop-out to return something when we don't have BASH
    return String.valueOf(Thread.currentThread().getId());
}

Я часто пишу скрипты или командные строки, которые по существу выглядят так, если я хочу:

  1. запустите программу, которая невосприимчива к вздохам
  2. который полностью отключен от оболочки, которая его порождает, и
  3. создает файл журнала из stderr и stdout, содержимое которого также отображается, но
  4. позволяет мне прекратить просмотр журнала в процессе и делать другие вещи, не нарушая работу процесс

наслаждайтесь.

nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &

вы могли бы попробовать Java Service Wrapper сообщество Edition является бесплатным и отвечает вашим потребностям.

что зависит. Если это всего лишь одноразовая вещь, я хочу демонизировать ее, а затем вернуться домой, но обычно я жду результатов, я могу сделать:

nohup java com.me.MyProgram &

в командной строке. Чтобы убить его чисто, у вас есть много вариантов. У вас может быть прослушиватель для SIGKILL или прослушивание порта и завершение работы при подключении, периодически проверяйте файл. Разные подходы имеют разные слабые стороны. Если это для использования в производстве, я бы подумал, и, вероятно, бросить скрипт в /etc / init.d что nohups это, и имеют более сложное выключение, например, что tomcat имеет.

мой предпочтительный способ на Ubuntu-это использовать утилиту libslack 'daemon'. Это то, что Дженкинс использует на Ubuntu (именно там я получил эту идею.) Я использовал его для своих серверных приложений на основе причала, и он хорошо работает.

при остановке процесса демона он будет сигнализировать JVM для завершения работы. На этом этапе можно выполнить код завершения работы / очистки, зарегистрировав крюк завершения работы в среде выполнения.addShutdownHook ().

этой вопрос заключается в демонизации произвольной программы (не специфичной для java), поэтому некоторые ответы могут применяться к вашему случаю:

DaemonTools : - более чистый способ управления службами в UNIX https://cr.yp.to/daemontools.html

  1. установите daemon tools из url https://cr.yp.to/daemontools/install.html следуйте инструкциям, упомянутым там,для любых вопросов, пожалуйста, попробуйте инструкции https://gist.github.com/rizkyabdilah/8516303

  2. создать файл в / etc/init / svscan.conf и добавить ниже русло.(требуется только для cent-os-6.7)

 start on runlevel [12345]
 stop on runlevel [^12345]
 respawn
 exec /command/svscanboot
  1. создать новый скрипт с именем выполнить внутри/service/ vm / папки и добавьте следующие строки.
#!/bin/bash    
echo starting VM 
exec java -jar
/root/learning-/daemon-java/vm.jar

Примечание.: замените банку с вашим собственным файлом Jar. или любой файл класса java.

  1. перезагрузить систему

  2. svstat / service/vm должен быть запущен и запущен сейчас !.

  3. svc-d / service / vm должен сбить vm сейчас !.
  4. svc-u / service / vm должен поднять vm сейчас !.

посмотри здесь:

http://jnicookbook.owsiak.org/recipe-no-022/

для примера кода, основанного на JNI. В этом случае вы демонизируете код, который был запущен как Java, и основной цикл выполняется в C. Но также можно поместить основной, демонический, сервисный цикл внутри Java.

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo029

удачи с JNI!

nohup java -jar {{your-jar.jar}} > /dev/null &

Это может сделать трюк.