摘要:我們分別使用這樣的原則來測試向每個(gè)架構(gòu)注入個(gè)靜態(tài)路由,測試最末尾的那個(gè)。而我們?nèi)绾巫龅竭_(dá)到的性能,主要我們在內(nèi)存中維護(hù)了一份靜態(tài)路由列表,能讓程序以最快的速度找到我們需要的。
對比
如果使用nodejs來搭建Service服務(wù),那么我們首選express或者koa,而fastify告訴我們一個(gè)數(shù)據(jù):
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 |
從數(shù)據(jù)中可以看出,Koa的性能遠(yuǎn)大于express。當(dāng)然,它的測試基于簡單的單路由測試。不過由此我們可以看到fastify的性能遠(yuǎn)大于Koa。相信使用過fastify的小伙伴都會(huì)對它的性能速度感到驚訝。其實(shí)原理很簡單,就是請求的URL快速匹配Callback。如何做到,理論上也很簡單,就是找尋它的最短路徑來匹配。所以一般能夠快速匹配的,都是通過空間換時(shí)間的方式來達(dá)到效果。
這里,我還想告訴大家一點(diǎn),fastify并不是最快的。
主角今天的主角就是koa-rapid-router。為什么我們會(huì)以KOA打頭呢?因?yàn)檫@篇文章目的其實(shí)是與koa-router的比較,而不是fastify。而此路由架構(gòu),也是為了在使用KOA的時(shí)候能夠接近fastify的性能(經(jīng)過測試,沒有超過fastify,KOA本身的性能也有問題)。
接下來,我們會(huì)拋出一系列的測試數(shù)據(jù)來告訴大家Koa-router的性能是何其糟糕。我們分別使用這樣的原則來測試
向每個(gè)架構(gòu)注入10000個(gè)靜態(tài)路由,測試最末尾的那個(gè)。
使用相同的測試命令 autocannon -c 100 -d 40 -p 10
對比靜態(tài)路由和動(dòng)態(tài)路由性能上的差距
測試代碼全部在這里
靜態(tài)路由對比我們寫入如下的代碼
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")); }
接著進(jìn)行測試 npm run test,得到數(shù)據(jù):
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 |
從數(shù)據(jù)上得出結(jié)論,koa-router在有10000個(gè)路由的時(shí)候,它的性能超級低下,只能達(dá)到平均的394.25,意思就是每秒只能處理394.25個(gè)請求,多來就不行。而koa + koa-rapid-router則處理到了44828.8個(gè)。同樣是使用KOA模型,差距很明顯。我做了分析,主要是koa-router內(nèi)部循環(huán)比較多導(dǎo)致的。在10000個(gè)請求循環(huán)過程中,效率非常低下。而我們?nèi)绾巫龅竭_(dá)到44828.8的性能,主要我們在內(nèi)存中維護(hù)了一份靜態(tài)路由列表,能讓程序以最快的速度找到我們需要的callback。
對比fastify,可以看出,KOA本身性能的問題很大。
大家一定會(huì)問,對比靜態(tài)路由Koa-router肯定沒有優(yōu)勢,那么我們來對比動(dòng)態(tài)路由。
動(dòng)態(tài)路由對比我們寫入如下代碼
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個(gè)靜態(tài)路由代碼的后面,修正測試的路徑,我們得到如下數(shù)據(jù):
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 |
動(dòng)態(tài)路由的對比從一定程度上可以看出koa-router的糟糕之處,不論是靜態(tài)路由還是動(dòng)態(tài)路由,它都基本穩(wěn)定在400左右的qps。而koa + koa-rapid-router稍有下降,fastify一如既往的穩(wěn)定。但是從http + koa-rapid-router模型上看,rapid完全超越fastify。koa + koa-rapid-router與koa + koa-router對比,性能大概是100倍的樣子。如果我們可以這樣認(rèn)定,如果我們需要高并發(fā),但是還是使用koa的生態(tài)的話,koa + koa-rapid-router是最佳選擇。如果我們完全追求性能,不考慮生態(tài)的話,那么fastify首選。
有人會(huì)問,那么為什么http + koa-rapid-router不使用,它可是比fastify更快的路由?那是因?yàn)椋?b>http + koa-rapid-router需要多帶帶建立生態(tài),暫時(shí)無法做到大規(guī)模使用,也許到最后,我們可以用上新的基于koa-rapid-router的企業(yè)級服務(wù)架構(gòu)。這也是我正在思考的。
結(jié)尾我們所造的輪子的性能是不可能超越http模塊的性能,我們只能無限接近它。這就像光速的道理一樣,只能接近,無法等于。高性能架構(gòu)主要還是在于理念模型,跟數(shù)學(xué)息息相關(guān)。
項(xiàng)目開源在 https://github.com/cevio/koa-rapid-router 有興趣的小伙伴關(guān)注下,謝謝。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/102589.html
摘要:所以,最佳選擇是。事實(shí)上,這種處理完全不必要。這樣的設(shè)計(jì),使得讀取局部變量比讀取全局變量快得多。請看下面兩段代碼,第一段代碼是讀取全局變量第二段代碼是讀取局部變量第二段代碼讀取變量的時(shí)候,不用前往上一層作用域,所以要比第一段代碼快五六倍。 轉(zhuǎn)自:http://www.ruanyifeng.com/blog/2011/08/jquery_best_practices.html ...
摘要:所以,最佳選擇是。事實(shí)上,這種處理完全不必要。這樣的設(shè)計(jì),使得讀取局部變量比讀取全局變量快得多。請看下面兩段代碼,第一段代碼是讀取全局變量第二段代碼是讀取局部變量第二段代碼讀取變量的時(shí)候,不用前往上一層作用域,所以要比第一段代碼快五六倍。 轉(zhuǎn)自:阮一峰 日期: 2011年8月 4日http://www.ruanyifeng.com/blo... 上周,我整理了《jQuery設(shè)計(jì)思想》。...
摘要:轉(zhuǎn)自阮一峰年月日上周,我整理了設(shè)計(jì)思想之理解篇。這樣的設(shè)計(jì),使得讀取局部變量比讀取全局變量快得多。請看下面兩段代碼,第一段代碼是讀取全局變量第二段代碼是讀取局部變量第二段代碼讀取變量的時(shí)候,不用前往上一層作用域,所以要比第一段代碼快五六倍。 轉(zhuǎn)自:阮一峰 2011年8月4日 http://www.ruanyifeng.com/blo... 上周,我整理了https://segmentf...
摘要:框架會(huì)默認(rèn)加載下命名為或的配置文件。采用異步寫日志的方式而不讓此次寫日志發(fā)生磁盤,阻塞線程從而造成不必要的性能損耗。 通過閱讀本篇文章將了解到 1.日志輸出到文件并根據(jù)LEVEL級別將日志分類保存到不同文件 2.通過異步輸出日志減少磁盤IO提高性能 3.異步輸出日志的原理 配置文件logback-spring.xml SpringBoot工程自帶logback和slf4j的依賴,所...
摘要:框架會(huì)默認(rèn)加載下命名為或的配置文件。采用異步寫日志的方式而不讓此次寫日志發(fā)生磁盤,阻塞線程從而造成不必要的性能損耗。 通過閱讀本篇文章將了解到 1.日志輸出到文件并根據(jù)LEVEL級別將日志分類保存到不同文件 2.通過異步輸出日志減少磁盤IO提高性能 3.異步輸出日志的原理 配置文件logback-spring.xml SpringBoot工程自帶logback和slf4j的依賴,所...
閱讀 2468·2021-11-19 09:59
閱讀 1991·2019-08-30 15:55
閱讀 935·2019-08-29 13:30
閱讀 1337·2019-08-26 10:18
閱讀 3087·2019-08-23 18:36
閱讀 2389·2019-08-23 18:25
閱讀 1161·2019-08-23 18:07
閱讀 439·2019-08-23 17:15