如何立即closuresNode.js http服务器?

我有一个包含http(s)服务器的Node.js应用程序。

在特定情况下,我需要以编程方式closures此服务器。 我现在正在调用它的close()函数,但是这并没有帮助,因为它等待任何保持活动的连接首先完成。

所以,基本上,这closures了服务器,但只有最less120秒的等待时间。 但是我希望服务器立即closures – 即使这意味着与当前处理的请求分离。

我不能做的是一个简单的

 process.exit(); 

因为服务器只是应用程序的一部分,应用程序的其余部分应该保持运行。 我正在寻找的是概念上的东西,如server.destroy(); 或类似的东西。

我怎么能做到这一点?

PS:连接的保持活动超时通常是必需的,因此减less这个时间不是一个可行的select。

诀窍是你需要订阅服务器的connection事件,它给你新的连接套接字。 你需要记住这个套接字,之后直接调用server.close() ,使用socket.destroy()销毁这个套接字。

此外,您需要侦听套接字的close事件,以便将其从arrays中移除,因为它的保持活动超时会耗尽。

我写了一个小示例应用程序,您可以用来演示此行为:

 // Create a new server on port 4000 var http = require('http'); var server = http.createServer(function (req, res) { res.end('Hello world!'); }).listen(4000); // Maintain a hash of all connected sockets var sockets = {}, nextSocketId = 0; server.on('connection', function (socket) { // Add a newly connected socket var socketId = nextSocketId++; sockets[socketId] = socket; console.log('socket', socketId, 'opened'); // Remove the socket when it closes socket.on('close', function () { console.log('socket', socketId, 'closed'); delete sockets[socketId]; }); // Extend socket lifetime for demo purposes socket.setTimeout(4000); }); // Count down from 10 seconds (function countDown (counter) { console.log(counter); if (counter > 0) return setTimeout(countDown, 1000, counter - 1); // Close the server server.close(function () { console.log('Server closed!'); }); // Destroy all open sockets for (var socketId in sockets) { console.log('socket', socketId, 'destroyed'); sockets[socketId].destroy(); } })(10); 

基本上,它做的是启动一个新的HTTP服务器,从10计数到0,并在10秒后closures服务器。 如果没有连接build立,服务器立即closures。

如果连接已经build立并且仍然打开,则会被销毁。 如果已经自然死亡,那么只有一个消息打印出来。

https://github.com/isaacs/server-destroy库提供了一个简单的方法来;destroy()一个服务器的问题所需的行为(通过跟踪打开的连接和销毁服务器上的每个销毁,如其他答案)。

我find了一个方法来做到这一点,而不必跟踪连接或强制他们closures。 我不确定在Node版本上有多可靠,或者是否有任何负面影响,但对于我所做的事情来说,它似乎工作得很好。 诀窍是在调用close方法之后立即使用setImmediate来发出“close”事件。 这是这样工作的:

 server.close(callback); setImmediate(function(){server.emit('close')}); 

至less对我来说,这最终会释放这个端口,以便在callback被调用的时候启动一个新的HTTP(S)服务。 现有的连接保持打开。 我正在使用它在更新Let's Encrypt证书后自动重新启动HTTPS服务。

如果在closures服务器之后需要保持这个进程,Golo Roden的解决scheme可能是最好的。

但是,如果您正在closures服务器,作为正常closures进程的一部分,则只需要这样做:

 var server = require('http').createServer(myFancyServerLogic); server.on('connection', function (socket) {socket.unref();}); server.listen(80); function myFancyServerLogic(req, res) { req.connection.ref(); res.end('Hello World!', function () { req.connection.unref(); }); } 

基本上,服务器使用的套接字只会在实际提供请求时使进程保持活动状态。 当他们只是坐在那里(因为一个Keep-Alive连接),只要没有别的东西让进程保持活跃状态​​,调用server.close()就会closures进程。 如果在服务器closures后需要做其他事情,作为正常关机的一部分,您可以挂接到process.on('beforeExit', callback)来完成正常的closures过程。

正如其他人所说,解决scheme是跟踪所有打开的套接字并手动closures它们。 我的节点软件包killable可以为你做这个。 一个例子(使用快递,但你可以打电话在任何http.server实例上使用killable):

 var killable = require('killable'); var app = require('express')(); var server; app.route('/', function (req, res, next) { res.send('Server is going down NOW!'); server.kill(function () { //the server is down when this is called. That won't take long. }); }); var server = app.listen(8080); killable(server); 

我最好的猜测将是手动杀死连接(即强行closures它的sockets)。

理想情况下,应该通过挖掘服务器的内部并手动closures它的套接字来完成。 或者,可以运行一个相同的shell命令(只要服务器具有适当的权限)。

还有另一个nodejs软件包来执行关机查杀连接: http-shutdown ,在撰写本文时似乎是合理的维护(2016年9月),并在NodeJS 6.x上为我工作

从文档

用法

目前有两种方法来使用这个库。 首先是显式包装Server对象:

 // Create the http server var server = require('http').createServer(function(req, res) { res.end('Good job!'); }); // Wrap the server object with additional functionality. // This should be done immediately after server construction, or before you start listening. // Additional functionailiy needs to be added for http server events to properly shutdown. server = require('http-shutdown')(server); // Listen on a port and start taking requests. server.listen(3000); // Sometime later... shutdown the server. server.shutdown(function() { console.log('Everything is cleanly shutdown.'); }); 

第二个是隐式地将原型function添加到Server对象:

 // .extend adds a .withShutdown prototype method to the Server object require('http-shutdown').extend(); var server = require('http').createServer(function(req, res) { res.end('God job!'); }).withShutdown(); // <-- Easy to chain. Returns the Server object // Sometime later, shutdown the server. server.shutdown(function() { console.log('Everything is cleanly shutdown.'); }); 

process.exit(代码); //代码0代表成功,代码1代表失败

Interesting Posts