Question

J'ai un programme Java que je voudrais daemonize sur un système Linux. En d'autres termes, je veux commencer à fonctionner dans une coquille et l'avoir continue de fonctionner après que je suis déconnecté. Je veux aussi être en mesure d'arrêter le programme proprement.

J'ai trouvé cet article qui utilise un combinaison de scripts shell et du code Java pour faire l'affaire. Il semble bien, mais je voudrais quelque chose de plus simple, si possible.

Quelle est votre méthode préférée pour daemonize un programme Java sur un système Linux?

Était-ce utile?

La solution

Apache Commons Daemon exécutera votre programme Java en tant que démon Linux ou service Windows NT.

Autres conseils

Si vous ne pouvez pas compter sur Java service Wrapper cité elsewhere (par exemple, si vous exécutez sur Ubuntu, qui n'a pas de version packagée de SW) que vous voulez sans doute de le faire à l'ancienne: avoir votre écriture de programme son PID /var/run/$progname.pid, et écrire un script d'initialisation SysV standard (utilisation par exemple celui pour ntpd à titre d'exemple, il est simple) autour d'elle. De préférence, le rendre compatible LSB aussi.

Pour l'essentiel, les tests de la fonction de démarrage si le programme est en cours d'exécution (en testant si existe /var/run/$progname.pid, et le contenu de ce fichier est le PID d'un processus en cours d'exécution), et sinon courir

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

La fonction vérifie d'arrêt sur /var/run/$progname.pid, des tests si ce fichier est le PID d'un processus en cours d'exécution, vérifie qu'il est une machine virtuelle Java (pour ne pas tuer un processus qui simplement réutilisé le PID d'une instance mort de mon démon Java) et tue alors ce processus.

Lorsqu'il est appelé, ma méthode principale () commencera par écrit son PID dans le fichier défini dans System.getProperty ( "pidfile").

Un obstacle majeur, bien que:. En Java, il n'y a aucun moyen simple et standard pour obtenir le PID du processus de la machine virtuelle Java fonctionne dans

Voici ce que je suis venu avec:

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());
}

Je me retrouve souvent à écrire des scripts ou des lignes de commande qui ressemblent essentiellement comme ça, si je veux:

  1. Exécuter un programme qui est à l'abri de sighups
  2. C'est complètement déconnecté de la coquille qui fraye, et
  3. produit un fichier journal de stderr et stdout dont le contenu sont affichés aussi bien, mais
  4. me permet d'arrêter l'affichage du journal en cours et faire d'autres choses sans perturber le processus de fonctionnement

Profitez.

nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &

Je préfère la commande nohup . Le billet de blog dit il y a de meilleures façons, mais je ne pense pas qu'ils sont assez mieux.

Vous pouvez essayer Java service Wrapper , l'édition communautaire est gratuite et se réunit vos besoins.

Cela dépend. Si c'est juste une chose une seule fois, je veux daemon, puis rentrer à la maison, mais en général j'attendre les résultats, je pourrais faire:

nohup java com.me.MyProgram &

à la ligne de commande. Pour tuer proprement, vous avez beaucoup d'options. Vous pourriez avoir un écouteur pour SIGKILL, ou écouter sur un port et l'arrêt lorsqu'une connexion est établie, vérifier périodiquement un fichier. approches de différence ont des faiblesses différentes. Si elle est pour une utilisation dans la production, je donnerais plus la pensée, et probablement jeter un script dans /etc/init.d qui nohups, et un arrêt plus sophistiqué, comme ce qui a tomcat.

Ma façon préférée sur Ubuntu est d'utiliser le libslack « démon » utilitaire. C'est ce que Jenkins utilise sur Ubuntu (qui est où j'ai eu l'idée.) Je l'ai utilisé pour mes applications de serveur basé sur la jetée et il fonctionne bien.

Lorsque vous arrêtez le processus démon, il signalera la machine virtuelle Java à l'arrêt. Vous pouvez exécuter le code d'arrêt / nettoyage à ce point en vous inscrivant un crochet d'arrêt avec Runtime.addShutdownHook ().

Cette question est sur daemonizing un programme arbitraire (non spécifique java) de sorte que certains les réponses peuvent demander à votre cas:

daemontools: - Un moyen plus propre pour gérer les services à UNIX https://cr.yp.to/daemontools .html

  1. Installer des outils démon de la https://cr.yp.to/daemontools /install.html suivez les instructions qui y sont mentionnés, pour toutes les questions s'il vous plaît essayer instructions https://gist.github.com/rizkyabdilah/8516303

  2. Créez un fichier à /etc/init/svscan.conf et ajoutez les lignes ci-dessous. (Uniquement pour cent-os-6.7)

 start on runlevel [12345]
 stop on runlevel [^12345]
 respawn
 exec /command/svscanboot
  1. Créez un nouveau script nommé run à l'intérieur / services / vm / dossier et ajoutez les lignes ci-dessous.
#!/bin/bash    
echo starting VM 
exec java -jar
/root/learning-/daemon-java/vm.jar

Note:    remplacer le pot avec votre propre fichier Jar. ou tout autre fichier de classe java.

  1. Redémarrer le système

  2. svstat / services / vm devrait être opérationnel maintenant.

  3. svc -d / Service / vm devrait vm faire baisser maintenant.
  4. svc -u / Service / vm devrait vm apporter maintenant!.

Jetez un coup d'oeil ici:

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

pour un exemple de code qui est basé sur JNI. Dans ce cas, vous daemonize le code qui a été lancé en boucle Java et principale est exécutée en C. Mais il est aussi possible de mettre principal, démon de boucle de service à l'intérieur de Java.

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

Amusez-vous avec JNI!

nohup java -jar {{your-jar.jar}} > /dev/null &

Cela peut faire l'affaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top