koa-rapid-router超越koa-router性能的100多倍

4次阅读

共计 2686 个字符,预计需要花费 7 分钟才能阅读完成。

对比
如果使用 nodejs 来搭建 Service 服务,那么我们首选 express 或者 koa,而 fastify 告诉我们一个数据:

Framework
Version
Router?
Requests/sec

hapi
18.1.0

29,998

Express
4.16.4

38,510

Restify
8.0.0

39,331

Koa
2.7.0

50,933

Fastify
2.0.0

76,835

http.Server
10.15.2

71,768

从数据中可以看出,Koa 的性能远大于 express。当然,它的测试基于简单的单路由测试。不过由此我们可以看到 fastify 的性能远大于 Koa。相信使用过 fastify 的小伙伴都会对它的性能速度感到惊讶。其实原理很简单,就是请求的 URL 快速匹配 Callback。如何做到,理论上也很简单,就是找寻它的最短路径来匹配。所以一般能够快速匹配的,都是通过空间换时间的方式来达到效果。
这里,我还想告诉大家一点,fastify 并不是最快的。
主角
今天的主角就是 koa-rapid-router。为什么我们会以 KOA 打头呢?因为这篇文章目的其实是与 koa-router 的比较,而不是 fastify。而此路由架构,也是为了在使用 KOA 的时候能够接近 fastify 的性能(经过测试,没有超过 fastify,KOA 本身的性能也有问题)。
接下来,我们会抛出一系列的测试数据来告诉大家 Koa-router 的性能是何其糟糕。我们分别使用这样的原则来测试

向每个架构注入 10000 个静态路由,测试最末尾的那个。
使用相同的测试命令 autocannon -c 100 -d 40 -p 10 <url>

对比静态路由和动态路由性能上的差距

测试代码全部在这里
静态路由对比
我们写入如下的代码
for (let i = 0; i < 10000; i++) {
router.get(‘/uuid/’ + (i + 1), async (ctx) => ctx.body = ‘ok’);
vrouter.get(‘/uuid/’ + (i + 1), (res) => res.end(‘ok’));
route_2.get(‘/interface/api/uuid/’ + (i + 1), async (ctx) => ctx.body = ‘ok’);
fastify.get(‘/interface/api/uuid/’ + (i + 1), (request, reply) => reply.send(‘ok’));
}
接着进行测试 npm run test,得到数据:
Preview:

Results

command
architecture
Latency
Req/Sec
Bytes/Sec

test:koa
koa + koa-router
245.07 ms
394.25
56 kB

test:fast
fastify
1.96 ms
49324
7 MB

test:rapid
koa + koa-rapid-router
2.17 ms
44828.8
6.37 MB

test:http
http + koa-rapid-router
1.64 ms
58911.2
5.95 MB

从数据上得出结论,koa-router 在有 10000 个路由的时候,它的性能超级低下,只能达到平均的 394.25,意思就是每秒只能处理 394.25 个请求,多来就不行。而 koa + koa-rapid-router 则处理到了 44828.8 个。同样是使用 KOA 模型,差距很明显。我做了分析,主要是 koa-router 内部循环比较多导致的。在 10000 个请求循环过程中,效率非常低下。而我们如何做到达到 44828.8 的性能,主要我们在内存中维护了一份静态路由列表,能让程序以最快的速度找到我们需要的 callback。
对比 fastify,可以看出,KOA 本身性能的问题很大。
大家一定会问,对比静态路由 Koa-router 肯定没有优势,那么我们来对比动态路由。
动态路由对比
我们写入如下代码
router.get(‘/zzz/{a:number}’, async (ctx) => ctx.body = ‘ok’);
vrouter.get(‘/zzz/{a:number}’, (res) => res.end(‘ok’));
route_2.get(‘/interface/api/zzz/:a(\\d+)’, async (ctx) => ctx.body = ‘ok’);
fastify.get(‘/interface/api/zzz/:a’, (request, reply) => reply.send(‘ok’));
我们将这段代码加入到 10000 个静态路由代码的后面,修正测试的路径,我们得到如下数据:

Results

command
architecture
Latency
Req/Sec
Bytes/Sec

test:koa
koa + koa-router
220.29 ms
441.75
62.7 kB

test:fast
fastify
1.9 ms
50988.65
7.24 MB

test:rapid
koa + koa-rapid-router
2.32 ms
41961.6
5.96 MB

test:http
http + koa-rapid-router
1.82 ms
53160.8
5.37 MB

动态路由的对比从一定程度上可以看出 koa-router 的糟糕之处,不论是静态路由还是动态路由,它都基本稳定在 400 左右的 qps。而 koa + koa-rapid-router 稍有下降,fastify 一如既往的稳定。但是从 http + koa-rapid-router 模型上看,rapid 完全超越 fastify。koa + koa-rapid-router 与 koa + koa-router 对比,性能大概是 100 倍的样子。如果我们可以这样认定,如果我们需要高并发,但是还是使用 koa 的生态的话,koa + koa-rapid-router 是最佳选择。如果我们完全追求性能,不考虑生态的话,那么 fastify 首选。
有人会问,那么为什么 http + koa-rapid-router 不使用,它可是比 fastify 更快的路由?那是因为,http + koa-rapid-router 需要单独建立生态,暂时无法做到大规模使用,也许到最后,我们可以用上新的基于 koa-rapid-router 的企业级服务架构。这也是我正在思考的。
结尾
我们所造的轮子的性能是不可能超越 http 模块的性能,我们只能无限接近它。这就像光速的道理一样,只能接近,无法等于。高性能架构主要还是在于理念模型,跟数学息息相关。
项目开源在 https://github.com/cevio/koa-rapid-router 有兴趣的小伙伴关注下,谢谢。

正文完
 0