流式传输大型响应后,节点服务器停止接受连接

时间:2017-01-10 22:15:53

标签: node.js http mongoose stream cursor

使用Node,Express,MongoDB和Mongoose,我正在尝试将大量对象(100K +)流式传输到客户端。

这适用于几千条记录。但是,对于100K +记录,请求在大约一分钟后成功完成,但是对服务器的所有后续请求都挂起,我需要重新启动服务器。没有错误可见。

关于可能发生的事情的想法?关于最好的调试方法的想法?

这是我的代码:

res.writeHead(200, { 'Content-Type': 'application/json' });
res.write('{"meta":{"code":200},"objects":[');

Object
  .find({ foo: 'bar' })
  .sort({ createdAt: -1 })
  .lean()
  .cursor()
  .on('error', function (err) {
    console.error(err);
    res.end();
  })
  .on('data', function (object) {
    if (!first)
      res.write(',');
    else  
      first = false;

    res.write(JSON.stringify(object));
  })
  .on('close', function () {
    res.end(']}');
  });

修改

等待几分钟后,我会看到以下错误,后续请求再次开始工作。因此,我怀疑这与未正确关闭连接有关。

Error: write after end
    at ServerResponse.write (_http_outgoing.js:443:15)
    at QueryCursor.<anonymous> (<redacted>/server/models/object.js:431:11)
    at emitOne (events.js:96:13)
    at QueryCursor.emit (events.js:188:7)
    at QueryCursor.Readable.read (_stream_readable.js:381:10)
    at flow (_stream_readable.js:761:34)
    at emitReadable_ (_stream_readable.js:433:3)
    at wrapped (<redacted>/node_modules/newrelic/lib/transaction/tracer/index.js:183:28)
    at _combinedTickCallback (internal/process/next_tick.js:71:11)
    at process._tickDomainCallback [as _tickCallback] (internal/process/next_tick.js:122:9)

编辑2:

我从来没有完全了解到这一点,但我怀疑服务器是在窒息尝试JSON序列化大量记录。我最终使用不同的解决方案,从客户端发出多个分页请求,而不是一次性加载所有记录。见下文。

1 个答案:

答案 0 :(得分:0)

我最终通过从客户端发出多个分页请求而不是一次性加载记录来避免此问题。这减少了服务器和数据库的压力,也允许我在客户端上显示进度指示器。