各大API網關性能比較

用於實現API網關的技術有不少,大體分爲這麼幾類:git

  • 通用反向代理:Nginx、Haproxy、……
  • 網絡編程框架:Netty、Servlet、……
  • API網關框架:Spring Cloud Gateway、Zuul、Zuul二、……

API網關最基本的功能就是反向代理,因此在對API網關作技術選型的時候須要着重考察其性能表現,本文對Nginx、Haproxy、Netty、Spring Cloud Gateway、Zuul2作了性能測試,測試代碼能夠在github得到。github

測試方法

  • 準備了三臺2CPU 4G內存的服務器,分別運行Tomcat、API Gateway、Gatling(壓測工具)
  • 先對Tomcat作壓測,取Tomcat充分預熱後的壓測結果做爲基準。壓的是Tomcat自帶的example:/examples/jsp/jsp2/simpletag/book.jsp
  • 在對Netty、Zuul二、Spring Cloud Gateway作壓測時候也是先壓個幾輪作預熱。
  • 被測的API網關都沒有添加額外業務,只作反向代理

吞吐量

下圖是吞吐量的狀況,能夠看到Netty、Nginx、Haproxy均比直壓Tomcat低一點點,而Spring Cloud Gateway和Zuul2則要低得多。算法

clipboard.png

下面這張圖能夠更明顯的看到吞吐量比較,Tomcat爲100%由於它是基準值,Netty、Nginx、Haproxy的只比基準值低8%,而Spring Cloud Gateway和Zuul2則只是基準值的35%和34%(難兄難弟)。編程

clipboard.png

平均響應時間

下圖能夠看到Netty、Nginx、Haproxy的平均響應時間與Tomcat差很少。可是Spring Cloud Gateway和Zuul2則是Tomcat的3倍多,不出所料。api

clipboard.png

下圖一樣是以Tomcat做爲基準值的比較:服務器

clipboard.png

響應時間分佈

光看平均響應時間是不夠的,咱們還得看P50、P90、P9九、P99.9以及Max響應時間(惋惜Gatling只能設置4個百分位,不然我還想看看P99.99的響應時間)。網絡

爲什麼要觀察P99.9的響應時間?光看P90不夠嗎?理由有兩個:

1)觀察P9九、P99.九、P99.99的響應時間能夠觀察系統的在高壓狀況下的穩定性,若是這三個時間的增加比較平滑那麼說明該系統在高壓力狀況下比較穩定,若是這個曲線很是陡峭則說明不穩定。框架

2)觀察P9九、P99.九、P99.99的響應時間可以幫助你估算用戶體驗。假設你有一個頁面會發出5次請求,那麼這5次請求均落在P90之內機率是多少?90%^5=59%,至少會經歷一次 > P90響應時間的機率是 100%-59%=41%,若是你的P90=10s,那麼就意味着用戶有41%的機率會在加載頁面的時候超過10s,是否是很驚人?若是你的P99=10s,那麼用戶只有5%的機率會在訪問頁面的時候超過10s。若是P99.9=10s,則有0.4%的機率。jsp

關於如何正確測量系統能夠看 「How NOT to Measure Latency」 by Gil Tene工具

clipboard.png

下面一樣是把結果與Tomcat基準值作對比:

clipboard.png

能夠看到幾個頗有趣的現象:

  • Haproxy、Nginx的P50、P90、P9九、P99.九、Max都是逐漸遞增的。
  • Netty的P50、P90、P9九、P99.9是很平坦的,Max則爲基準值的207%。
  • Spring Cloud Gateway和Zuul2則是相反的,它們的平面呈現降低趨勢。Spring Cloud Gateway的Max甚至還比基準值低了一點點(94%),我相信這只是一個隨機出現的數字,不要太在乎。

結論

Nginx、Haproxy、Netty三者的表現均很不錯,其對於吞吐量和響應時間的性能損耗很低,能夠忽略不計。

可是目前最爲火熱的Spring Cloud Gateway和Zuul2則表現得比較糟糕,因我沒有寫額外的業務邏輯這,能夠推測這和它們的內置邏輯有關,那麼大體有這麼幾種可能:

  1. 內置邏輯比較多
  2. 內置邏輯算法存在問題,佔用了太多CPU時間
  3. 內置邏輯存在阻塞
  4. 內置邏輯沒有用正確姿式使用Netty(二者皆基於Netty)

不論是上面的哪種都須要再後續分析。

不過話說回來考慮選用那種做爲API網關(的基礎技術)不光要看性能,還要看:

  • 是否易於擴展本身的業務邏輯
  • API使用的便利性
  • 代碼的可維護性
  • 文檔是否齊全
  • ...

性能只是咱們手裏的一個籌碼,當咱們知道這個東西性能到底幾何後,才能夠與上面的這些作交換(trade-off)。好比Nginx和Haproxy的可擴展性不好,那麼咱們可使用Netty。若是你以爲Netty的API太底層了太難用了,那麼能夠考慮Spring Cloud Gateway或Zuul2。前提是你知道你會失去多少性能。

相關文章
相關標籤/搜索