正常关闭 node.JS HTTP 服务器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5263716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:55:47  来源:igfitidea点击:

Graceful shutdown of a node.JS HTTP server

httpnode.jsexit

提问by Bryan Field

Here is a simple webserver I am working on

这是我正在开发的一个简单的网络服务器

var server = require("http").createServer(function(req,resp) {
    resp.writeHead(200,{"Content-Type":"text/plain"})
    resp.write("hi")
    resp.end()
    server.close()
})
server.listen(80, 'localhost')
// The shortest webserver you ever did see! Thanks to Node.JS :)

Works great except for keep-alive. When the first request comes in, server.closegets called. But the process does not end. Actually the TCP connection is still open which allows another request to come through which is what I am trying to avoid.

除了保持活动之外,效果很好。当第一个请求进来时,server.close被调用。但这个过程并没有结束。实际上 TCP 连接仍然打开,这允许另一个请求通过,这是我试图避免的。

How can I close existing keep-alive connections?

如何关闭现有的保持活动连接?

采纳答案by Ricardo Tomasi

You can call request.connection.destroy()in the response callback. That will close the request connection.

您可以调用request.connection.destroy()响应回调。这将关闭请求连接。

It will also end your process since there is nothing left to do, the end result is the same as calling process.exit()right there.

它也将结束您的过程,因为没有什么可做的,最终结果与在process.exit()那里调用相同。

回答by Ben Last

You can control the idle timeout for a connection, so you can set how long a keep-alive connection will remain open. For example:

您可以控制连接的空闲超时,因此您可以设置保持活动连接保持打开状态的时间。例如:

server=require('http').createServer(function(req,res) {
    //Respond
    if(req.url.match(/^\/end.*/)) {
        server.close();
        res.writeHead(200,{'Content-Type':'text/plain'});
        res.end('Closedown');
    } else {
        res.writeHead(200,{'Content-Type':'text/plain'});
        res.end('Hello World!');
    }
}).listen(1088);
//Set the idle timeout on any new connection
server.addListener("connection",function(stream) {
    stream.setTimeout(4000);
});

We can test this with netcat:

我们可以用 netcat 测试一下:

ben@quad-14:~/node$ echo -e "GET /test HTTP/1.1\nConnection: keep-alive\n\n" | netcat -C -q -1 localhost 1088
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: keep-alive
Transfer-Encoding: chunked

c
Hello World!
0

after 4 seconds, the connection closes

after 4 seconds, the connection closes

And now we can show that closing the server works: after all idle connections are dropped, the server exits:

现在我们可以证明关闭服务器是有效的:在所有空闲连接都被删除后,服务器退出:

ben@quad-14:~/node$ echo -e "GET /end HTTP/1.1\nConnection: keep-alive\n\n" | netcat -C -q -1 localhost 1088
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: keep-alive
Transfer-Encoding: chunked

9
Closedown
0

after 4 seconds, the connection closes and the server exits

after 4 seconds, the connection closes and the server exits

回答by Joshua Wise

If you're closing the server as part of a graceful shutdown of the process, you just need this:

如果您在正常关闭进程的过程中关闭服务器,您只需要:

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();
    });
}

Basically, the sockets that your server uses will only keep the process alive while they're actually serving a request. While they're just sitting there idly (because of a Keep-Alive connection), a call to server.close()will close the process, as long as there's nothing else keeping the process alive. If you need to do other things after the server closes, as part of your graceful shutdown, you can hook into process.on('beforeExit', callback)to finish your graceful shutdown procedures.

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