RPC 框架性能測試,注意這 8 點就夠了

某天,二狗子寫了一個 RPC 框架後,簡單測了一下性能,發現超出 grpc 一大截。二狗子一高興,忍不住找同事吹了一波。結果,同事親測後對二狗子說框架性能也就這樣。二狗子表示不服,跟同事一番脣槍舌劍後才發現,兩個人測試方法有點不大一樣。先不論測試方法不同在哪裏,今天二狗子先來聊聊,對 RPC 框架做性能測試要注意什麼。

1.確定要觀察指標

一般情況下,必要且重要的指標有:吞吐率(tps)、平均耗時、最大耗時、中位數耗時和 p99 耗時。通常情況下,二狗子不會記錄 CPU 和內存的消耗,因爲這兩者的數值會一直變化,測試時並不好記錄。

2. 確定壓測對象

衡量一個 RPC 框架的性能需要從兩個視角去思考:Client 視角與 Server 視角。只要消息協議、傳輸協議相同,同一種語言的實現就可以有好多種。在大規模的業務架構中,上游 Client 不見得使用的也是下游的框架,而開發者調用的下游服務也同樣如此。

如果 Client 和 Server 部署在同一臺機器上,且未綁定核,則測試時兩端會互相影響。如果要壓測 Server,那麼我們應該給 Client 足夠多的資源,這樣才能把 Server 壓到極致。

3.減少外部因素的影響

這個很好理解,如果外部因素影響過大,則無法測試 RPC 性能的優劣。

一般在測試時,會把 Server 和 Client 放在同一臺機器上,這樣可以減少網絡的影響。如果網絡影響過大,則主要耗時在網絡傳輸上,無法測試 RPC 性能好壞。這裏需要注意上面提到的第二點,部署在同一臺機器上的時候需要爲進程綁核數。

Server 和 Client 在同一臺機器上的情況,Client 請求 Server 是不需要經過網卡轉發的,這與實際情況不同,有需要的同學可以分開部署再進行壓測一次。但是根據其它框架的壓測結果來看,性能表現差距不大。

4.必須要有上下文切換

有一些測試程序非常簡單,簡單到只是客戶端發送了一段“hello world”字符串,服務端直接把字符串原封不動地返回給客戶端。這樣測試出來的結果是不可信的,因爲真實場景不可能這麼簡單。仔細想想,這樣並不是在測試框架的性能,而是在測試你的框架讀/寫 socket 的速度。

RPC 業務特徵是 Handler 邏輯較重,耗時較長,顯然是不能串行處理的。因此 RPC 場景,Handler 必須要異步處理,上下文切換、I/O 協作等都是必須考慮的代價。

5.調用鏈路不應該太簡單

一次 RPC 調用往往需要多個微服務協作完成,而下游服務又會有其自身依賴,所以整個調用鏈路會是一個複雜的網狀結構。測試的時候,具體這樣做:

1.  我們在 Server 內用 Client 訪問下游 Server,這能考察 Server 和 Client 的綜合表現

2.  一個 Client 訪問多個 Server,這能考察負載均衡是否足夠併發,真實場景中很少一個 Client 只訪問一個 Server

6.請求必須包含長尾

真實的請求中肯定會有長尾。對於在同一個線程裏的請求,如果前面的請求慢了一下,那也只能跟着慢了,所以 1% 的長尾會影響遠超 1% 的請求。

模擬長尾請求的方法有很多,最簡單的就是在服務器端增加故意引發延遲的代碼來模擬長尾請求。比如在服務端隨機增加一個延遲等待的時間,在一定概率下增加延遲並使請求變爲長尾請求。

7. 包體積不應太大,也不應該太小

如果有需要,可以對大包和小包分開測試。

對於 HTTP 框架來說,數據可以放在 query、path、header、body 等地方,不同位置對解析造成的影響也不一樣。

8. 與其它 RPC 相比時,需要保證公平性

需要考慮以下幾點:

  1. 序列化方式對齊:對於 RPC 框架來說,計算開銷主要都集中在序列化與反序列化中。拿 protobuf 舉例,有些框架爲了追求性能,使用了 gogo/protobuf,而有些框架爲了可維護性選擇了官方的 protobuf 庫
  2. 對齊連接模型:常規的 RPC 連接模型有短連接、長連接、連接多路複用三種。其中連接多路複用是性能最好的,但這可能並不是框架默認的配置,所以在開始測試前就需要設置好

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章