Wie kann man Node.js als Hintergrundprozess ausführen und niemals sterben?

480

Ich verbinde mich über Putty SSH mit dem Linux-Server. Ich habe versucht, es als Hintergrundprozess wie folgt auszuführen:

$ node server.js &

Nach 2,5 Stunden wird das Terminal jedoch inaktiv und der Prozess stirbt ab. Kann ich den Prozess trotzdem am Leben erhalten, auch wenn das Terminal nicht angeschlossen ist?


Bearbeiten 1

Eigentlich habe ich es versucht nohup, aber sobald ich das Putty SSH-Terminal schließe oder mein Internet ausstecke, stoppt der Serverprozess sofort.

Muss ich in Putty etwas tun?


Bearbeiten 2 (am Februar 2012)

Es gibt ein node.jsModul für immer . Der Server node.js wird als Daemon-Dienst ausgeführt.

Murvinlai
quelle
7
In meinem Fall funktioniert nohup, wenn ich Terminal durch Eingabe verlasse exit. Wenn ich gerade das Putty-Fenster schließe, schlägt es fehl.
Pawel Furmaniak

Antworten:

513

Einfache Lösung (wenn Sie nicht daran interessiert sind, zum Prozess zurückzukehren, möchten Sie nur, dass er weiter ausgeführt wird):

nohup node server.js &

Es gibt auch den jobsBefehl, eine indizierte Liste dieser Hintergrundprozesse anzuzeigen. Und Sie können einen Hintergrundprozess beenden, indem Sie ihn ausführen kill %1oder kill %2wobei die Nummer der Index des Prozesses ist.

Leistungsstarke Lösung (ermöglicht es Ihnen, die Verbindung zum Prozess wiederherzustellen, wenn dieser interaktiv ist):

screen

Sie können dann durch Drücken von Strg + a + d die Verbindung trennen und durch Ausführen wieder anhängen screen -r

Betrachten Sie auch die neuere Alternative zum Bildschirm, tmux.

MK.
quelle
1
Wenn ich also "screen" ausführe, erstelle ich den Bildschirm und starte darin, oder?
Murvinlai
30
Ja, und dann können Sie durch Drücken von Strg + a, d die Verbindung trennen und dann durch Ausführen von Bildschirm -r
MK
1
@murvinlai EC2 ist eine Umgebung und hat nichts mit Root-Rechten zu tun. Es geht wahrscheinlich um Ihren AMI. Zum Beispiel mit Amazon AMI können Sie sicherlich sudo bash.
ShuaiYuan
1
man bash: Wenn ein Befehl vom Steueroperator & beendet wird, führt die Shell den Befehl im Hintergrund in einer Subshell aus. Die Shell wartet nicht auf das Beenden des Befehls und der Rückgabestatus ist 0.
MK.
34
Bitte an alle, die dies lesen: Das Ausführen eines node.js-Servers in einem Bildschirm oder einer tmux-Sitzung ist ein AMATEUR Lösung! Tun Sie das nicht, außer für schnelle Tests. Um einen Prozess am Laufen zu halten, müssen Sie ihn dämonisieren ! Verwenden Sie dafür geeignete Werkzeuge für immer , pm2 oder die einfachen alten init.d-Skripte .
Victor Schröder
1119

nohup node server.js > /dev/null 2>&1 &

  1. nohupbedeutet: Beenden Sie diesen Vorgang nicht, auch wenn die Stty abgeschnitten ist.
  2. > /dev/nullbedeutet: stdout geht nach / dev / null (ein Dummy-Gerät, das keine Ausgabe aufzeichnet).
  3. 2>&1bedeutet: stderr geht auch zum stdout (der bereits umgeleitet wird /dev/null). Sie können & 1 durch einen Dateipfad ersetzen, um ein Fehlerprotokoll zu führen, z.2>/tmp/myLog
  4. &am Ende bedeutet: Führen Sie diesen Befehl als Hintergrundaufgabe aus.
Yoichi
quelle
49
Dies sollte die akzeptierte Antwort sein, da sie von viel höherer Qualität ist als die derzeit akzeptierte.
L0j1k
2
@ L0j1k umstritten, OP hat ein gewisses Maß an Verständnis gezeigt, dass für die akzeptierte Antwort eine kleine weitere Erklärung erforderlich ist.
JFA
41
Es geht also nicht so sehr um das OP, sondern um die Tausenden von Menschen, die zu OPs Frage kommen, um Hilfe zu erhalten.
L0j1k
3
Ist es notwendig, stdout und stderr umzuleiten? Würde es genauso gut funktionieren, wenn ich sie überhaupt nicht umleiten würde? Oder wenn ich sie stattdessen in Dateien umgeleitet habe?
Shawn
10
Stdout UND stderr senden an /dev/null? Nizza Protokollierung ... Viel Glück beim Versuch, dies zu debuggen ...
Victor Schröder
138

Sie sollten wirklich versuchen, zu verwenden screen. Es ist ein bisschen komplizierter als nur zu tun nohup long_running &, aber den Bildschirm zu verstehen, wenn Sie nie wieder zurückkommen.

Starten Sie zuerst Ihre Bildschirmsitzung:

user@host:~$ screen

Führen Sie alles aus, was Sie wollen:

wget http://mirror.yandex.ru/centos/4.6/isos/i386/CentOS-4.6-i386-binDVD.iso

Drücken Sie Strg + A und dann d. Erledigt. Ihre Sitzung wird im Hintergrund fortgesetzt.

Sie können alle Sitzungen nach auflisten screen -lsund einige nach screen -r 20673.pts-0.srvBefehl anhängen , wobei 0673.pts-0.srv eine Eintragsliste ist.

Alex Povar
quelle
125

Dies ist eine alte Frage, hat aber bei Google einen hohen Stellenwert. Ich kann fast nicht an die Antworten mit den höchsten Stimmen glauben, weil das Ausführen eines node.js-Prozesses innerhalb einer Bildschirmsitzung mit dem &oder sogar mit demnohup Flag - allesamt - nur Problemumgehungen sind.

Speziell die Screen / TMux-Lösung, die eigentlich als Amateur- Lösung gelten sollte. Screen und Tmux sind nicht dazu gedacht, Prozesse am Laufen zu halten, sondern zum Terminalen von Terminalsitzungen. Es ist in Ordnung, wenn Sie ein Skript auf Ihrem Server ausführen und die Verbindung trennen möchten. Bei einem node.js-Server möchten Sie jedoch nicht, dass Ihr Prozess an eine Terminalsitzung angehängt wird. Das ist zu zerbrechlich. Um die Dinge am Laufen zu halten, müssen Sie den Prozess dämonisieren!

Dafür gibt es viele gute Werkzeuge.

PM2 : http://pm2.keymetrics.io/

# basic usage
$ npm install pm2 -g
$ pm2 start server.js

# you can even define how many processes you want in cluster mode:
$ pm2 start server.js -i 4

# you can start various processes, with complex startup settings
# using an ecosystem.json file (with env variables, custom args, etc):
$ pm2 start ecosystem.json

Ein großer Vorteil, den ich für PM2 sehe, ist, dass es das Systemstart-Skript generieren kann, damit der Prozess zwischen Neustarts bestehen bleibt:

$ pm2 startup [platform]

Wo platformkann sein ubuntu|centos|redhat|gentoo|systemd|darwin|amazon.

forever.js : https://github.com/foreverjs/forever

# basic usage
$ npm install forever -g
$ forever start app.js

# you can run from a json configuration as well, for
# more complex environments or multi-apps
$ forever start development.json

Init-Skripte :

Ich gehe nicht ins Detail, wie man ein Init-Skript schreibt, da ich kein Experte in diesem Thema bin und es für diese Antwort zu lang wäre, aber im Grunde handelt es sich um einfache Shell-Skripte, die durch Betriebssystemereignisse ausgelöst werden. Mehr dazu lesen Sie hier

Docker :

Führen Sie Ihren Server einfach in einem Docker-Container mit der -dOption und voilá aus , Sie haben einen daemonisierten node.js-Server!

Hier ist ein Beispiel für eine Docker-Datei (aus dem offiziellen Handbuch von node.j ):

FROM node:argon

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

Erstellen Sie dann Ihr Image und führen Sie Ihren Container aus:

$ docker build -t <your username>/node-web-app .
$ docker run -p 49160:8080 -d <your username>/node-web-app

Hoffe, das hilft jemandem, auf dieser Seite zu landen. Verwenden Sie immer das richtige Werkzeug für den Job. Es erspart Ihnen viele Kopfschmerzen und über Stunden!

Victor Schröder
quelle
2
Das habe ich gesucht. Gibt es bei der pm2-Lösung eine Möglichkeit, später ein Terminal daran anzuschließen?
Quantumplation
4
@ Quantumplation, nein. Dies ist nicht möglich, da der Prozess nicht in einer interaktiven Sitzung ausgeführt wird. Sie können jedoch das gleiche "Gefühl" haben, indem tail -fSie die Protokolldatei verwenden, die pm2 generiert.
Victor Schröder
1
Sie geben an, dass die screenLösung, die viele Leute finden, eine Problemumgehung ist. Es gibt viele Möglichkeiten, eine bestimmte Aufgabe zu erfüllen. Ich glaube, es kommt vor, dass (unter Berücksichtigung der spezifischen Frage) die spezifische Aufgabe der run as background and never dieHervorragenden für viele erfüllt wird. Es hat auch den zusätzlichen Vorteil, dass der Benutzer wieder darauf zugreifen kann, um erneut zu interagieren und Änderungen vorzunehmen, wenn er dies wünscht. Der Schlüssel ist Komponenten ist backgroundund never die. Alle Lösungen haben bestimmte Boni.
LD James
@ Rakshith Ravi - Ich bin anderer Meinung. Diese erfordern alle zusätzliche Downloads / Software / Tools (mit Ausnahme der Init-Lösung, für die keine Lösung angegeben wurde). Das nohup ist die Lösung. Es ist in Linux integriert und dafür da. Es ist eine Zeile, es ist sauber und es funktioniert jedes Mal wie beabsichtigt, unabhängig von Updates. Menschen sollten wirklich versuchen, die Verwendung von Tools von Drittanbietern für grundlegende Anwendungsfälle wie diesen zu vermeiden. Das Docker-Beispiel (zum Beispiel) ist viel ausführlicher und ressourcenintensiver als der eine einfache Befehl in der Antwort mit der höchsten Bewertung. Liebe Docker, aber nicht dafür.
Jack_Hu
1
@ Jack_Hu, ich habe keine Zweifel am Overhead, aber die nohupLösung erfüllt nicht die Anforderung "Niemals sterben". Wenn Sie keine sehr knifflige trapoder hackige Endlosschleife schreiben , kann ich den Prozess nicht ohne die Verwendung von speziell für diesen Zweck geschriebenen Tools (oder natürlich eines von Ihnen selbst geschriebenen Init-Skripts) dämonisieren.
Victor Schröder
24

Eine andere Lösung lehnt den Job ab

$ nohup node server.js &
[1] 1711
$ disown -h %1
myururdurmaz
quelle
disown ist genau das, wonach ich gesucht habe, aber was macht -h flag? Ich kann es nicht im Handbuch finden
Rimantas Jacikevicius
von der Manpage: Wenn die Option -h angegeben ist, wird nicht jede Jobspezifikation aus der Tabelle entfernt, sondern markiert, damit SIGHUP nicht an den Job gesendet wird, wenn die Shell ein SIGHUP empfängt. Wenn keine Jobspezifikation angegeben ist, bedeutet die Option -a, alle Jobs zu entfernen oder zu markieren.
Myururdurmaz
14

nohupDamit kann das Programm auch nach dem Absterben des Terminals fortgesetzt werden. Ich hatte tatsächlich Situationen, in denen nohupverhindert wurde, dass die SSH-Sitzung korrekt beendet wurde. Daher sollten Sie auch Eingaben umleiten:

$ nohup node server.js </dev/null &

Abhängig von der nohupKonfiguration müssen Sie möglicherweise auch die Standardausgabe und den Standardfehler in Dateien umleiten.

Daniel Gallagher
quelle
7

Ich habe diese Funktion in meiner Shell-RC-Datei, basierend auf der Antwort von @ Yoichi:

nohup-template () {
    [[ "$1" = "" ]] && echo "Example usage:\nnohup-template urxvtd" && return 0
    nohup "$1" > /dev/null 2>&1 &
}

Sie können es folgendermaßen verwenden:

nohup-template "command you would execute here"
thiagowfx
quelle
7

Nohup und Bildschirm bieten großartige Lichtlösungen, um Node.js im Hintergrund auszuführen. Der Node.js-Prozessmanager ( PM2 ) ist ein praktisches Tool für die Bereitstellung. Installieren Sie es mit npm global auf Ihrem System:

npm install pm2 -g

So führen Sie eine Node.js-App als Daemon aus:

pm2 start app.js

Sie können es optional mit Keymetrics.io verknüpfen, einem Überwachungs-SAAS von Unitech.

Donald Derek
quelle
6
$ disown node server.js &

Der Befehl wird aus der Liste der aktiven Aufgaben entfernt und der Befehl an den Hintergrund gesendet

Skynet
quelle
5

Haben Sie über den Befehl nohup gelesen ?

S.Lott
quelle
3

So führen Sie den Befehl als Systemdienst auf Debian mit sysv init aus:

Kopieren Sie das Skelett-Skript und passen Sie es an Ihre Bedürfnisse an. Wahrscheinlich müssen Sie nur einige Variablen festlegen. Ihr Skript erbt feine Standardeinstellungen von /lib/init/init-d-script, wenn etwas nicht Ihren Anforderungen entspricht - überschreiben Sie es in Ihrem Skript. Wenn etwas schief geht, können Sie Details in der Quelle sehen /lib/init/init-d-script. Obligatorische Vars sind DAEMONund NAME. Das Skript wird verwendet start-stop-daemon, um Ihren Befehl auszuführen. In können START_ARGSSie zusätzliche Parameter für start-stop-daemondie Verwendung definieren.

cp /etc/init.d/skeleton /etc/init.d/myservice
chmod +x /etc/init.d/myservice
nano /etc/init.d/myservice

/etc/init.d/myservice start
/etc/init.d/myservice stop

So starte ich einige Python-Sachen für mein Wikimedia-Wiki:

...
DESC="mediawiki articles converter"
DAEMON='/home/mss/pp/bin/nslave'
DAEMON_ARGS='--cachedir /home/mss/cache/'
NAME='nslave'
PIDFILE='/var/run/nslave.pid'
START_ARGS='--background --make-pidfile --remove-pidfile --chuid mss --chdir /home/mss/pp/bin'

export PATH="/home/mss/pp/bin:$PATH"

do_stop_cmd() {
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
        $STOP_ARGS \
        ${PIDFILE:+--pidfile ${PIDFILE}} --name $NAME
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    rm -f $PIDFILE
    return $RETVAL
}

Neben dem Festlegen von vars musste ich überschreiben, do_stop_cmdda Python die ausführbare Datei ersetzt, sodass der Dienst nicht ordnungsgemäß beendet wurde.

user3132194
quelle
3

Abgesehen von den oben genannten coolen Lösungen möchte ich auch Supervisord- und Monit-Tools erwähnen, mit denen der Prozess gestartet, seine Anwesenheit überwacht und im Falle eines Todes gestartet werden kann. Mit 'monit' können Sie auch einige aktive Prüfungen durchführen, z. B. prüfen, ob der Prozess auf eine http-Anfrage reagiert

Krzysztof Księżyk
quelle
3

Für Ubuntu benutze ich Folgendes:

(exec PROG_SH &> / dev / null &)

Grüße

David Lopes
quelle
Kleiner Punkt: 'exec' wird nicht benötigt, wenn PROG_SH eine ausführbare Datei ist. Der Sinn der von David vorgeschlagenen Lösung besteht darin, das Kind von der aktuell laufenden Shell zu trennen. Der Elternteil des Kindes wird zu "pid 1" und ist nicht betroffen, wenn die Shell beendet wird.
SoloPilot
0

Versuchen Sie dies für eine einfache Lösung

cmd & exit

Hunter Frazier
quelle