Golang 網路庫併發吞吐量測試

120582243發表於2019-09-24

https://github.com/Allenxuxu/gev

本文主要測試 gev 網路庫和其他三方 Go 網路庫以及標準庫的吞吐量對比。


## 測試物件


- gev :一個輕量、快速的基於 Reactor 模式的非阻塞 TCP 網路庫
- eviop :evio 的優化版本
- evio :Fast event-loop networking for Go
- gnet:eviop 的網路模型替換版本
- net 標準庫

## 測試方法


採用陳碩測試 muduo 使用的 ping pong 協議來測試吞吐量。

> 簡單地說,ping pong 協議是客戶端和伺服器都實現 echo 協議。當 TCP 連線建立時,客戶端向伺服器傳送一些資料,伺服器會 echo 回這些資料,然後客戶端再 echo 回伺服器。這些資料就會像乒乓球一樣在客戶端和伺服器之間來回傳送,直到有一方斷開連線為止。這是用來測試吞吐量的常用辦法。

測試的客戶端程式碼:https://github.com/Allenxuxu/gev/blob/master/benchmarks/client/main.go

測試指令碼:https://github.com/Allenxuxu/gev/blob/master/benchmarks/bench-pingpong.sh

主要做兩項測試:

- 單執行緒單個 work 協程測試,測試併發連線數為 10/100/1000/10000 時的吞吐量
- 4執行緒4個 work 協程測試,測試併發連線數為 10/100/1000/10000 時的吞吐量

所有測試中,ping pong 訊息的大小均為 4096 bytes,客戶端始終是4執行緒執行。

## 測試結果


https://i.iter01.com/images/93163c661a851703050b2db9cb5f0e71d5c557bd40bd30f2e25919b9ac27d497.png


https://i.iter01.com/images/7a865884b58a2860e8e8be107cd621a6c62b845a1d877d8ae8792b55475d3cb8.png


## 總結與思考


無論是單執行緒,還是多執行緒模式下,gev 都比其他網路庫吞吐量略高出一些。

evio 因為 epoll 使用一些 bug 和可優化之處,所以在 linux 環境中的吞吐量遠不如優化版本 eviop 。

eviop 是我對 evio bug 修復和優化的版本,所以其效能也是比 evio 提升不少。我曾嘗試在 eviop 中替換 evio 的網路模型(evio 利用 accpet 的驚群現象工作),但是因為其程式碼耦合度過高,修改成本過大,最終決定一邊完善 eviop(維持網路模型不變)一邊自己借鑑muduo 的網路模型重新擼一個新的 -- gev 。

gnet 是研究了 eviop 的程式碼,繼續在其之上替換網路模型的版本。但是網路模型的優勢在單執行緒模式中並沒有體現出來,吞吐量反而比 eviop 小一些。在多執行緒模式下,網路模型的優勢得以體現。

gev 與其他使用 epoll 構建的基於事件驅動的網路庫在逐步的優化中,相信效能都差不多。因為作者目的不同,網路庫不同的設計,優勢點都會不同。我研究 evio,最終自己擼了 gev ,也是因為想要一個在記憶體佔用低前提下,速度足夠快,能負載更多連線的網路庫。

如果對 gev 網路庫感興趣,歡迎提意見和 PR 。➡️ https://github.com/Allenxuxu/gev

相關文章