2013-06-30 16 views
9

Ich habe einen Nodejs-Server ausgeführt Express zu Server aus http Anrufe. Gibt es einen empfohlenen Ansatz, um den Server ordnungsgemäß herunterzufahren, wenn etwas Schlimmes passiert? Soll ich den Server irgendwie laufen lassen?Nodejs/Express, ordnungsgemäß heruntergefahren

I.E. Bei einer nicht abgefangenen Ausnahme hält der Server einfach an. Ich denke, das führt dazu, dass die Verbindung zu verbundenen Clients unterbrochen wird und sie keine Antwort zurückgeben.

Sollte ich:

  1. Warten für alle HTTP-Verbindungen zu beenden, bevor ich den Server erlauben zu sterben (und es dann neu starten).
  2. Oder sollte ich versuchen, den Server vor dem Aussterben zu stoppen?

ist das richtig?

process.on('exit', function() { 
    console.log('About to exit, waiting for remaining connections to complete'); 
    app.close(); 
}); 

In diesem Fall wird ein Fehler kann den Server verlassen in einem undefinierten Zustand und der Server wird auch weiterhin beenden verbleibenden Verbindungen geworfen wurden.

Gibt es eine gute Möglichkeit, mit Fehlern umzugehen, oder sollte ich den Server sterben lassen und neu starten?

Antwort

6

Versuchen Sie nichts Ungewöhnliches mit unbehandelten Ausnahmen zu machen. Lass den Server sterben.

Wenn ein Routen-Handler eine Ausnahme auslöst, fängt Express diese einfach ab und gibt HTTP 500 an den Client zurück. Da Express die Ausnahme abgefangen hat, stürzt Ihr Server nicht ab.

Was normalerweise einen Server zum Absturz bringt, ist, wenn eine Ausnahme innerhalb eines Callbacks ausgelöst wird. zum Beispiel:

app.get('/foo', function(req, res) { 
    db.query(..., function(err, r) { 
     throw new Error(); // oops, we'll crash 
    }); 
}); 

Da natürlich der Rückruf außerhalb des Express-Router Call-Stack ausgeführt wird, gibt es keine Möglichkeit, es mit einer bestimmten Anforderung zu verknüpfen. Sie können jedoch gegen eine solche Situation:

app.get('/foo', function(req, res, next) { 
    db.query(..., function(err, r) { 
     try { 
      throw new Error(); 
     } catch(ex) { 
      next(ex); 
     } 
    }); 
}); 

Express' next Funktion nimmt einen Fehler als erstes Argument. Wenn Sie next mit einem Fehler Argumente nennen, wird es die Verarbeitung Routen stoppen und suchen Sie nach einem error handler oder Rückkehr nur 500.

Natürlich alles in try/catch Verpackung ist wahrscheinlich übertrieben; Die meisten Dinge werfen keine Ausnahmen. Sie sollten dies nur tun, wenn Sie wissen etwas werfen könnte. Andernfalls könnten Sie in einen sehr inkonsistenten Zustand geraten, indem Sie Ausnahmen verschlucken.

Es ist wichtig, daran zu denken, dass Ihre Anwendung in einem undefinierten Zustand ist, sobald eine unerwartete Ausnahme ausgelöst wird. Es ist möglich, dass die Problemanforderung nicht ausgeführt wird und Ihre App nie neu gestartet wird. Oder irgendeine andere seltsame Sache könnte passieren. (War es ein Datenbankproblem? Dateisystem? Beschädigter Speicher?)

Diese Arten von Situationen sind unglaublich schwierig zu diagnostizieren, viel weniger zu debuggen. Es ist sicherer und wohl besser, einfach schnell zu versagen, abstürzen zu lassen und den Server schnell neu zu starten. Ja, alle Clients, die zufällig verbunden sind, werden abgeschnitten, aber es ist einfach genug, sie einfach erneut zu versuchen.

Wenn Sie sich Sorgen um die Verfügbarkeit machen, verwenden Sie die cluster module, so dass Sie mehrere (in der Regel Anzahl der CPU-Kerne) Serverprozesse ausführen, und ein Absturz wird nicht die gesamte Website herunterbringen.

+1

Dies ist eine großartige Erklärung. Eine Sache ist mir noch unklar. 'Es ist wichtig, daran zu denken, dass Ihre Anwendung in einem undefinierten Zustand ist, sobald eine unerwartete Ausnahme ausgelöst wird. Es ist möglich, dass die Problemanforderung niemals abgeschlossen wird und Ihre App nie neu gestartet wird ". Das klingt so, als ob ich App nicht anrufen sollte.schließen(); auf Prozess 'exit'. Wahr? – lostintranslation

+0

Der Aufruf von 'app.close()' im 'process'' exit'-Handler ist zwecklos: die [docs say] (http://nodejs.org/api/process.html#process_event_exit) * "Die Hauptereignisschleife wird nicht mehr ausgeführt werden, nachdem der 'exit' Callback beendet ist. '* Mit anderen Worten, das' exit'-Ereignis informiert Sie über den Prozess ** wird ** enden, nachdem Ihre Funktion zurückkehrt. Das Schließen eines Netzwerk-Listeners ist sinnlos, da es kein nächstes Häkchen gibt; Der Code zum Akzeptieren einer eingehenden Verbindung wird niemals ausgeführt werden können. – josh3736

+0

genial, danke! – lostintranslation

5

NodeJS wird heruntergefahren, wenn nichts erwartet wird; Während der HTTP-Server auf Verbindungen wartet, wird der Knoten weiterhin ausgeführt.

server.close([callback])

Stoppt den Server von neuen Verbindungen akzeptiert und hält Verbindungen vorhanden sind. Diese Funktion ist asynchron, der Server wird schließlich geschlossen, wenn alle Verbindungen beendet sind und der Server ein close Ereignis ausgibt. Optional können Sie einen Rückruf übergeben, um auf das Ereignis close zu warten.

Nachdem Sie dies getan haben, wird der Server weiter ausgeführt, bis die letzte Verbindung beendet ist und dann ordnungsgemäß heruntergefahren. Wenn Sie nicht auf das Beenden von Verbindungen warten möchten, können Sie socket.end() oder socket.destroy() für Ihre verbleibenden Verbindungen verwenden.

Siehe http://nodejs.org/api/net.html


process.on('exit', function() { 
    console.log('About to exit, waiting for remaining connections to complete'); 
    app.close(); 
}); 

Diese Funktion sollte ausgeführt werden, wenn Knoten vorhanden ist und nicht tatsächlich Knoten sagen zu verlassen. Hier ist ein Weg, können Sie Ihren Prozess beenden, aber es wäre nicht ordnungsgemäß beenden:

process.exit([code])

Beendet den Prozess mit dem angegebenen Code. Wenn nicht angegeben, verwendet exit den 'Erfolgscode' 0.

mit einem ‚Versagen‘ Code verlassen:

process.exit(1); Die Schale, die Knoten ausgeführt sollte den Beendigungscode als 1 sehen.

Siehe http://nodejs.org/api/process.html


Ich hoffe, das hilft!

Verwandte Themen