javascript - 直接来自 Node mongodb 的 JSON 字符串

标签 javascript node.js mongodb express

我一直在一个简单的服务器上进行一系列负载测试,以尝试确定是什么对我的复杂得多的 Node/express/mongodb 应用程序的负载产生负面影响。经常出现的事情之一是字符串操作需要在快速响应中将内存中的对象转换为 JSON。

我通过 Node 从 mongodb 提取并通过线路发送的数据量约为 200/300 KB 未压缩。 (Gzip 会将其转换为 28k,这要好得多。)

有没有办法让 native nodejs mongodb 驱动程序为我将结果字符串化?现在,对于使用标准 .toArray() 的每个请求,我们正在执行以下操作:

  1. 查询数据库,查找结果并将其传输到 Node native 驱动程序
  2. 然后 native 驱动程序将它们转换为内存中的 javascript 对象
  3. 然后我的代码将内存中的对象传递给 express
  4. Express 然后使用 JSON.stringify() 将其转换为 Node 的 http response.send 的字符串(我阅读了来源 Luke。)

我希望在 C++/ native 层完成字符串化工作,这样它就不会增加我的事件循环的处理时间。有什么建议么?

编辑 1:

已证实的瓶颈。

可能还有其他可以轻松优化的内容,但负载测试显示的内容如下。

我们在几秒钟内向同一个网络服务器发送了 500 个请求。使用此代码:

app.get("/api/blocks", function(req, res, next){
    db.collection('items').find().limit(20).toArray(function(err, items){
        if(err){
            return next(err);
        }
        return res.send(200, items);
    });
});

总体平均值:323 毫秒,95% 为 820 毫秒

如果我换掉 json 数据:

var cached = "[{... "; //giant json blob that is a copy+paste of the response in above code.
app.get("/api/blocks", function(req, res, next){
    db.collection('items').find().limit(20).toArray(function(err, items){
        if(err){
            return next(err);
        }
        return res.send(200, cached);
    });
});

平均值为 164 毫秒,95% 为 580

现在您可能会说,“天哪,平均 323 毫秒已经很棒了,您的问题是什么?”我的问题是,这是一个 stringify 导致响应时间加倍的示例。

根据我的测试,我还可以告诉您这些有用的信息:

  • Gzip 使响应时间提高了 2 倍或更好。以上是gzip
  • 与通用 nodejs 相比,Express 增加了几乎察觉不到的开销
  • 通过执行 cursor.each 对数据进行批处理,然后将每个单独的项目发送到响应中要糟糕得多

更新 2:

使用分析工具:https://github.com/baryshev/look 这是在同一数据库密集型进程中一遍又一遍地访问我的生产代码。该请求包括一个 mongodb 聚合并发回约 380KB 数据(未压缩)。

premature optimization my foot!

该函数非常小,包括 var body = JSON.stringify(obj, replacer, spaces); 行。

最佳答案

听起来您应该直接从 Mongodb 流式传输到 Express。

P this question that asks exactly this :

cursor.stream().pipe(JSONStream.stringify()).pipe(res);

关于javascript - 直接来自 Node mongodb 的 JSON 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23413091/

相关文章:

javascript - 为什么我的 JavaScript if 语句总是 true?

javascript - String.endsWith(/[字符串]/[1-999]/)

javascript - 如何使用 JavaScript 返回元素的内部子元素?

javascript - NodeJS express 。 res.send() 在分配给另一个 var 时失败

javascript - 如何将 puppeteer 操纵者的焦点转移到弹出窗口

c# - Mongodb保证单次查询中数组和计数的正确性

java - Spring -MongoDB

javascript - Jquery 替换为并在再次单击同一个类时恢复旧值

node.js - 使用elasticsearch js进行多字段搜索

node.js - MongoDB 只存储 61246 个文档?