0%

[Golang] WebSocket Stream Benchmark 效能評估

前言

如果 WebSocket 伺服器頻繁向客戶端發送訊息,是否會影響客戶端的請求?是否應該使用多個 WebSocket 連接來分開數據流量?所以我用 Golang 來做這個場景的基準測試。最後,讓我來和大家分享一下這個結果。

Benchmark 目標

當伺服器通過 WebSocket 連線以高頻率向客戶端發送數據時,如果客戶端通過同一 WebSocket 連線向伺服器發送低頻率信息,需要多長時間才能收到回覆?

原始碼與使用方法

  • 原始碼: websocket-stream-benchmarck
  • 使用方法:
    Clone 此專案並編譯

    1
    2
    3
    git clone https://github.com/weirenxue/websocket-stream-benchmarck.git # clone

    make # build

    將會在 ./bin文件夾中找到兩個可執行文件 clientserver。首先運行 ./bin/server,然後打開另一個終端窗口,運行 ./bin/client,等待 client 完成執行並輸出結果。

    你可能想改變 config.toml 中的配置,看看不同情況下的測試結果。

config.toml 的參數說明

  • server
    • host:WebSocket 伺服器主機。
    • port:WebSocket 伺服器端口。
    • dummy_message_size:每個假訊息的大小。
    • dummy_message_duration:發送每個假訊息的時間間隔。
  • client
    • request_duration:發送每個請求的時間間隔。
    • total_request:應該發送的請求的數量。

設計概念

  • Server:一旦客戶端連接到伺服器,伺服器就會每隔 dummy_message_duration 向客戶端發送一條大小為 dummy_message_size 的訊息。伺服器會監聽客戶端是否發送訊息,如果是,它將接收並直接回覆原始訊息。
  • Client:客戶端生成一個 uuid 作為發送給伺服器的請求,而伺服器必須發回同樣的訊息。基於 uuid 的唯一性,我們可以知道一個請求從被發送到被回覆所需的時間,最後將每個請求所需的時間除以請求的數量以取得平均來回時間。

最後,每個案例測試五次,選擇最差的案例並記錄在實驗結果中。

測試環境與結果

  • OS:macOS 12.2.1
  • CPU:i7 2.7GHz 4 Cores
  • RAM:16 GB LPDDR3
dummy config→
request config↓
dummy_message_size="10KB"
dummy_message_duration="1h"
(no dummy message due to long duration)
dummy_message_size="10KB"
dummy_message_duration="500us"
dummy_message_size="1MB"
dummy_message_duration="500us"
total_request=1000
request_duration="1ms"
total duration: 160.714504ms
average duration: 160.714µs
total received dummy message: 0B
total duration: 83.472281ms
average duration: 83.472µs
total received dummy message: 19710KB
total duration: 5.364239748s
average duration: 5.364239ms
total received dummy message: 787MB
request_duration="10ms"
total_request=1000
total duration: 300.998294ms
average duration: 300.998µs
total received dummy message: 0B
total duration: 110.638204ms
average duration: 110.638µs
total received dummy message: 154350KB
total duration: 5.675233495s
average duration: 5.675233ms
total received dummy message: 7520MB

結語

我們也許會擔心若所有資料流量都在同一個 WebSocket 連線上,頻寬會被分走,導致有些 Client 端的指令無法被及時處理。但根據這個專案的結果顯示,我們可以放心的讓所有資料流量都在一個 WebSocket 連線上傳遞。這是好事,因為多個連線會造成伺服器一定的負擔。

除此之外,可以從商用產品來看 WebSocket 連線數問題。例如,在 Firebase 的 Realtime Database 服務的官方定價中,有一項是限制同時使用的連線數,因此若在一個瀏覽器視窗上有多個連線數,將會造成金額上的負擔。當然,Firebase SDK 很貼心,讓所有的請求都是在同一個 WebSocket 上進行,以確保一個瀏覽器視窗只有一個 WebSocket 連線。

很高興能在這裡幫助到您,歡迎登入 Liker 為我鼓掌 5 次,或者成為我的讚賞公民,鼓勵我繼續創造優質文章。
以最優質的內容回應您的鼓勵