You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express服务优雅关闭时如何停止接收新请求仅处理存量请求并响应

Express 服务优雅关闭实现方案

核心实现思路

  • 触发关闭流程时,首先标记服务为正在关闭状态,拒绝所有新进来的请求,返回503 Service Unavailable状态码,通知上游流量调度组件停止向当前节点转发请求
  • 统计当前正在处理的活跃请求数量,所有存量请求处理完成后再关闭服务进程
  • 配置最大等待超时时间,避免极端情况下进程无限挂起无法退出

具体代码实现

首先添加全局状态标记和活跃请求计数器,对应的中间件要放在所有路由规则之前,确保所有请求都会经过统计逻辑:

// 全局状态标记
let isShuttingDown = false;
let activeRequests = 0;

// 请求统计中间件
app.use((req, res, next) => {
  if (isShuttingDown) {
    // 已进入关闭流程,直接拒绝新请求
    res.status(503).send('Service is shutting down');
    return;
  }
  activeRequests++;
  // 响应结束后减少活跃请求计数
  res.on('finish', () => {
    activeRequests--;
    // 处于关闭流程且无活跃请求时直接退出
    if (isShuttingDown && activeRequests === 0) {
      process.exit(0);
    }
  });
  next();
});

之后修改关闭逻辑,同时监听系统的进程退出信号触发优雅关闭流程:

function gracefulShutdown() {
  console.log('Start graceful shutdown process');
  // 标记关闭状态,停止受理新请求
  isShuttingDown = true;

  // 停止监听新端口
  server.close(() => {
    log('HTTP server closed');
  });

  // 配置最大等待时间,这里设为30秒覆盖你最长20秒的接口耗时,超时强制退出
  setTimeout(() => {
    console.log(`Force shutdown after timeout, remaining active requests: ${activeRequests}`);
    process.exit(1);
  }, 30 * 1000);
}

// 监听进程退出信号
process.on('SIGTERM', gracefulShutdown);
process.on('SIGINT', gracefulShutdown);

注意事项

  • 如果服务前有Nginx、负载均衡等反向代理组件,可以配合调整健康检查规则,触发关闭时先让健康检查返回失败,等上游流量完全切走后再处理存量请求,效果会更平稳
  • 如果服务有用到数据库、Redis等外部资源连接,记得在进程退出前主动关闭对应连接,避免资源泄露

内容的提问来源于stack exchange,提问作者ankalal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 18:36:08