Ich habe ein Java-Programm, das ich auf einem Linux-System dämonisieren möchte. Mit anderen Worten, ich möchte es in einer Shell ausführen und nach dem Abmelden weiter ausführen lassen. Ich möchte auch in der Lage sein, das Programm sauber zu stoppen.
Ich habe diesen Artikel gefunden, der eine Kombination aus Shell-Scripting und Java-Code verwendet, um den Trick auszuführen. Es sieht gut aus, aber ich möchte, wenn möglich, etwas Einfacheres.
Was ist Ihre bevorzugte Methode, um ein Java-Programm auf einem Linux-System zu dämonisieren?
nohup java prog &
.Antworten:
Apache Commons Daemon führt Ihr Java-Programm als Linux-Daemon oder WinNT-Dienst aus.
quelle
Wenn Sie sich nicht auf den an anderer Stelle genannten Java Service Wrapper verlassen können (z. B. wenn Sie Ubuntu ausführen, das keine gepackte Version von SW enthält), möchten Sie dies wahrscheinlich auf die altmodische Weise tun: Lassen Sie Ihr Programm seine PID in / schreiben var / run / $ schedame.pid und schreiben Sie ein Standard-SysV-Init-Skript (verwenden Sie beispielsweise das für ntpd als Beispiel, es ist einfach). Machen Sie es vorzugsweise auch LSB-konform.
Im Wesentlichen testet die Startfunktion, ob das Programm bereits ausgeführt wird (indem getestet wird, ob /var/run/$progname.pid vorhanden ist und der Inhalt dieser Datei die PID eines laufenden Prozesses ist) und ob es nicht ausgeführt wird
logfile=/var/log/$progname.log pidfile=/var/run/$progname.pid nohup java -Dpidfile=$pidfile $jopts $mainClass </dev/null > $logfile 2>&1
Die Stoppfunktion überprüft /var/run/$progname.pid, prüft, ob diese Datei die PID eines laufenden Prozesses ist, und überprüft, ob es sich um eine Java-VM handelt (um einen Prozess nicht zu beenden, der die PID einfach von einem Toten wiederverwendet hat Instanz meines Java-Daemons) und beendet dann diesen Prozess.
Beim Aufruf beginnt meine main () -Methode damit, ihre PID in die in System.getProperty ("pidfile") definierte Datei zu schreiben.
Eine große Hürde: In Java gibt es keine einfache und standardmäßige Methode, um die PID des Prozesses zu ermitteln, in dem die JVM ausgeführt wird.
Folgendes habe ich mir ausgedacht:
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()); }
quelle
Ich schreibe häufig Skripte oder Befehlszeilen, die im Wesentlichen so aussehen, wenn ich möchte:
Genießen.
nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &
quelle
Ich bevorzuge den Befehl nohup . Der Blog-Beitrag sagt, dass es bessere Möglichkeiten gibt, aber ich denke nicht, dass sie besser genug sind.
quelle
Sie können Java Service Wrapper ausprobieren . Die Community Edition ist kostenlos und entspricht Ihren Anforderungen.
quelle
Das hängt davon ab. Wenn es nur eine einmalige Sache ist, möchte ich sie dämonisieren und dann nach Hause gehen, aber normalerweise warte ich auf die Ergebnisse.
an der Kommandozeile. Um es sauber zu töten, haben Sie viele Möglichkeiten. Möglicherweise haben Sie einen Listener für SIGKILL oder überprüfen einen Port und fahren herunter, wenn eine Verbindung hergestellt wird. Überprüfen Sie regelmäßig eine Datei. Differenzansätze haben unterschiedliche Schwächen. Wenn es für die Produktion verwendet werden soll, würde ich mir mehr Gedanken darüber machen und wahrscheinlich ein Skript in /etc/init.d werfen, das es nicht aktualisiert, und ein ausgefeilteres Herunterfahren durchführen, wie z. B. das, was Tomcat hat.
quelle
Meine bevorzugte Methode unter Ubuntu ist die Verwendung des libslack-Dienstprogramms 'daemon'. Dies ist, was Jenkins unter Ubuntu verwendet (woher ich die Idee hatte). Ich habe es für meine Jetty-basierten Serveranwendungen verwendet und es funktioniert gut.
Wenn Sie den Daemon-Prozess stoppen, signalisiert dies der JVM das Herunterfahren. Sie können den Code zum Herunterfahren / Bereinigen an dieser Stelle ausführen, indem Sie einen Shutdown-Hook bei Runtime.addShutdownHook () registrieren.
quelle
Bei dieser Frage geht es darum, ein beliebiges Programm (nicht Java-spezifisch) zu dämonisieren, sodass einige der Antworten möglicherweise auf Ihren Fall zutreffen:
quelle
DaemonTools: - Eine sauberere Methode zum Verwalten von Diensten unter UNIX https://cr.yp.to/daemontools.html
Installieren Sie Daemon-Tools über die URL https://cr.yp.to/daemontools/install.html. Befolgen Sie die dort genannten Anweisungen. Bei Problemen versuchen Sie bitte die Anweisungen https://gist.github.com/rizkyabdilah/8516303
Erstellen Sie eine Datei unter /etc/init/svscan.conf und fügen Sie die folgenden Zeilen hinzu (nur für cent-os-6.7 erforderlich).
Hinweis: Ersetzen Sie das Glas durch Ihre eigene Glasdatei. oder eine beliebige Java-Klassendatei.
Starten Sie das System neu
svstat / service / vm sollte jetzt betriebsbereit sein!
quelle
nohup java -jar {{your-jar.jar}} > /dev/null &
Dies kann den Trick tun.
quelle
Schauen Sie hier:
http://jnicookbook.owsiak.org/recipe-no-022/
für einen Beispielcode, der auf JNI basiert. In diesem Fall dämonisieren Sie den Code, der als Java gestartet wurde, und die Hauptschleife wird in C ausgeführt. Es ist jedoch auch möglich, die Dienstschleife des Hauptdämons in Java einzufügen.
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo029
Viel Spaß mit JNI!
quelle