Jak Daemonizować program Java?

Mam program Java, który chciałbym demonizować na systemie linux. Innymi słowy, chcę rozpocząć uruchamianie go w powłoce i mieć go nadal działa po wylogowaniu. Chcę też móc całkowicie zatrzymać program.

Znalazłem Ten artykuł, który wykorzystuje kombinację skryptów powłoki i kodu Javy do wykonania tej sztuczki. Wygląda dobrze, ale chciałbym coś prostszego, jeśli to możliwe.

Jaka jest Twoja preferowana metoda demonizacji programu Java na Linuksie system?

Author: Rich Apodaca, 2009-02-11

11 answers

Apache Commons Daemon uruchomi Twój program Java jako Linux daemon lub WinNT Service.

 37
Author: Bahaa Zaid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-08 15:14:53

Jeśli nie możesz polegać na Java Service Wrapper cytowany gdzie indziej (na przykład, jeśli używasz Ubuntu, które nie ma spakowanej wersji oprogramowania SW) prawdopodobnie chcesz zrobić to w staromodny sposób: niech twój program napisze swój PID W /var/run/$progname.pid, i napisać standardowy skrypt sysv init (użyj na przykład tego dla ntpd, to proste) wokół niego. Najlepiej, żeby też był zgodny z LSB.

Zasadniczo funkcja start sprawdza, czy program jest już uruchomiony (testując if / var / run / $progname.pid istnieje, a zawartość tego pliku jest PID uruchomionego procesu), a jeśli nie uruchom

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

Funkcja stop sprawdza / var / run / $progname.pid, testuje, czy plik jest PID uruchomionego procesu, sprawdza, czy jest to maszyna wirtualna Java (aby nie zabić procesu, który po prostu ponownie użył PID z martwej instancji mojego Daemona Java), a następnie zabija ten proces.

Po wywołaniu moja metoda main () rozpocznie się od zapisania jej PID W plik zdefiniowany w systemie.getProperty ("pidfile").

Jedna poważna przeszkoda: w Javie nie ma prostego i standardowego sposobu na uzyskanie PID procesu, w którym uruchamia się JVM.

Oto co wymyśliłem:

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());
}
 32
Author: Varkhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-24 18:38:33

Często piszę skrypty lub wiersze poleceń, które zasadniczo wyglądają tak, jeśli chcę:

  1. Uruchom program, który jest odporny na sighups
  2. , który jest całkowicie odłączony od powłoki, która ją rodzi, i
  3. tworzy plik dziennika ze stderr i stdout, którego zawartość jest wyświetlana, ale
  4. pozwala mi przestać przeglądać postęp logowania i robić inne rzeczy bez zakłócania biegu proces
Smacznego.
nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &
 23
Author: Ben Hardy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-10 23:27:28

Wolę polecenie nohup . Na blogu napisano, że są lepsze sposoby, ale myślę, że nie są one wystarczająco lepsze.

 14
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-10 23:10:43

Możesz wypróbować Java Service Wrapper , wersja community jest darmowa i spełnia Twoje potrzeby.

 5
Author: John T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-10 23:07:06

To zależy. Jeśli jest to tylko jednorazowa rzecz, chcę ją daemonizować i wrócić do domu, ale zazwyczaj czekam na wyniki, mogę to zrobić:

nohup java com.me.MyProgram &

W wierszu poleceń. Aby go zabić, masz wiele opcji. Możesz mieć odbiornik SIGKILL lub słuchać na porcie i zamykać po nawiązaniu połączenia okresowo sprawdzaj plik. Podejścia różnicowe mają różne słabości. Jeśli to jest do wykorzystania w produkcji, dałbym to więcej przemyśleć, i prawdopodobnie wrzucić scenariusz do / etc / init.d, że to nie działa, i mają bardziej wyrafinowane wyłączenie, takie jak to, co tomcat ma.

 4
Author: Don Branson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-10 23:10:45

Moim preferowanym sposobem na Ubuntu jest użycie narzędzia libslack 'daemon'. Tego właśnie używa Jenkins na Ubuntu (stąd pomysł.) Używałem go do Moich aplikacji serwerowych opartych na Jetty i działa dobrze.

Po zatrzymaniu procesu daemona, JVM zostanie wyłączony. W tym momencie można wykonać kod zamykania/czyszczenia, rejestrując hook zamykania w trybie Runtime.addShutdownHook().

 4
Author: colini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-16 15:31:42

To pytanie dotyczy demonizacji dowolnego programu (nie specyficznego dla Javy), więc niektóre odpowiedzi mogą dotyczyć Twojego przypadku:

 2
Author: dreeves,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:41

DaemonTools : - czystszy sposób zarządzania usługami w Unixie https://cr.yp.to/daemontools.html

  1. Zainstaluj daemon tools z adresu url https://cr.yp.to/daemontools/install.html postępuj zgodnie z instrukcjami tam wymienionymi,w razie jakichkolwiek problemów spróbuj instrukcji https://gist.github.com/rizkyabdilah/8516303

  2. Utwórz plik w / etc / init / svscan.conf {[18] } i dodać poniższe linie.(wymagane tylko dla cent-os-6.7)

 start on runlevel [12345]
 stop on runlevel [^12345]
 respawn
 exec /command/svscanboot
  1. Utwórz nowy skrypt o nazwie Uruchom w folderze / service / vm / i dodaj poniższe linie.
#!/bin/bash    
echo starting VM 
exec java -jar
/root/learning-/daemon-java/vm.jar

Uwaga: zastąp Jar własnym plikiem Jar. lub dowolnego pliku klasy java.

  1. Uruchom ponownie system

  2. Svstat / service / vm powinien być już uruchomiony !.

  3. svc-d/service / vm powinien obniżyć vm już teraz !.
  4. svc-u / service / vm powinien podnieść vm teraz !.
 2
Author: Velu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-09 04:35:53

Spójrz tutaj:

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

Dla przykładowego kodu opartego na JNI. W tym przypadku daemonizujesz kod, który został uruchomiony jako Java, a główna pętla jest wykonywana w C. Ale możliwe jest również umieszczenie głównej, daemonowej, service loop wewnątrz Javy.

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

Baw się dobrze z JNI!

 0
Author: Oo.oO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-05 07:32:50
nohup java -jar {{your-jar.jar}} > /dev/null &
To może załatwić sprawę.
 0
Author: fifman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-14 12:05:24