Как демонизировать программу Java?
У меня есть программа Java, которую я хотел бы демонизировать в системе linux. Другими словами, Я хочу запустить его в оболочке и продолжить работу после выхода из системы. Я также хочу иметь возможность остановить программу чисто.
нашел в этой статье который использует комбинацию сценариев оболочки и кода Java, чтобы сделать трюк. Это выглядит хорошо, но я хотел бы что-то попроще, если это возможно.
каков ваш предпочтительный метод демонизации Java программы на Linux?
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()); }
Я часто пишу скрипты или командные строки, которые по существу выглядят так, если я хочу:
- запустите программу, которая невосприимчива к вздохам
- который полностью отключен от оболочки, которая его порождает, и
- создает файл журнала из stderr и stdout, содержимое которого также отображается, но
- позволяет мне прекратить просмотр журнала в процессе и делать другие вещи, не нарушая работу процесс
наслаждайтесь.
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
установите daemon tools из url https://cr.yp.to/daemontools/install.html следуйте инструкциям, упомянутым там,для любых вопросов, пожалуйста, попробуйте инструкции https://gist.github.com/rizkyabdilah/8516303
создать файл в / etc/init / svscan.conf и добавить ниже русло.(требуется только для cent-os-6.7)
start on runlevel [12345] stop on runlevel [^12345] respawn exec /command/svscanboot
- создать новый скрипт с именем выполнить внутри/service/ vm / папки и добавьте следующие строки.
#!/bin/bash echo starting VM exec java -jar /root/learning-/daemon-java/vm.jar
Примечание.: замените банку с вашим собственным файлом Jar. или любой файл класса java.
перезагрузить систему
svstat / service/vm должен быть запущен и запущен сейчас !.
- svc-d / service / vm должен сбить vm сейчас !.
- 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!