65.9K
CodeProject 正在变化。 阅读更多。
Home

NodeJS REST 服务器尝试验证有效脚本

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2012年5月6日

CPOL

7分钟阅读

viewsIcon

40024

downloadIcon

211

测试 NodeJS 中流行的 REST 实现,包括测量 MongoDB 插入速率。

介绍  

既然我决定选择 NodeJS 作为关联数据库的服务提供商,我认为有一个 REST 服务来运行查询会很不错。想要我时间允许下最有效的服务器,我决定测试一些已经构建好的 REST 服务器,以审查它们的语法并了解性能影响。 

安装   

抱歉,这只是一个概念验证 (POC),我还没有准备好进行打包,所以下载这个项目,然后运行 npm journey 和 restify。这样就可以开始了。如果您是 NodeJS 新手,我强烈推荐 Webstorm 作为您的 IDE。 

如果您想要最新版本或想提供帮助,请前往 GitHub 上的 rapid-rest 项目,在那里工作仍在继续,您会找到一个支持强制查询字符串参数的新版本。

https://github.com/knowlecules/rapid-rest

定义测试范围

选择 REST 实现

我的第一个想法是抓取 GitHub 上关注度最高的项目,即 restify。我本以为我会满意我的选择,然后迅速完成这个小项目。但令我惊讶的是,吞吐量非常糟糕。我每秒看到 250 个请求。从之前的研究来看,我应该接近这个数字的 20 倍,最多是 40 倍。

我此时应该说明,很可能是我的测试过程有问题。我不太记得我到底在做什么,我也不太关心去找出原因。生活还在继续。我将代码的剩余部分留在了项目中,我非常倾向于这是客户端(client-restify.js)的问题,而不是服务器的问题。所以我编写了自己的“发送即忘”客户端,以便我能纯粹专注于服务器测试。

候选者和基线

经过大量的搜索,可能是因为我在 StackOverflow 的一个问题中读到的内容,我决定将 journey 加入测试。如果您在进行自己的测试,您将需要一个基线来衡量,然后,当然,您应该受到启发来编写自己的库,其性能介于基线和最快的竞争者之间。

鉴于我以前做过这类事情,我知道有些人已经在这类项目上取得了进展但后来就停滞了,偶尔您会找到一些足够成熟的代码,可以用于您自己的邪恶目的。对于这个项目,那就是 node-rest,它已损坏(我认为,也许是我使用不当),但足够成熟,并且语法足够漂亮,所以我决定以此作为我自己的 KISS REST 服务器的起点。

参赛名单

按任意顺序,以下是这些库的简要描述

  • restify.
    • 该作者在 NodeJS 领域非常活跃,有 500 用户关注该项目。
  • journey
    • LESS 的作者,有 274 用户关注该项目。
  • 基线
    • 接近在 NodeJS 上运行的 REST 服务器可能实现的最佳吞吐量。
  • rapid-rest(基于 node-rest
    • REST 服务器的最小实现,它接受参数化的 URL,并识别 JSON 和其他接收到的内容。

要衡量的指标

最初的目的是测量时间和资源消耗。在测试了一些基准测试库之后,很明显测试套件本身消耗了大部分资源。我得到了一些漂亮的图表,但付出了什么代价?

与设计和编写代码同等重要的是确保测试工具不会影响测试结果。初始测试是使用 restify(client-restify.js)提供的库编写的客户端进行的。

该客户端使用纯 NodeJS 库重新编写(client.js),性能提高了 30%。该客户端是“发送即忘”请求程序,因此它有一个限制,在饱和资源之前可以进行的最大请求数。对于测试机上的这些测试,上限是 300,000,但您会发现性能在大约 90,000 时有所下降。

测试

要求是测量数据库以 JSON 字符串填充的速度,这些字符串代表用户对问卷的回答(类似于调查)。为了隔离数据库对性能的影响,将进行另一组不进行任何数据访问的测试。

进行了许多测试,但图表只使用了单次测试运行。有几次运行出现了巨大的差异,我只能归因于环境,可能是 IDE,可能是机器。本文档中的结果来自我最后一次在笔记本电脑上尽力保持环境干净的测试。

测试在 Windows 7 Vaio, i5 - PCG-81411L 上进行。

REST 请求速率

衡量不同实现处理 30,000 个请求的能力。

Rate of REST

带 MongoDB 插入的 REST 请求速率

衡量不同实现处理 30,000 个请求以及随后在单次插入和批量插入模式下进行 MongoDB 插入的能力。

Rate of REST with Mongo insert

选择的批量大小会影响收益递减,因为大小增加。这些测试的“最佳点”对于不同的 REST 服务器是不同的。rapid-rest 偏好 4,而 restify 在批量大小为 12 时运行效果最佳。此测试的重要性在于它如何影响使用 MongoDB on NodeJS 的应用程序的架构。结果表明,当在集合级别缓存指令时,插入速率几乎可以翻倍。

基线以上的 REST 请求处理

衡量响应 REST 请求所需的额外处理。

REST request overhead

* 注:达到那条红线是本次测试的全部意义所在。

此图表显示了在编写针对性代码与通用代码时可以实现什么。显然 rapid-rest 支持 REST,因此它具有通用接口,但它不支持“application/json”以外的内容类型,并且错误支持机制应该进行一次审查。

基线以上的 REST 和 MongoDB 请求处理

衡量响应将单个文档插入 MongoDB 数据库的 REST 请求所需的额外处理。

REST with Mongo insert overhead

* 另一条值得骄傲的小红线。

此图表完成了整个画面。处理将数据插入 MongoDB 的 REST 请求的整个垂直部分,以及测试中涉及的 REST 服务器所产生的开销。

结束了。接下来呢?

有什么教训?

提前生成简洁的函数

我没有剖析 restifyjourney 背后的任何代码,但我知道性能差异完全取决于请求时运行的代码行数(毕竟 Javascript 需要解析)。对于 REST 服务器架构,我们在服务器预先配置方面拥有巨大的优势。请求解析函数应该在这里生成,以完成最少的工作。

批量 MongoDB 插入

此基准测试的一个衍生结果是找出如何通过发送对象数组来提高 Mongo 的吞吐量。如果您运行了基准测试并进行了计算,您会发现 rapid-rest 的吞吐量提高了 300%,而 journeyrestify 相对于基线结果提高了 200%。最佳批量大小似乎大于 4 但小于 15,如果您使用缓存进行开发,这将非常有用。

可能需要尽可能避免 Mongo upserts(需要进一步调查)

即使非安全模式的 upsert 速度与插入速度相同,MongoDB 在响应收到后仍会继续运行。这种额外的消耗似乎是非线性的,较小的测试不会产生任何影响,而 30,000 次迭代的测试则增加了大量负荷。由于数据库在每次测试前都会被删除,我只能将这种缓慢归因于对现有项目的搜索。我没有为集合添加索引,这可能会解决这个问题。

哪个是更好的 REST 服务器?

这完全取决于您的需求。如果您需要一个功能齐全的 REST 服务器,该服务器拥有可靠的往绩和众多贡献者,他们可能已经消除了大多数错误,那么您可能会选择 restifyjourney。如果您是一名程序员,希望榨取一些 MIPS 来给老板留下深刻印象,并且您的需求很简单,那么实现 rapid-rest 可能会让您脱颖而出。 

© . All rights reserved.