在 RPC Benchmark Round 1 中 turbo 的成績一騎絕塵,實(shí)力碾壓眾 rpc 框架。對(duì)此,很多人表示不服氣,認(rèn)為作者既是運(yùn)動(dòng)員又是裁判員有失公平。所以我認(rèn)為有必要解釋一下 rpc-benchmark 的公正性,以及為什么 turbo 能夠如此強(qiáng)悍。
參考對(duì)象
rpc-benchmark 靈感源自 techempower-benchmarks,為了能夠評(píng)測眾多服務(wù)器框架,techempower-benchmarks 提供了6個(gè)測試用例:
JSON serialization
This test exercises the framework fundamentals including keep-alive support, request routing, request header parsing, object instantiation, JSON serialization, response header generation, and request count throughput.Single database query
This test exercises the framework's object-relational mapper (ORM), random number generator, database driver, and database connection pool.Multiple database queries
This test is a variation of Test #2 and also uses the World table. Multiple rows are fetched to more dramatically punish the database driver and connection pool. At the highest queries-per-request tested (20), this test demonstrates all frameworks' convergence toward zero requests-per-second as database activity increases.Fortunes
This test exercises the ORM, database connectivity, dynamic-size collections, sorting, server-side templates, XSS countermeasures, and character encoding.Database updates
This test is a variation of Test #3 that exercises the ORM's persistence of objects and the database driver's performance at running UPDATE statements or similar. The spirit of this test is to exercise a variable number of read-then-write style database operations.Plaintext
This test is an exercise of the request-routing fundamentals only, designed to demonstrate the capacity of high-performance platforms in particular. Requests will be sent using HTTP pipelining. The response payload is still small, meaning good performance is still necessary in order to saturate the gigabit Ethernet of the test environment.
techempower-benchmarks 規(guī)則都是公開的,代碼都是開放的。任何人覺得xx框架寫得不好,配置有問題,都可以來提交自己的 Pull Request 。一句話,不服氣的話就來提交代碼。
測試用例
不過 techempower-benchmarks 對(duì)比的都是服務(wù)器框架,并不能用來測試 rpc 的性能,作為學(xué)習(xí)模仿者,我創(chuàng)建了 rpc-benchmark 這個(gè)項(xiàng)目。 rpc-benchmark 提供了4個(gè)測試用例:
boolean existUser(String email), 判斷某個(gè) email 是否存在
輸入是很短的字符串,輸出是 bool 值,這個(gè)測試用例用于衡量小 Request 小
Response 的性能。boolean createUser(User user), 添加一個(gè) 用戶
輸入是一個(gè) User 的對(duì)象,輸出是 bool 值,這個(gè)測試用例用于衡量大 Request 小 Response 的性能。User getUser(long id), 根據(jù) id 獲取一個(gè)用戶
輸入是一個(gè) long 類型的值,輸出是 User 對(duì)象,這個(gè)測試用例用于衡量小 Request 大 Response 的性能。Page<User> listUser(int pageNo), 獲取用戶列表
輸入是 int 類型的值,輸出是一個(gè)包含15個(gè) User 的列表,這個(gè)測試用例用于衡量小 Request 超大 Response 的性能。
這4個(gè)測試用例構(gòu)成了一個(gè)基本的業(yè)務(wù)邏輯: 用戶注冊(cè)管理。非常具有代表性,并且沒有脫離現(xiàn)實(shí)使用場景。有些測試用例可能會(huì)注重衡量字符串的傳輸速度,從4字節(jié) 64字節(jié) ... 64k字節(jié) 依次測起,這樣的測試用例就過于脫離現(xiàn)實(shí),沒有太多的實(shí)際意義。畢竟作為 rpc 框架,除了傳輸速度,序列化速度其實(shí)也是非常重要的。而僅僅用字符串來測試僅能測試出框架的傳輸速度,并不能有效衡量序列化的性能,也不能衡量整體的 rpc 性能。
測試工具
因?yàn)槊總€(gè) rpc 框架都有自己的 序列化協(xié)議 傳輸協(xié)議,所以 rpc-benchmark 不能像 techempower-benchmarks 一樣直接使用 wrk 作為測試工具,只能每個(gè)框架都編寫測試用的 客戶端實(shí)現(xiàn)。
客戶端實(shí)現(xiàn) 使用的工具是JMH,這個(gè)工具 Java 開發(fā)團(tuán)隊(duì)自己也在使用。正確的性能測試在之前并不是一件簡單的事情,JMH 的出現(xiàn)讓性能測試真正的 標(biāo)準(zhǔn)化 簡單化。更多關(guān)于 JMH 的介紹可以參考下面的鏈接。
測試方法
測試的過程是先進(jìn)行10次預(yù)熱,然后才開始真正的3次測試(JMH的“每次”執(zhí)行實(shí)際上是執(zhí)行很多次,更好的翻譯其實(shí)應(yīng)該是“每輪”)。剛開始使用的是5次預(yù)熱,但是后來發(fā)現(xiàn) http 傳輸協(xié)議的 undertow grpc 等框架都比較慢熱,需要更多的預(yù)熱次數(shù)。完整的測試要跑起來依然有點(diǎn)費(fèi)勁,需要配置很多環(huán)境。不過如果你只是想研究下某個(gè)框架的代碼實(shí)現(xiàn)的話,完全可以更簡單一些。拉下代碼來直接導(dǎo)入到 Eclipse/IDEA ,配置好hosts,啟動(dòng) Server,然后啟動(dòng)相應(yīng)的 Client 就好了。
為什么把 undertow springboot netty 也作為了測試對(duì)象
按照 wiki 的定義,這三個(gè)確實(shí)不能認(rèn)為是 rpc ,不過簡單封裝之后他們都可以作為 rpc 使用。加入這幾個(gè)更多的是為給 rpc 框架的實(shí)現(xiàn)者提供一個(gè)參考,作為基礎(chǔ)的協(xié)議層性能是怎么樣的?作為springcloud 的底層實(shí)現(xiàn),springboot 其實(shí)代表了springcloud 的性能。undertow 證明了 http+json 并不比 tcp+binary 慢太多,其速度甚至比 dubbo motan 還要快不少。同時(shí)也是為了告訴噴子們,并不是說你用了高性能的 netty+protopuff 就能比 turbo 快,turbo 能碾壓眾框架并不只是靠簡單的拼積木就能做到的。
不足之處
僅1個(gè)客戶端32個(gè)線程其實(shí)是非常不嚴(yán)謹(jǐn)?shù)?,正確的做法應(yīng)該是從1個(gè)線程一直到32k個(gè)線程逐步增加,從1臺(tái)客戶端機(jī)器到1000臺(tái)客戶端機(jī)器逐步增加(客戶端數(shù)量 線程數(shù)量 應(yīng)該是一個(gè)笛卡爾積)。不過每輪測試實(shí)在都太耗費(fèi)時(shí)間了,而且阿里云的服務(wù)器也不便宜,所以只能作罷。后續(xù)如果有云服務(wù)器廠商贊助的話,可以考慮把這塊給做起來。
turbo為什么如此強(qiáng)悍
篇幅有限寫不開了,下篇再說吧。