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

使用Express流式返回查询结果时出现Knex数据库连接获取超时问题

问题根本原因

你的代码只捕获了stream创建阶段的同步异常,没有处理stream运行过程中的异步错误,导致数据库连接泄漏,最终占满连接池触发超时,具体问题如下:

  • 外层的try/catch只能捕获db(...).stream()调用时立刻抛出的同步错误,stream在后续数据传输过程中出现的所有异步错误(比如客户端中途断开请求、网络波动中断传输、JSON序列化报错)都无法被捕获,这时候数据库连接不会被Knex主动回收,持续占用连接池配额。
  • 原生的pipe方法不会在下游stream出错/中断时自动销毁上游的数据库stream,哪怕响应提前终止,数据库侧的stream还会保持挂起状态,对应的连接一直不会释放。
  • 并发请求多的时候,泄漏的连接慢慢占满整个连接池,新的请求拿不到空闲连接,就会随机抛出你遇到的连接获取超时报错。

修复方案

用Node.js内置的stream.pipeline代替原生pipe,它会自动在任意环节出错时销毁所有上下游stream,释放资源,同时补充完整的错误和中断场景处理,示例代码如下:

const { pipeline } = require('stream')
const JSONStream = require('JSONStream')

app.get('/events', (req, res, next) => {
  try {
    const stream = db('events')
      .select('*')
      .where({ id_user: 'foo' })
      .stream()

    pipeline(
      stream,
      JSONStream.stringify(),
      res,
      (err) => {
        if (err) {
          stream.destroy(err)
          next(err)
        }
      }
    )

    req.on('close', () => {
      if (!stream.destroyed) {
        stream.destroy()
      }
    })
  } catch (err) {
    next(err)
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 00:57:01