NGINX、HAProxy和Traefik負載均衡能力對比

NGINX、HAProxy和Traefik負載均衡能力對比

11 人贊了文章

網上有很多討論Nginx和HAProxy的文章,很多文章基本都是說這樣子的內容:

一、Nginx優點:

1、工作在網路7層之上,可針對http應用做一些分流的策略,如針對域名、目錄結構,它的正規規則比HAProxy更為強大和靈活,所以,目前為止廣泛流行。

2、Nginx對網路穩定性的依賴非常小,理論上能ping通就能進……

二、HAProxy優點:

1、HAProxy是支持虛擬主機的,可以工作在4、7層(支持多網段)

2、HAProxy的優點能夠補充Nginx的一些缺點,比如支持Session的保持,Cookie的引導;同時支持通過獲取指定的url來檢測……

詳細我就不全部貼了,大家也可以自己在google出來,很多一邊倒都說HAProxy的負載均衡能力比Nginx的要強,但是這些文章,很大一部分沒有一個真實的數據反映出HAProxy和Nginx哪一個能力更強,而且就算有,都是基於比較舊的版本去測試了。

這次我就親自測試Nginx和HAProxy的負載均衡能力上的區別,等著,標題不是還有一個Traefik嗎?嗯,在我搜索過程,我發現有外國的小伙也在討論Traefik,Traefik是一個反向代理器,是一個比較年輕的項目,對容器支持十分友好,早就2017年,我就在項目使用過,不過僅是在反向代理這一塊,在負載均衡上面沒有太多深入研究,中文社區中,對他的測評並不多,但很多說法都是說這貨的能力比較弱,事實真的如此嗎?

故事背景

公司在一個項目上需要用到負載均衡,但在我工作這麼多年上,我僅在測試環境上自己部署過Nginx的負載均衡,在生產環境上面,一直都是用雲平台提供的負載均衡服務,所以目前為止,對負載均衡的能力掌握比較小,所以我透過這次的測試來了解目前市面常用的負載均衡器的對比。

測試要求

  1. 負載均衡使用的是7層模型(所以這裡沒有提到LVS的原因)
  2. 需要解析HTTPS,在負載均衡直接解析HTTPS,到達後面服務後直接用HTTP,避免後續服務重新解析,消耗性能

前期準備

本次用到伺服器5台,配置均為4 CPUs,8G內存,40G存儲空間,centOS 7.4 系統。

伺服器1 IP:172.18.128.254

伺服器2 IP:172.18.128.255

伺服器3 IP:172.18.129.0

伺服器4 IP:172.18.129.1

伺服器5 IP:172.18.129.2

伺服器1、2、3用作部署Web服務,伺服器4用作部署負載均衡服務,伺服器5用作Web客戶端。

開始部署

首先部署伺服器1、2、3的Web服務,Web服務是一個由go編寫的服務,代碼如下:

package mainimport ( "log" "fmt" "net/http" "runtime" "io/ioutil")//Define the port used for this web applicationvar SERVER_PORT = ":8000"//Read the content of a filefunc serveContent(file string) string { b, err := ioutil.ReadFile(file) if err != nil { log.Print(err) return "{error:"Resource not found"}" } str := string(b) return str}//REST handlerfunc handler(w http.ResponseWriter, r *http.Request) { log.Print("Processing request: ", r.URL.Path[1:]) str := serveContent(r.URL.Path[1:]) fmt.Fprintf(w, str)}//Main programfunc main() { runtime.GOMAXPROCS(runtime.NumCPU()) log.Print("Starting webserver on Port", SERVER_PORT) http.HandleFunc("/", handler) http.ListenAndServe(SERVER_PORT, nil)}

我再編寫一個文件用於接下來請求用的:

# hello.txt{output:"I Love Spring Cloud"}

部署伺服器4的負載均衡服務,由於我比較懶,所有測試服務我都是用Docker來部署,至於HTTPS的證書,是通過Lets Encrypt去申請的,具體申請方法我再另一篇文章會有所提到。

首先,我們來編寫各個服務用到的配置文件,

Nginx的配置文件:

# /opt/app/nginx/config/minsheng.conf upstream minsheng.ms { server 172.18.128.254:8000; server 172.18.129.0:8000; server 172.18.128.255:8000;}server{ listen 80; listen 443 ssl; server_name test.ruishanio.net; ssl_certificate /etc/nginx/ssl/test.ruishanio.net/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/test.ruishanio.net/test.ruishanio.net.key; ssl_trusted_certificate /etc/nginx/ssl/test.ruishanio.net/ca.cer; location / { proxy_pass http://minsheng.ms; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }

HAProxy的配置文件:

# /opt/app/haproxy/conf/haproxy.cfgfrontend https_frontend bind *:443 ssl crt /etc/ssl/test.ruishanio.net/test.ruishanio.net.pem mode http option httpclose option forwardfor reqadd X-Forwarded-Proto: https default_backend web_serverbackend web_server mode http balance roundrobin server s1 172.18.128.254:8000 inter 2000 fall 3 server s2 172.18.129.0:8000 inter 2000 fall 3 server s3 172.18.128.255:8000 inter 2000 fall 3

Traefik的配置文件:

# /opt/app/traefik/conf/traefik.toml[entryPoints] [entryPoints.http] address = ":80" [entryPoints.https] address = ":443" [entryPoints.https.tls] [[entryPoints.https.tls.certificates]] certFile = "/etc/ssl/test.ruishanio.net/fullchain.cer" keyFile = "/etc/ssl/test.ruishanio.net/test.ruishanio.net.key"[file][backends] [backends.backend1] [backends.backend1.servers] [backends.backend1.servers.server0] url = "http://172.18.128.254:8000" weight = 1 [backends.backend1.servers.server1] url = "http://172.18.129.0:8000" weight = 1 [backends.backend1.servers.server2] url = "http://172.18.128.255:8000" weight = 1[frontends] [frontends.frontend1] entryPoints = ["http", "https"] backend = "backend1" passHostHeader = true[[tls]] entryPoints = ["https"] [tls.certificate] certFile = "/etc/ssl/test.ruishanio.net/fullchain.cer" keyFile = "/etc/ssl/test.ruishanio.net/test.ruishanio.net.key"

部署命令分別是:

# Nginxdocker run -d --net=host -v /opt/app/nginx/config/:/etc/nginx/conf.d/ -v /opt/app/ssl:/etc/nginx/ssl --name nginx nginx# HAProxydocker run -d --net=host -v /opt/app/haproxy/conf/:/usr/local/etc/haproxy -v /opt/app/ssl:/etc/ssl --name=haproxy haproxy# Traefikdocker run -d --net=host -v /opt/app/traefik/conf/:/etc/traefik -v /opt/app/ssl/:/etc/ssl --name=traefik traefik

最後,我們部署測試機的環境,我們選用 wrk 作為測試工具,CentOS安裝wrk參考這裡:Installing wrk on Linux

進行測試

現在我們開始進行測試,首先我們分別裸跑三個服務的性能會到哪裡。

$ wrk -t 10 -c 200 -d 60s -T 30s --latency http://172.18.128.254:8000/hello.txtRunning 1m test @ http://172.18.128.254:8000/hello.txt 10 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 3.47ms 3.26ms 48.20ms 76.78% Req/Sec 6.75k 445.49 21.86k 86.84% Latency Distribution 50% 3.44ms 75% 5.26ms 90% 7.68ms 99% 13.68ms 4030219 requests in 1.00m, 568.84MB readRequests/sec: 67058.69Transfer/sec: 9.46MB$ wrk -t 10 -c 200 -d 60s -T 30s --latency http://172.18.128.255:8000/hello.txtRunning 1m test @ http://172.18.128.255:8000/hello.txt 10 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 15.04ms 80.06ms 1.06s 97.78% Req/Sec 5.39k 532.13 12.06k 93.46% Latency Distribution 50% 4.38ms 75% 7.02ms 90% 11.02ms 99% 492.93ms 3139915 requests in 1.00m, 443.18MB readRequests/sec: 52309.88Transfer/sec: 7.38MB$ wrk -t 10 -c 200 -d 60s -T 30s --latency http://172.18.129.0:8000/hello.txtRunning 1m test @ http://172.18.129.0:8000/hello.txt 10 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 3.51ms 3.35ms 42.92ms 80.40% Req/Sec 6.75k 800.56 64.34k 99.15% Latency Distribution 50% 3.46ms 75% 5.33ms 90% 7.84ms 99% 14.01ms 4027949 requests in 1.00m, 568.52MB readRequests/sec: 67021.06Transfer/sec: 9.46MB

除了 172.18.128.255 這台機弱一點外,其餘兩台機的性能都能達到67000請求/秒的能力。

接下來我們首先測試Nginx的負載均衡的能力。

$ wrk -t 10 -c 200 -d 60s -T 30s --latency https://test.ruishanio.net/hello.txtRunning 1m test @ https://test.ruishanio.net/hello.txt 10 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 18.26ms 1.71ms 44.14ms 71.24% Req/Sec 1.09k 108.54 1.84k 80.41% Latency Distribution 50% 18.14ms 75% 19.37ms 90% 20.49ms 99% 22.33ms 647237 requests in 1.00m, 119.72MB readRequests/sec: 10782.14Transfer/sec: 1.99MB

可以看到,Nginx最終能夠去到10000請求/秒的能力。

然後,我們測試HAProxy的負載均衡能力。

$ wrk -t 10 -c 200 -d 60s -T 30s --latency https://test.ruishanio.net/hello.txtRunning 1m test @ https://test.ruishanio.net/hello.txt 10 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 39.50ms 3.21ms 106.74ms 71.21% Req/Sec 415.63 42.95 1.43k 79.00% Latency Distribution 50% 39.43ms 75% 41.54ms 90% 43.43ms 99% 46.43ms 247707 requests in 1.00m, 39.45MB readRequests/sec: 4122.57Transfer/sec: 672.33KB

測試結果表明,HAProxy的測試只達到了4100請求/秒的能力。

最後,我們來進行測試Traefik的負載均衡能力。

$ wrk -t 10 -c 200 -d 60s -T 30s --latency https://test.ruishanio.net/hello.txtRunning 1m test @ https://test.ruishanio.net/hello.txt 10 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 9.24ms 4.16ms 192.86ms 73.97% Req/Sec 2.18k 280.31 19.41k 94.82% Latency Distribution 50% 9.57ms 75% 10.81ms 90% 14.70ms 99% 18.67ms 1300778 requests in 1.00m, 183.60MB readRequests/sec: 21644.33Transfer/sec: 3.05MB

很難想像,這貨居然達到了21000請求/秒的能力。

最後,貼一下這幾個負載均衡在測試過程中的CPU佔用率。

第一個峰值是Nginx 32%左右,第二個峰值是HAProxy 20%左右,最後一個是Traefik 76%左右,三個服務都沒有把整台機的CPU利用完。

從利用率來看,Nginx 每1%的CPU佔用率 312請求,HAProxy為 每1%請求佔用率 205 請求,Traefik 每1%的CPU佔用率 276 請求。從CPU利用率來看,Nginx的利用率最高。

總結

這是一個開放題,最後我選擇了哪一個服務,我不在此處闡述。但我對這次的測試總結一下。

關於HAProxy,互聯網對它的負載均衡能力評價是最高的,但測試結果表明,它的負載均衡能力表現最差,也不知道是我測試方法有問題還有配置不合理造成,但我修改了幾次配置再測試,結果也不會相差太遠。

而Nginx,請求結果上它不是最高,但是在CPU利用比上面,它佔了最大優勢。

最後是Traefik,這個後起之秀簡直刮目相看,它儘可能地壓榨了整體CPU的性能,CPU的利用率它是最高的,請求數也到達了Nginx的兩倍,HAProxy的5倍,唯一遺憾的是CPU利用比上,它不如Nginx。

大家如何選擇負載均衡的話,可以參考我這篇文章,有疑問,有問題,也可以留言討論。

推薦閱讀:

TAG:負載均衡 | Nginx | haproxy |