Netflix Zuul與Nginx的性能對比

https://mp.weixin.qq.com/s/zW5chRcxqeUYoCX-aiITYwhtml

這是一篇翻譯,關於你們常常質疑的一個問題:API網關Zuul的性能。

做者:STANISLAV MIKLIK
原文:NETFLIX ZUUL VS NGINX PERFORMANCE
http://instea.sk/2015/04/netflix-zuul-vs-nginx-performance/

現在你能夠聽到不少關於「微服務」的信息。Spring Boot是一個用來構建單個微服務應用的理想選擇,可是你還須要以某種方式將它們互相聯繫起來。這就是Spring Cloud試圖解決的問題,尤爲是Spring Cloud Netflix。它提供了各類組件,好比:Eureka服務發現與Ribbon客戶端負載均衡的結合,爲內部「微服務」提供通訊支持。可是,若是你想要與外界通訊時(你提供外部API,或只是從你的頁面使用AJAX),將各類服務隱藏在一個代理以後是一個明智的選擇。nginx

常規的選擇咱們會使用Nginx做爲代理。可是Netflix帶來了它本身的解決方案——智能路由Zuul。它帶有許多有趣的功能,它能夠用於身份驗證、服務遷移、分級卸載以及各類動態路由選項。同時,它是使用Java編寫的。若是Netflix使用它,那麼它與本地反向代理相比是否足夠快呢?或者當咱們對靈活性(或其餘功能)要求更高時,它是否適合與Nginx聯合使用。web

免責聲明:不要認爲這是一個嚴肅的基準。我只是想感覺Nginx和Zuul的差別,由於我在互聯網上並無找到任何基準(也多是我沒有搜索足夠長的時間)。它不遵循任何推薦的基準測試方法(預熱時間、測試次數……),我只是使用3個在不一樣可用區域的EC2實例(這不是最佳的)。服務器

測試

那我作了什麼呢?測試是比較兩種解決方案的原始性能,沒有任何其餘特殊的功能。我只是同時發起單個HTTP請求來獲取一個HTML頁面(大小約爲26KB)。我使用ApacheBench來發起200個併發線程的測試(我也嘗試了httpperf,可是它須要更高的CPU要求,因此仍是選擇了要求更低的ab)。微信

直接鏈接

首先,我感興趣的是不經過任何反向代理直接訪問HTTP服務器的性能。Ab在一臺機器上運行,直接訪問目標服務器。併發

$ ab -n 10000 -c 200 http://target/sample.html

....

Document Path: /sample.html
Document Length: 26650 bytes

Total transferred: 268940000 bytes
HTML transferred: 266500000 bytes
Requests per second: 2928.45 [#/sec] (mean)
Time per request: 68.295 [ms] (mean)
Time per request: 0.341 [ms] (mean, across all concurrent requests)
Transfer rate: 76911.96 [Kbytes/sec] received

Connection Times (ms)
 min mean[+/-sd] median max
Connect: 4 33 6.0 32 66
Processing: 20 35 7.5 35 392
Waiting: 20 35 6.4 34 266
Total: 24 68 7.8 66 423

Percentage of the requests served within a certain time (ms)
 50% 66
 66% 67
 75% 69
 80% 70
 90% 74
 95% 81
 98% 91
 99% 92
 100% 423 (longest request)

很好,幾回測試都顯示了相似的值:292八、272五、283四、2648 req/s。有一些誤差,但這些數字如今還不重要。app

經過Nginx

如今我可使用Nginx的代理服務。只須要將Nginx配置更新爲代理到目標服務器,好比:負載均衡

server {
   listen 80 default_server;
   listen [::]:80 default_server ipv6only=on;

   # Make site accessible from http://localhost/
   server_name localhost;

   # allow file upload
   client_max_body_size 10M;

   location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_set_header Host $host;
      proxy_pass http://target:80;
   }
}

像以前同樣運行類型的測試:ide

$ ab -n 50000 -c 200 http://proxy/sample.html
...
Server Software: nginx/1.4.6
Server Hostname: proxy
Server Port: 80

Document Path: /sample.html
Document Length: 26650 bytes

Concurrency Level: 200
Time taken for tests: 52.366 seconds
Complete requests: 50000
Failed requests: 0
Total transferred: 1344700000 bytes
HTML transferred: 1332500000 bytes
Requests per second: 954.81 [#/sec] (mean)
Time per request: 209.465 [ms] (mean)
Time per request: 1.047 [ms] (mean, across all concurrent requests)
Transfer rate: 25076.93 [Kbytes/sec] received

Connection Times (ms)
 min mean[+/-sd] median max
Connect: 3 50 11.7 48 114
Processing: 37 159 11.9 160 208
Waiting: 36 159 11.9 160 207
Total: 40 209 10.4 209 256

Percentage of the requests served within a certain time (ms)
 50% 209
 66% 212
 75% 214
 80% 216
 90% 220
 95% 224
 98% 232
 99% 238
 100% 256 (longest request)

測試結果爲95四、95四、941 req/s。性能與延遲(如預期)變差了。微服務

經過Zuul

如今咱們在同一臺機器上安裝Zuul。它的應用自己很簡單:

@SpringBootApplication
@Controller
@EnableZuulProxy
public class DemoApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(DemoApplication.class)
            .web(true).run(args);
    }
}

咱們還須要在 application.yml中定義固定的路由規則:

zuul:
  routes:
    sodik:
      path: /sodik/**
      url: http://target

如今咱們試試運行測試:

$ ab -n 50000 -c 200 http://proxy:8080/sodik/sample.html

Server Software: Apache-Coyote/1.1
Server Hostname: proxy
Server Port: 8080

Document Path: /sodik/sample.html
Document Length: 26650 bytes

Concurrency Level: 200
Time taken for tests: 136.164 seconds
Complete requests: 50000
Failed requests: 2
(Connect: 0, Receive: 0, Length: 2, Exceptions: 0)
Non-2xx responses: 2
Total transferred: 1343497042 bytes
HTML transferred: 1332447082 bytes
Requests per second: 367.20 [#/sec] (mean)
Time per request: 544.657 [ms] (mean)
Time per request: 2.723 [ms] (mean, across all concurrent requests)
Transfer rate: 9635.48 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 2 12 92.3 2 1010
Processing: 15 532 321.6 461 10250
Waiting: 10 505 297.2 441 9851
Total: 17 544 333.1 467 10270

Percentage of the requests served within a certain time (ms)
50% 467
66% 553
75% 626
80% 684
90% 896
95% 1163
98% 1531
99% 1864
100% 10270 (longest request)

結果比我(樂觀的)猜想更差。此外,咱們還能看到兩次請求失敗(咱們能夠在Zuul的日誌中看到有兩個相應的異常,這些異常引起了HTTP鏈接池超時)。顯然默認狀況下超時時間爲10秒。

咱們再進一步測試,獲得了更多的結果:

Document Path: /sodik/sample.html
Document Length: 26650 bytes

Concurrency Level: 200
Time taken for tests: 50.080 seconds
Complete requests: 50000
Failed requests: 0
Total transferred: 1343550000 bytes
HTML transferred: 1332500000 bytes
Requests per second: 998.39 [#/sec] (mean)
Time per request: 200.322 [ms] (mean)
Time per request: 1.002 [ms] (mean, across all concurrent requests)
Transfer rate: 26199.09 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 2 16 7.9 16 126
Processing: 15 184 108.1 203 1943
Waiting: 13 183 105.9 202 1934
Total: 18 200 107.8 218 1983

Percentage of the requests served within a certain time (ms)
50% 218
66% 228
75% 235
80% 239
90% 254
95% 287
98% 405
99% 450
100% 1983 (longest request)

哇,不錯的改善。我認爲Java JIT編譯對於性能有必定的幫助,可是要驗證這是否只是一個巧合,再嘗試一次:1010 req / sec。最終結果對我來講是一個驚喜。

結論

Zuul的原始性能很是接近於Nginx。事實上,在啓動預測以後,個人測試結果甚至略好一些(重申免責聲明-這並不是一個嚴肅的基準性能測試)。Nginx顯示出更多的可預測性能(變化較小),可悲的是在Zuul預熱期間,咱們經歷了一些小故障(150000個請求中的2個,可是您的微服務應該是容錯機制的,對吧?)。

因此,若是您考慮使用一些Zuul的額外功能,或者但願經過它與其餘Netflix服務集成(好比Eureka)得到更多的服務能力,Zuul看起來很是有但願做爲簡單反向代理的替代產品。也許這也是Netflix使用的緣由,因此您也能夠嘗試一下。

活動推薦:Spring Cloud 中國社區沙龍上海站
版權聲明

本文采用 CC BY 3.0 CN協議 進行許可。 可自由轉載、引用,但需署名做者且註明文章出處。如轉載至微信公衆號,請在文末添加做者公衆號二維碼。
關注本號
Netflix Zuul與Nginx的性能對比
Netflix Zuul與Nginx的性能對比
好書推薦
Netflix Zuul與Nginx的性能對比

相關文章
相關標籤/搜索