前一篇文章使用四種框架分別實現百萬websocket常連線的伺服器介紹了四種websocket框架的測試方法和基本資料。 最近我又使用幾個框架實現了websocket push伺服器的原型,並專門對這七種實現做了測試。 本文記錄了測試結果和一些對結果的分析。
這七種框架是:
最近用Golang實現了第八種,Go表現還不錯。
測試環境
使用三臺C3.4xlarge AWS伺服器做測試。 一臺作為伺服器,兩臺作為客戶端機器, 每臺客戶端機器啟動10個client,一共20個client
C3.4xlarge的配置如下:
型號 | vCPU | 記憶體 (GiB) | SSD 儲存 (GB) |
c3.large | 2 | 3.75 | 2 x 16 |
c3.xlarge | 4 | 7.5 | 2 x 40 |
c3.2xlarge | 8 | 15 | 2 x 80 |
c3.4xlarge | 16 | 30 | 2 x 160 |
c3.8xlarge | 32 | 60 | 2 x 320 |
伺服器和客戶端機器按照上一篇文章做了基本的優化。
以下是測試的配置資料:
- 20 clients
- setup rate設為500 * 20 requests/second = 10000 request /second
- 每個client負責建立50000個websocket 連線
- 等1,000,000個websocket建好好,傳送一個訊息(時間戳)給所有的客戶端,客戶端根據時間戳計算latency
- 如果伺服器setup rate建立很慢,主動停止測試
- 監控三個階段的效能指標: setup時, setup完成後應用發呆(idle)時,傳送訊息時
測試結果
Netty
Setup時
- cpu idle: 90%
- minor gc: Few
- full gc: No
Setup完成, 應用Idle時
- cpu idle: 100%
- memory usage: 1.68G
- server free memory: 16.3G
傳送訊息時
- cpu idle: 75%
- minor gc: few
- full gc: No
- Message latency (one client)
1234567891011count = 50000min = 0max = 18301mean = 2446.09stddev = 3082.11median = 1214.0075% 3625.0095% 8855.0098% 12069.0099% 13274.0099.9% 18301.00
Vert.x
Setup時
- cpu idle: 95%
- minor gc: Few
- full gc: No
Setup完成, 應用Idle時
- cpu idle: 100%
- memory usage: 6.37G
- server free memory: 16.3G
傳送訊息時
- cpu idle: 47% ~ 76%
- minor gc: few
- full gc: few
- Message latency (one client)
1234567891011count = 50000min = 49max = 18949mean = 10427.00stddev = 5182.72median = 10856.0075% 14934.0095% 17949.0098% 18458.0099% 18658.0099.9% 18949.00
Undertow
Setup時
- cpu idle: 90%
- minor gc: Few
- full gc: No
Setup完成, 應用Idle時
- cpu idle: 100%
- memory usage: 4.02G
- server free memory: 14.2G
傳送訊息時
- cpu idle: 65%
- minor gc: few
- full gc: No
- Message latency
1234567891011count = 50000min = 1max = 11948mean = 1366.86stddev = 2007.77median = 412.0075% 2021.0095% 5838.0098% 7222.0099% 8051.0099.9% 11948.00
Jetty
Setup時
- cpu idle: 2%
- minor gc: Many
- full gc: No
- memory usage: 5G
- server free memory: 17.2G
當建立360,000左右的websocket時, setup非常的慢, gc頻繁,無法繼續正常建立websocket, 主動終止測試。
Grizzly
Setup時
- cpu idle: 20%
- minor gc: Some
- full gc: Some
- memory usage: 11.5G
- server free memory: 12.3G
當建立500,000左右的websocket時, setup非常的慢, gc頻繁,無法繼續正常建立websocket, 主動終止測試。
Spray
Setup時
- cpu idle: 80%
- minor gc: Many
- full gc: No
當建立500,000左右的websocket時, setup非常的慢, gc頻繁,無法繼續正常建立websocket, 主動終止測試。
Node.js
Setup時
- cpu idle: 94%
Setup完成, 應用Idle時
- cpu idle: 100%
- memory usage: 5.0G
- server free memory: 16.3G
傳送訊息時
- cpu idle: 94%
- Message latency (one client)
- Message latency
1234567891011count = 50000min = 0max = 18mean = 1.27stddev = 3.08median = 1.0075% 1.0095% 1.0098% 1.0099% 1.0099.9% 15.00
Go
Setup時
- cpu idle: 94%
Setup完成, 應用Idle時
- cpu idle: 100%
- memory usage: 15G
- server free memory: 6G
傳送訊息時
- cpu idle: 94%
- Message latency (one client)
- Message latency
1234567891011count = 50000min = 0max = 35mean = 1.89stddev = 1.83median = 1.0075% 1.0095% 2.0098% 2.0099% 4.0099.9% 34.00
測試結果分析
- Netty, Go, Node.js, Undertow, Vert.x都能正常建立百萬連線。 Jetty, Grizzly 和 Spray未能完成百萬連線
- Netty表現最好。記憶體佔用非常的少, CPU使用率也不高。 尤其記憶體佔用,遠遠小於其它框架
- Jetty, Grizzly和Spray會產生大量的中間物件,導致垃圾回收頻繁。Jetty表現最差
- Node.js表現非常好。 尤其是測試中使用單例項單執行緒,建立速度非常快,訊息的latency也很好。 記憶體佔用也不錯
- Undertow表現也不錯,記憶體佔用比Netty高一些,其它差不多
- 這裡還未測到Spray另一個不好的地方。 在大量連線的情況小,即使沒有訊息傳送,Spray也會佔用40% CPU 時間