Сценарий : API отдыха Nodejs, использующий http.createServer()
Цель : Когда приходит SIGNINT
(в моем случае из-за перезагрузки PM2) сделать изящноезавершение работы сервера, затем отключение соединения с БД и затем мирный выход.
Код :
// index.js
server.keepAliveTimeout = 10
process.on('SIGINT', () => {
server.close(err => {
// close the DB
...
process.exit(0)
})
})
// the code related to any API response
const headers = {
...
'Connection': 'close'
}
response.writeHead(statusCode, headers)
return response.end(JSON.stringify(data))
Проблема : server.close
обратный вызов никогда не срабатывает.Процесс PM2 достигает тайм-аута через (в моем случае) 20 секунд, и поэтому отключение больше не происходит корректно.
Причина расследования : Обратный вызов срабатывает, если нет открытых подключений браузера (например, если никто не вызывает API) или если вызов API выполняется с помощью Firefox.Вместо Chrome я могу видеть в chrome://net-internals/#sockets
1 простое transport_socket_pool после запуска запроса.В этом случае обратный вызов close
не срабатывает.Как только я очищаю незанятые сокеты в Chrome, обратный вызов срабатывает правильно.Обратите внимание, что в режиме инкогнито Chrome сокет не остается в режиме ожидания, а закрывается должным образом, поэтому обратный вызов срабатывает.
Вопросы :
- Это ошибка вХром или нормальное поведение?
- Разве заголовка
Connection: close
и короткого keepAliveTimeout
не должно быть достаточно, чтобы уведомить любого клиента, что он не должен держать ни один сокет открытым так долго? - Как правильно обрабатывать клиенты, которые мешают завершить
server.close
? - Должен ли я пройти по всем созданным сокетам и закрыть их вручную?