簡體   English   中英

Express.js應用程序沒有使用server.close()干凈地關閉

[英]Express.js app not shutting down cleanly with server.close()

我正在嘗試在關閉應用程序時正確關閉MongoDB連接。 這是代碼:

var express = require('express')
  , http = require('http')
  , mongoose = require('mongoose')
  , path = require('path');

var app = express();

app.set('port', process.env.PORT || 3000);

mongoose.connect('mongodb://localhost/test');

// some post and get handlers etc. (removed for shorter output)

var server = app.listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
});

function cleanup () {
    server.close(function () {
        console.log("Closed out remaining connections.");
        mongoose.connection.close();
        process.exit();
    });

    setTimeout( function () {
        console.error("Could not close connections in time, forcing shut down");
        process.exit(1);
    }, 30*1000);
}

process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);

當應用程序第一次啟動時,一切都很順利。 當我在啟動后立即按下Ctrl-c時,它會在Closed out remaining connections.干凈地關閉Closed out remaining connections. 信息。 但是,只要應用程序與數據庫交互或甚至提供靜態頁面,我嘗試在此之后關閉它,它將退出並出現以下錯誤:

net.js:1225
    throw new Error('Not running');
          ^
Error: Not running
    at Server.close (net.js:1225:11)
    at process.cleanup (<...>/app.js:77:12)
    at process.EventEmitter.emit (events.js:92:17)
    at Signal.wrap.onsignal (node.js:756:46)
22 Aug 15:15:28 - [nodemon] exiting

是什么原因造成了這個錯誤以及我如何解決它?

調用server.close時,會檢查兩個屬性。

   handle<tcp handle>
   connections

server.close的負責代碼片段負責此錯誤;

  if (!this._handle) {
    // Throw error. Follows net_legacy behaviour.
    throw new Error('Not running');
  }

只有當handle === null和connections === 0時,才會調用傳遞給close的回調。

案例:服務器啟動並發送信號,沒有服務。

在關閉前調用;

  handle === TCP handle.
  connection===0;

關閉句柄后=== null; 連接=== 0;

調用回調。

案例:服務器啟動並在請求服務器之后發送信號。

在關閉前調用;

  handle === TCP.handle;
  connection===1;

關閉句柄后=== null; 連接=== 1;

沒有回調被觸發。

第二次按ctrl-c

在關閉前調用;

  handle === null;
  connection===1;

因為句柄=== null,檢查會拋出你看到的錯誤。

服務器打開連接的原因是因為您正在發送Connection: keep-alive標頭。

摩根的答案干凈地關閉了服務器上的所有連接,斷開了所有客戶端的連接。

如果您只是測試您的應用程序並希望在測試之前/之后干凈地關閉它,我建議發送Connection: close header和server.close()將按預期工作。

我不認為設置server._connections = 0實際上會關閉連接。 它只是滿足了執行回調的條件。

您可能想嘗試這樣的事情:

// Everything else how you had it before ...

var sockets = [];

server.on('connection', function(socket) {
  sockets.push(socket);
});

function cleanup () {
  server.close(function () {
    console.log("Closed out remaining connections.");
     // mongoose.connection.close(); Might want to comment this out
    process.exit();
  });

  // Add this part to manually destroy all the connections.
  sockets.forEach(function(socket) {
    socket.destroy();
  });

  // setTimeout() ...
}

暫無
暫無

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

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