it-swarm.com.de

Wie man ein Java-Programm dämonisiert?

Ich habe ein Java-Programm, das ich gerne auf einem Linux-System dämonisieren möchte. Mit anderen Worten, ich möchte es in einer Shell ausführen und nach dem Abmelden weiterlaufen lassen. Ich möchte auch das Programm sauber stoppen können.

Ich habe diesen Artikel gefunden, der eine Kombination aus Shell-Scripting und Java-Code für den Trick verwendet. Es sieht gut aus, aber ich hätte gerne etwas Einfacheres, wenn möglich.

Was ist Ihre bevorzugte Methode, um ein Java-Programm auf einem Linux-System zu dämonisieren?

69
Rich Apodaca

Apache Commons Daemon führt Ihr Java-Programm als Linux-Daemon oder WinNT-Dienst aus.

37
Bahaa Zaid

Wenn Sie sich nicht auf Java Service Wrapper cited an anderer Stelle verlassen können (wenn Sie beispielsweise Ubuntu ausführen, auf dem keine SW-Version installiert ist), möchten Sie dies wahrscheinlich auf die alte Art und Weise tun: Lassen Sie Ihr Programm seine PID in /var/run/$progname.pid schreiben, und schreiben Sie ein Standard-SysV-Init-Skript (verwenden Sie beispielsweise das Beispiel für ntpd, es ist ganz einfach). Machen Sie es vorzugsweise auch LSB-kompatibel.

Im Wesentlichen testet die Startfunktion, ob das Programm bereits läuft (indem geprüft wird, ob /var/run/$progname.pid vorhanden ist und der Inhalt dieser Datei die PID eines laufenden Prozesses ist) und, falls nicht, ausgeführt

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

Die Stoppfunktion prüft auf /var/run/$progname.pid und prüft, ob diese Datei die PID eines laufenden Prozesses ist, und überprüft, ob es sich um ein Java VM handelt (um einen Prozess nicht zu beenden, der den PID von einer toten Instanz meines Java-Daemons) und beendet dann diesen Prozess. 

Nach dem Aufruf schreibt meine main () - Methode ihre PID in die in System.getProperty ("pidfile") definierte Datei.

Eine große Hürde jedoch: In Java gibt es keine einfache und standardisierte Methode, um die PID des Prozesses zu erhalten, 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());
}
32
Varkhan

Ich schreibe häufig Skripte oder Befehlszeilen, die im Wesentlichen so aussehen, wenn ich möchte:

  1. Führen Sie ein Programm aus, das immun gegen Seufzer ist 
  2. Das ist völlig getrennt von der Shell, die sie erzeugt, und 
  3. Erzeugt eine Protokolldatei aus stderr und stdout, deren Inhalt ebenfalls angezeigt wird, jedoch
  4. Erlaubt mir, die Protokollierung anzuhalten und andere Aufgaben zu erledigen, ohne den laufenden Prozess zu unterbrechen

Genießen.

Nohup Java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &
23
Ben Hardy

Ich bevorzuge den Befehl Nohup . Der Blogpost sagt, dass es bessere Wege gibt, aber ich denke nicht, dass sie genug besser sind.

14
S.Lott

Sie können versuchen, Java Service Wrapper , die Community Edition ist kostenlos und entspricht Ihren Anforderungen.

5
John T

Mein bevorzugter Weg für Ubuntu ist die Verwendung des libslack-Dienstprogramms "daemon". Dies ist, was Jenkins auf 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, wird die JVM angehalten, herunterzufahren. Sie können an dieser Stelle den Shutdown/Cleanup-Code ausführen, indem Sie einen Shutdown-Hook mit Runtime.addShutdownHook () registrieren.

4
colini

Kommt darauf an. Wenn es nur eine einmalige Sache ist, möchte ich es dämonisieren und dann nach Hause gehen, aber normalerweise warte ich auf die Ergebnisse.

Nohup Java com.me.MyProgram &

in der Befehlszeile. Um es sauber zu töten, haben Sie viele Möglichkeiten. Möglicherweise haben Sie einen Listener für SIGKILL, oder Sie überwachen einen Port und fahren herunter, wenn eine Verbindung hergestellt wird. Überprüfen Sie regelmäßig eine Datei. Unterschiedliche Ansätze haben unterschiedliche Schwächen. Wenn es für die Produktion in der Produktion verwendet wird, würde ich darüber nachdenken und wahrscheinlich ein Skript in /etc/init.d ablegen, das es nicht zulässt, und ein komplizierteres Herunterfahren haben, wie beispielsweise das von Tomcat.

4
Don Branson

Bei dieser Frage geht es um das Daemonisieren eines beliebigen Programms (nicht Java-spezifisch), daher können einige Antworten auf Ihren Fall zutreffen:

2
dreeves

DaemonTools: - Eine sauberere Methode zum Verwalten von Diensten unter UNIX https://cr.yp.to/daemontools.html

  1. Installieren Sie die 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. de/rizkyabdilah/8516303

  2. 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).

 start on runlevel [12345]
 stop on runlevel [^12345]
 respawn
 exec /command/svscanboot
  1. Erstellen Sie ein neues Skript mit dem Namen run im Ordner/service/vm/und fügen Sie die folgenden Zeilen hinzu.
#!/bin/bash    
echo starting VM 
exec Java -jar
/root/learning-/daemon-Java/vm.jar

Hinweis: Ersetzen Sie das Jar durch Ihre eigene Jar-Datei. oder eine beliebige Java-Klassendatei.

  1. Starten Sie das System neu

  2. svstat/service/vm sollte jetzt einsatzbereit sein!.

  3. svc -d/service/vm sollte vm jetzt herunterfahren!.
  4. svc -u/service/vm sollte jetzt vm hochbringen!.
2
Velu

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 Hauptschleife des Daemons in Java zu integrieren.

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

Viel Spaß mit JNI!

0
Oo.oO
Nohup Java -jar {{your-jar.jar}} > /dev/null &

Dies kann den Trick tun.

0
fifman