Express.js应用程序没有使用server.close()干净地关闭

时间:2013-08-22 13:30:46

标签: node.js mongodb express application-shutdown

我正在尝试在应用关闭时正确关闭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.消息干净地关闭。但是,只要应用程序与数据库交互或甚至提供静态页面,我尝试在此之后关闭它,它会退出并出现以下错误:

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

任何想法是什么导致了这个错误以及我如何解决它?

3 个答案:

答案 0 :(得分:4)

调用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;

关闭后       处理===空;       连接=== 0;

调用回调。

案例:服务器启动并在请求服务器之后发送信号。

在关闭之前调用;

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

关闭后       handle === null;       连接=== 1;

没有触发回调。

第二次按ctrl-c

在关闭之前调用;

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

因为句柄=== null,检查会抛出你看到的错误。

答案 1 :(得分:2)

您的服务器打开连接的原因是您发送了Connection: keep-alive标题。

Morgan的回答干净地关闭了服务器上的所有连接,断开了所有客户端的连接。

如果您只是测试您的应用程序并希望在测试之前/之后干净地关闭它,我建议发送Connection: close标题,server.close()将按预期工作。

答案 2 :(得分:1)

我不认为设置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() ...
}