簡體   English   中英

為什么從不調用 server.close 回調?

[英]Why is server.close callback never invoked?

如果拋出未處理的錯誤,我正在嘗試“優雅地”關閉 net.Server 實例(使用 app.listen() 創建)。 服務器創建發生在我的 bin/www 腳本中。 所有錯誤處理和路由中間件配置都在 index.js 中定義。

在我的應用程序配置模塊(index.js)中,我有錯誤處理中間件,用於檢查每個錯誤是否得到處理。 如果錯誤未得到處理,則會發出“關閉”事件。

注意:每個 req 和 res 都包含在一個域中。 我正在使用express-domain-middleware中間件模塊來偵聽每個 req 域上的錯誤事件並將錯誤路由到我的錯誤處理。 我只提到這一點,以防它可能是罪魁禍首。

'close_server' 事件處理程序應該:

  1. 關閉服務器,不接受新連接。
  2. 完成所有打開的連接后關閉當前進程。
  3. 如果 10 秒后服務器還沒有關閉,則強制關閉進程。

提供給 server.close() 的可選回調似乎從未被調用,我不知道為什么。 為了測試這一點,我提出了一個引發錯誤的請求。 該進程僅在計時器到期(經過 10 秒)后關閉。

服務器中是否有東西保持打開連接? 為什么從不調用 server.close() 回調?

謝謝!

更新我正在使用 Chrome 向服務器發出請求。 瀏覽器似乎保持打開連接。 如果我使用 curl 發出請求,它將按預期工作。

看到這個問題

index.js

     app.use(function (err, req, res, next) {
        if (typeof err.statusCode !== 'undefined') {
            if (err.statusCode >= 500) {
                Logger.error({error: err});
                return next(err);
            } else {
                Logger.warn({warn: err});
                return next(err);
            }
        } else {
            //The error is un-handled and the server needs to go bye, bye
            var unhandledError = new UnhandledError(util.format('%s:%s', req.method, req.originalUrl), 'Server shutting down!', err.stack, 500);
            Logger.fatal({fatal: unhandledError});
            res.status(500).send('Server Error');
            app.emit('close_server', unhandledError);
        }
    });

斌/萬維網

#!/usr/bin/env node
var app = require('../index');    
var port = config.applicationPort;

app.set('port', port);
var server = app.listen(app.get('port'));

/*
 * Wait for open connections to complete and shut server down.
 * After 10 seconds force process to close.
 * */
app.on('close_server', function () {
    server.close(function () {
        console.log('Server Closed.');
        process.exit()
    });
    setTimeout(function () {
        console.log('Force Close.');
        process.exit()
    }, 10 * 1000);
});

server.close()不會關閉打開的客戶端連接,它只會停止接受連接。

因此,很可能是Chrome發送帶有Connection: keep-alive的請求,這意味着出於效率原因(為了能夠在同一連接上發出多個請求),連接保持打開狀態一段時間,而curl可能使用Connection: close服務器響應后立即斷開連接。

正如@mscdex 提到的, server.close永遠不會在瀏覽器發送請求Connection: keep-alive時運行其回調。

我就是這樣解決這個問題的。 我等待 5 秒鍾讓服務器關閉,然后強制退出。

process.on('SIGINT', gracefulShutdown)
process.on('SIGTERM', gracefulShutdown)

function gracefulShutdown (signal) {
  if (signal) {
    console.log(`\nReceived signal ${signal}`)
  }
  console.log('Gracefully closing http server')

  try {
    // gives 5 seconds for the server to shutdown, after which forces exit
    setTimeout(() => process.exit(0), 5000)

    server.close(function (err) {
      if (!err) {
        console.log('http server closed successfully. Exiting!')
      }
      process.exit(err ? 1 : 0)
    })
  } catch (err) {
    console.error('There was an error')
    setTimeout(() => process.exit(1), 500)
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM