本文咱們主要是想測試和研究幾點:nginx
本文測試使用的代碼在: github.com/JosephZhu19…git
在代碼裏咱們實現了兩套代理程序: github
測試使用的機器配置是(阿里雲ECS): spring
nginx 配置的就是默認的測試頁(刪了點內容,減小內網帶寬): 後端
四層的代理,咱們僅僅是使用Netty來轉發ByteBuf。 七層的代理,會有更多額外的開銷,主要是Http請求的編碼解碼以及Http請求的聚合,服務端:性能優化
客戶端: 服務器
這裏咱們能夠想到,四層代理由於少了Http數據的編解碼過程,性能確定比七層好不少,好多少咱們能夠看看測試結果。網絡
咱們知道做爲一個代理,咱們須要開啓服務端從上游來獲取請求,而後再做爲客戶端把請求轉發到下游,從下游獲取到響應後,返回給上游。咱們的服務端和客戶端都須要Worker線程來處理IO請求,有三種作法;app
以七層代理的代碼爲例: oop
接下去的測試咱們會來測試這三種線程模型,這裏想固然的猜想是方案A的性能是最好的,由於獨立了線程池不相互影響,咱們接下去看看結果
Layer4ProxyServer Started with config: ServerConfig(type=Layer4ProxyServer, serverIp=172.26.5.213, serverPort=8888, backendIp=172.26.5.214, backendPort=80, backendThreadModel=ReuseServerThread, receiveBuffer=10240, sendBuffer=10240, allocatorType=Unpooled, maxContentLength=2000)
Layer4ProxyServer Started with config: ServerConfig(type=Layer4ProxyServer, serverIp=172.26.5.213, serverPort=8888, backendIp=172.26.5.214, backendPort=80, backendThreadModel=IndividualGroup, receiveBuffer=10240, sendBuffer=10240, allocatorType=Unpooled, maxContentLength=2000)
Layer4ProxyServer Started with config: ServerConfig(type=Layer4ProxyServer, serverIp=172.26.5.213, serverPort=8888, backendIp=172.26.5.214, backendPort=80, backendThreadModel=ReuseServerGroup, receiveBuffer=10240, sendBuffer=10240, allocatorType=Unpooled, maxContentLength=2000)
看到這裏其實已經有結果了,ReuseServerThread性能是最好的,其次是ReuseServerGroup,最差是IndividualGroup,和咱們猜的不一致。
從網絡帶寬上能夠看到,先測試的ReuseServerThread跑到了最大的帶寬(後面三個高峯分別表明了三次測試):
Layer7ProxyServer Started with config: ServerConfig(type=Layer7ProxyServer, serverIp=172.26.5.213, serverPort=8888, backendIp=172.26.5.214, backendPort=80, backendThreadModel=ReuseServerThread, receiveBuffer=10240, sendBuffer=10240, allocatorType=Unpooled, maxContentLength=2000)
Layer7ProxyServer Started with config: ServerConfig(type=Layer7ProxyServer, serverIp=172.26.5.213, serverPort=8888, backendIp=172.26.5.214, backendPort=80, backendThreadModel=IndividualGroup, receiveBuffer=10240, sendBuffer=10240, allocatorType=Unpooled, maxContentLength=2000)
Layer7ProxyServer Started with config: ServerConfig(type=Layer7ProxyServer, serverIp=172.26.5.213, serverPort=8888, backendIp=172.26.5.214, backendPort=80, backendThreadModel=ReuseServerGroup, receiveBuffer=10240, sendBuffer=10240, allocatorType=Unpooled, maxContentLength=2000)
結論同樣,ReuseServerThread性能是最好的,其次是ReuseServerGroup,最差是IndividualGroup。我以爲是這麼一個道理:
下面分別是網絡帶寬和CPU監控圖:
Layer7ProxyServer Started with config: ServerConfig(type=Layer7ProxyServer, serverIp=172.26.5.213, serverPort=8888, backendIp=172.26.5.214, backendPort=80, backendThreadModel=ReuseServerThread, receiveBuffer=10240, sendBuffer=10240, allocatorType=Pooled, maxContentLength=100000000)
Layer7ProxyServer Started with config: ServerConfig(type=Layer7ProxyServer, serverIp=172.26.5.213, serverPort=8888, backendIp=172.26.5.214, backendPort=80, backendThreadModel=ReuseServerThread, receiveBuffer=10240, sendBuffer=10240, allocatorType=Pooled, maxContentLength=2000)
能夠看到Netty 4.1中已經把默認的分配器設置爲了PooledByteBufAllocator
這裏總結了一個表格,性能損失比例都以第一行直接壓Nginx爲參照:
結論是:
之因此寫這個文章作這個分析的緣由是由於最近在作咱們自研網關的性能優化和壓力測試 github.com/spring-aven… 。 我發現有一些其它開源的基於Netty的代理項目並非複用鏈接的,可能做者沒有意識到這個問題,我看了下Zuul的代碼,它也是複用的。