Ответ 1
Apache Commons Daemon запустит вашу Java-программу как демон Linux или службу WinNT.
У меня есть Java-программа, которую я хотел бы демонизировать в Linux-системе. Другими словами, я хочу запустить его в оболочке и продолжить работу после того, как я выйду из системы. Я также хочу, чтобы у меня была возможность полностью остановить программу.
Я нашел эта статья, в которой используется комбинация сценариев оболочки и кода Java, чтобы сделать трюк. Это выглядит хорошо, но мне бы хотелось, если возможно, что-то более простое.
Какой предпочтительный метод для демонстрации программы Java в системе Linux?
Apache Commons Daemon запустит вашу Java-программу как демон Linux или службу WinNT.
Если вы не можете положиться на Java Service Wrapper, ссылка в другом месте ( например, если вы работаете на Ubuntu, у которого нет пакетной версии SW), вы, вероятно, захотите сделать это старомодно: попросите свою программу записать свой PID в /var/run/ $progname.pid и напишите стандартный SysV init script (используйте, например, пример для ntpd, это просто) вокруг него. Желательно также сделать его совместимым с LSB.
По сути, функция start проверяет, запущена ли программа (путем тестирования, существует ли /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
Функция остановки проверяет /var/run/ $progname.pid, проверяет, является ли этот файл PID выполняющегося процесса, проверяет, является ли это виртуальной машиной Java (чтобы не убивать процесс, который просто повторно использовал PID из мертвого экземпляра моего Java-демона), а затем убивает этот процесс.
При вызове мой метод main() начнется с записи его PID в файле, определенном в System.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());
}
Я часто нахожу, что пишу сценарии или командные строки, которые по существу выглядят так, если я хочу:
Enjoy.
nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &
Я предпочитаю команду nohup. В сообщении в блоге говорится, что есть лучшие способы, но я не думаю, что они достаточно хороши.
Вы можете попробовать Java Service Wrapper, публикация сообщества бесплатна и соответствует вашим потребностям.
Это зависит. Если это всего лишь одноразовая вещь, я хочу ее демонизировать, а затем вернуться домой, но обычно жду результатов, я мог бы сделать:
nohup java com.me.MyProgram &
в командной строке. Чтобы убить его чисто, у вас есть много вариантов. У вас может быть слушатель для SIGKILL, или слушать порт и выключение при подключении, периодически проверять файл. Разностные подходы имеют разные недостатки. Если бы он использовался для производства, я бы подумал над этим и, вероятно, выбросил script в /etc/init.d, который не имеет его, и имеет более сложное завершение работы, например, то, что имеет tomcat.
Мой предпочтительный способ Ubuntu - использовать утилиту libslack 'daemon'. Это то, что Дженкинс использует на Ubuntu (где я получил эту идею). Я использовал его для своих приложений на сервере Jetty, и он работает хорошо.
Когда вы остановите процесс демона, он будет сигнализировать о запуске JVM. Вы можете выполнить код завершения/очистки в этот момент, зарегистрировав крюк остановки с помощью Runtime.addShutdownHook().
DaemonTools: - более чистый способ управления службами в UNIX https://cr.yp.to/daemontools.html
Установить инструменты демона из 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
#!/bin/bash echo starting VM exec java -jar /root/learning-/daemon-java/vm.jar
Примечание: замените Jar своим собственным файлом Jar. или любой файл класса java.
Перезагрузите систему
svstat/service/vm должен быть запущен и запущен сейчас!
Если вам нравятся новые вещи, вы можете попробовать Akuma. Для (немного) информации см. Также Блог Kohsuke Kawaguchi.
Взгляните сюда:
http://jnicookbook.owsiak.org/recipe-no-022/
для примера кода, основанного на JNI. В этом случае вы демонизируете код, который был запущен как Java, а основной цикл выполняется в C. Но также можно поместить основной цикл daemon в Java.
https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo029
Получайте удовольствие от JNI!
nohup java -jar {{your-jar.jar}} > /dev/null &
Это может сделать трюк.