简体   繁体   English

如何正确关闭 node-express 服务器?

[英]how to properly close node-express server?

I need to close server after getting callback from /auth/github/callback url. With usual HTTP API closing server is currently supporting with server.close([callback]) API function, but with node-express server i'm getting TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close'我需要在从/auth/github/callback url 获得回调后关闭服务器。使用通常的HTTP API关闭服务器目前支持server.close([callback]) API function,但是对于 node-express 服务器我得到TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close' TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close' error. TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close'错误。 And I don't know how to find information to solve this problem.而且我不知道如何查找信息来解决这个问题。
How should I close express server?我应该如何关闭快速服务器?

NodeJS configuration notes: NodeJS配置注意事项:

$ node --version
v0.8.17
$ npm --version
1.2.0
$ npm view express version
3.0.6

Actual application code:实际应用代码:

var app = express();

// configure Express
app.configure(function() {
    // … configuration
});

app.get(
    '/auth/github/callback',
    passport.authenticate('github', { failureRedirect: '/login' }),
    function(req, res) {
        res.redirect('/');

        setTimeout(function () {
            app.close();
            // TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close'
        }, 3000)
    }
);

app.listen('http://localhost:5000/');

Also, I have found 'nodejs express close…' but I don't sure if I can use it with code I have: var app = express();另外,我发现“nodejs express close…”但我不确定我是否可以将它与我的代码一起使用: var app = express(); . .

app.listen() returns http.Server . app.listen()返回http.Server You should invoke close() on that instance and not on app instance.您应该在该实例而不是app实例上调用close()

Ex.前任。

app.get(
    '/auth/github/callback',
    passport.authenticate('github', { failureRedirect: '/login' }),
    function(req, res) {
        res.redirect('/');

        setTimeout(function () {
            server.close();
            // ^^^^^^^^^^^
        }, 3000)
    }
);

var server = app.listen('http://localhost:5000/');

You can inspect sources: /node_modules/express/lib/application.js您可以检查来源: /node_modules/express/lib/application.js

In express v3 they removed this function.在 express v3 中,他们删除了这个功能。

You can still achieve the same by assigning the result of app.listen() function and apply close on it:您仍然可以通过分配app.listen()函数的结果并对其应用 close 来实现相同的目的:

var server = app.listen(3000);
server.close((err) => {
  console.log('server closed')
  process.exit(err ? 1 : 0)
})

https://github.com/visionmedia/express/issues/1366 https://github.com/visionmedia/express/issues/1366

If any error occurs in your express app then you must have to close the server and you can do that like below-如果您的快速应用程序中发生任何错误,那么您必须关闭服务器,您可以执行以下操作 -

var app = express();
var server = app.listen(process.env.PORT || 5000)

If any error occurs then our application will get a signal named SIGTERM .如果发生任何错误,我们的应用程序将收到一个名为SIGTERM的信号。 You can read more SIGTERM here - https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html您可以在此处阅读更多 SIGTERM - https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html

process.on('SIGTERM', () => {
  console.info('SIGTERM signal received.');
  console.log('Closing http server.');
  server.close((err) => {
    console.log('Http server closed.');
    process.exit(err ? 1 : 0);
  });
});

I have answered a variation of "how to terminate a HTTP server" many times on different support channels.我在不同的支持渠道上多次回答了“如何终止 HTTP 服务器”的变体。 Unfortunately, I couldn't recommend any of the existing libraries because they are lacking in one or another way.不幸的是,我不能推荐任何现有的库,因为它们以一种或另一种方式 缺乏 I have since put together a package that (I believe) is handling all the cases expected of graceful express.js HTTP(S) server termination.从那以后,我已经组合了一个包,(我相信)它可以处理优雅的 express.js HTTP(S) 服务器终止所期望的所有情况。

https://github.com/gajus/http-terminator https://github.com/gajus/http-terminator

The main benefit of http-terminator is that: http-terminator的主要好处是:

  • it does not monkey-patch Node.js API它没有猴子补丁 Node.js API
  • it immediately destroys all sockets without an attached HTTP request它会立即销毁所有没有附加 HTTP 请求的套接字
  • it allows graceful timeout to sockets with ongoing HTTP requests它允许对正在进行的 HTTP 请求的套接字进行优雅的超时
  • it properly handles HTTPS connections它正确处理 HTTPS 连接
  • it informs connections using keep-alive that server is shutting down by setting a connection: close header它通过设置连接来通知连接使用保持活动服务器正在关闭:关闭标头
  • it does not terminate the Node.js process它不会终止 Node.js 进程

calling server.close does the job调用server.close完成这项工作

server.close((err) => {
  console.log('server closed')
  process.exit(err ? 1 : 0)
})

also it is good to listen for system(user) signals and shutdown gracefully on them too, for that you should listen on both SIGTERM and SIGINT监听系统(用户)信号并优雅地关闭它们也是很好的,因为你应该同时监听SIGTERMSIGINT

const port = process.env.PORT || 5000;
const server = app.listen(port);
console.log(`listening on port:${port}`);
for (let signal of ["SIGTERM", "SIGINT"])
    process.on(signal, () => {
        console.info(`${signal} signal received.`);
        console.log("Closing http server.");
        server.close((err) => {
            console.log("Http server closed.");
            process.exit(err ? 1 : 0);
        });
    });

Old question but now Node v18.2.0 introduced server.closeAllConnections() .老问题,但现在 Node v18.2.0引入了server.closeAllConnections() It should be noted that server.close never runs its callback when the browser sends the request Connection: keep-alive , because server.close only stops the server from accepting new connections, it does not close old connections.需要注意的是server.close不会在浏览器发送Connection: keep-alive请求时运行它的回调,因为server.close只是阻止服务器接受新连接,它不会关闭旧连接。

Before Node v18.2.0 I tackled this problem by waiting 5 seconds for the server to shutdown, after which it would force exit.在 Node v18.2.0 之前,我通过等待 5 秒让服务器关闭来解决这个问题,之后它会强制退出。

This code encompasses both situations此代码包含两种情况

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

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

  // closeAllConnections() is only available from Node v18.02
  if (server.closeAllConnections) server.closeAllConnections()
  else setTimeout(() => process.exit(0), 5000)

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

Most answers call process.exit() , I don't think this is a good idea.大多数答案都调用process.exit() ,我认为这不是一个好主意。 You probably need to perform some teardown, also it's simply not needed.您可能需要执行一些拆解,也根本不需要。

const server = app.listen(port);

server.on('close', () => {
  // Perform some teardown, for example with Knex.js: knex.destroy()
});

// FYI Docker "stop" sends SIGTERM
// If SIGTERM is not catched, Docker is forced to kill the container after ~10s
// and this provokes an exit code 137 instead of 0 (success)
process.on('SIGTERM', () => server.close());

Check Express.js 4.x documentation: https://expressjs.com/en/advanced/healthcheck-graceful-shutdown.html#graceful-shutdown检查 Express.js 4.x 文档: https://expressjs.com/en/advanced/healthcheck-graceful-shutdown.html#graceful-shutdown

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM