Nodejs / express, выключение изящно
У меня есть сервер nodejs, на котором выполняется express для сервера http-вызовов. Есть ли рекомендуемый подход к закрытию сервера изящно, если что-то плохое случится? Должен ли я как-то оставить сервер работать?
т. е. на необработанном исключении сервер просто останавливается, я думаю, что это убьет подключенных клиентов и не вернет им ответ.
Я:
- дождитесь завершения всех http-соединений, прежде чем я разрешу серверу die (а затем перезапустите его).
- или я должен попытаться остановить сервер от смерти?
это правильно?
process.on('exit', function () {
console.log('About to exit, waiting for remaining connections to complete');
app.close();
});
в этом случае может возникнуть ошибка, оставляющая сервер в неопределенном состоянии, и сервер продолжит завершение оставшихся подключений.
есть ли хороший способ обрабатывать ошибки, или я должен позволить серверу умереть и перезапустить?
3 ответов
не пытайтесь делать ничего необычного с необработанными исключениями. Пусть сервер умрет.
как правило, если обработчик маршрута выдает исключение, Express просто поймает его и вернет HTTP 500 клиенту. Поскольку Express поймал исключение, ваш сервер не аварийно завершит работу.
обычно происходит то, что сбивает сервер, когда исключение выбрасывается внутри обратного вызова; например:
app.get('/foo', function(req, res) {
db.query(..., function(err, r) {
throw new Error(); // oops, we'll crash
});
});
потому что обратный вызов естественно выполняется вне Экспресс-стек вызовов маршрутизатора, нет способа связать его с определенным запросом. Однако вы можете остерегаться такой ситуации:
app.get('/foo', function(req, res, next) {
db.query(..., function(err, r) {
try {
throw new Error();
} catch(ex) {
next(ex);
}
});
});
Экспресс' next
функция принимает ошибку в качестве первого аргумента. Если вы позвоните next
С аргументом ошибки он прекратит обработку маршрутов и будет искать обработчик ошибок, или просто верните 500.
конечно, оборачивая все на try
/catch
вероятно, излишне; большинство вещей на самом деле не бросайте исключения. Вы должны сделать это, только если вы знаю что-то может бросить. В противном случае вы можете оказаться в очень трудном для отладки несогласованном состоянии, проглотив исключения.
важно помнить, что после неожиданного исключения, ваше приложение в неопределенном состоянии. Возможно, что запрос на проблему никогда не будет завершен, и ваше приложение никогда не перезапустится. Или может произойти еще много странных вещей. (Это была проблема с базой данных? Файловая система? Поврежденная память?)
такие ситуации невероятно трудно диагностировать, а тем более отлаживать. Безопаснее и, возможно, лучше просто быстро потерпеть неудачу, сбой и быстро перезагрузить сервер. Да, все подключенные клиенты будут отрезаны, но для них достаточно просто повторить попытку.
если вы беспокоитесь о доступности, используйте модуль кластера так что у вас есть несколько (обычно количество CPU Core) серверные процессы запущены, и один сбой не приведет к сбою всего сайта.
NodeJS завершит работу, когда он не ожидает, что что-то произойдет; в то время как http-сервер ждет на узле соединений остается запущенным.
server.close([callback])
останавливает сервер от принятия новых подключений и сохраняет существующие подключение. Эта функция асинхронна, сервер окончательно закрыто, когда все соединения завершены и сервер выдает
close
событие. Дополнительно можно передать обратный вызов для прослушиванияclose
событие.
после этого сервер будет продолжать работать до тех пор, пока не завершится последнее соединение, а затем выключится изящно.
если вы не хотите ждать завершения соединения, вы можете использовать socket.end()
или socket.destroy()
на остальные соединения.
см.http://nodejs.org/api/net.html
process.on('exit', function () { console.log('About to exit, waiting for remaining connections to complete'); app.close(); });
эта функция должна выполняться, когда узел существует, а не фактически скажите узлу выйти. Вот один из способов, которым вы можете закончить свой процесс, но он не закончится изящно:
process.exit([code])
завершает процесс с указанным кодом. Если опущено, exit использует код успеха
0
.для выхода с кодом "сбой":
process.exit(1);
оболочка, которая выполняла узел, должна видеть код выхода as1
.
посмотреть http://nodejs.org/api/process.html
надеюсь, это поможет!
Если вы используете express, вы можете использовать этот модуль npm для изящной обработки остановок.