導語:API Gateway是實現微服務重要的組件之一。面對諸多的開源API Gateway,如何進行選擇也是架構師須要關注的焦點。本文做者對幾個較大的開源API Gateway進行了壓力測試,對於架構師來講,相信能夠提供很多幫助。
過去一段時間,OpsGenie的員工數量和產品特性都經歷了快速發展。去年,僅僅是咱們的工程師團隊就由15人增加到了50人。針對開發團隊的劃分,咱們遵循兩個披薩原則[1]將每一個團隊控制在8個工程師。
如你所料的,咱們的產品仍是一個單體應用。對並行開發的團隊來講,CI/CD等過程,開發和運維都是有挑戰的。咱們跟隨當前的技術趨勢,正處於單體應用到微服務架構的過渡期。你能夠閱讀Martin Fowler的這篇文章[2],瞭解更多微服務架構和它的好處。
這裏有一些關於微服務概念推薦的架構模式[3]。其中的一個模式是API網關[4]。API網關是全部客戶端的統一入口。API網關對於任意一種處理請求有兩種方式處理。一部分請求只要簡單路由到相應的服務;還有一些請求須要拆分到多個服務。
API網關模式是開始微服務架構很好的切入點,由於它能路由具體的請求到拆分出來的不一樣服務。事實上,API網關對咱們來講不是一個新概念。到目前爲止,咱們已經使用過Nginx放在咱們的單體應用前面充當API網關,可是咱們想從新評估過渡時期繼續使用Nginx的合理性。咱們關心性能、可擴展性和其餘的擴展能力,例如限流。首先,評估大流量下的性能,確保它們能知足咱們的需求。
在這篇文章中,咱們講解如何設置咱們的測試環境,而且對比這些網關的性能: Zuul 1[5], Nginx[6], Spring Cloud Gateway[7], Linkerd[8]。事實上,咱們還有另外兩個選擇Envoy[9]和 UnderTow[10]。咱們將會對這些工具作相同的測試,而且在後面的博客中公佈測試結果。
Zuul 1因爲使用Java開發,而且對Spring框架有很強的支持,對咱們來講彷佛很合適。儘管有不少文章對比過Zuul和Nginx,可是咱們還想跟Spring Cloud Gateway和Linkerd一塊兒評估。此外,咱們計劃作高負載的測試,因此咱們決定設置咱們本身的測試環境。
爲了評估API網關各自的性能,咱們爲OpsGenie產品建立了一個隔離的獨立測試環境。咱們使用Apache的ab做爲壓測工具。
首先,咱們參照Nginx文檔在一個單核1G內存的AWS EC2實例上安裝了一個Nginx。這個環境是咱們的初始測試環境,而後咱們安裝Zuul和Spring Cloud Gateway到這個環境中。Nginx爲靜態資源提供web服務,咱們經過Nginx、Zuul和Spring Cloud Gateway定義反向代理到這個web服務。咱們一樣啓動了另一個單核1G內存的EC2實例發起壓測請求。
圖片中的箭頭是咱們的測試路徑。這裏有4中狀況:
- 直接訪問
- Nginx反向代理訪問
- Zuul訪問
- Spring Cloud Gateway訪問
- Linkerd訪問
咱們知道你們急於想看測試結果,因此,咱們先給測試結果,而後再作詳細說明。
性能壓測總結
測試策略
咱們使用Apache的ab作壓測工具。咱們發起總共10000個請求、使用200個併發線程分別進行壓測。
咱們將在3種不一樣配置的AWS EC2服務器上進行測試。咱們會縮小每一步的測試用例的範圍:
- 儘管咱們不選擇直接訪問,可是咱們在第一步額外作了直接訪問的測試,用於衡量代理的理想值,這個測試咱們不會在後面的步驟中進行。
- 儘管Spring Cloud Gateway依然沒有官方穩定版,咱們會在最後那步評估它。
- Zuul隨後的性能比第一次壓測的性能更好。咱們估計出現這種狀況的緣由是第一次壓測進行了JIT優化,因此咱們把針對Zuul的第一次壓測當成「預熱」。在總結表中的值是預熱以後的性能。
- 咱們知道Linkerd是資源密集型代理,因此咱們只在高資源配置的最後一步對比。
測試配置
T2.Micro——單核1G內存:咱們對比測試直接訪問、Nginx反向代理和Zuul(預熱以後)。
M4.Micro ——雙核8G內存:咱們對比測試Nginx反向代理和Zuul(預熱以後)。
M4.2xLarge——8核32G內存:咱們對比測試Nginx反向代理、Zuul(預熱以後)、Spring Cloud Gateway和Linkerd。
測試結果
性能壓測結果以下
測試詳情
直接訪問
首先,咱們不使用代理,直接訪問靜態資源。結果以下,單個請求平均30ms。
Nginx反向代理
咱們的第2個測試,經過Nginx反向代理訪問資源。單次請求平均耗時40ms。能夠說,Nginx代理對比直接訪問,平均增長了33%的耗時。
Zuul反向代理
接下來,咱們建立了一個Spring Boot應用:
這是咱們的application.yml文件:
Zuul第1次測試結果以下:
直接訪問Nginx單次請求是30ms,經過Nginx反向代理訪問是40ms。Zuul首次訪問單次請求在388ms。如在另一篇博客[12]中提到的,JVM預熱會有做用。咱們從新壓測,結果以下:
預熱後Zuul代理的性能更好(單次請求是200ms),可是跟Nginx反向代理的40ms對比,仍然很差。
服務器升級到雙核8G內存會怎麼樣呢?
前面的測試服務器配置是單核1G內存。Nginx是C++應用,Zuul是基於Java的。咱們知道,Java應用對環境要求更苛刻。因此咱們將服務器配置換成雙核8G內存實例。
咱們從新對Nginx和Zuul作壓測,結果以下
由上面圖片可見,Nginx反向代理和Zuul代理單次請求花費時間分別是32ms和95ms。此次壓測結果比單核1G內存的40ms和200ms更好。
因而可知,使用Spring Boot部署的Zuul有額外的消耗。極可能Zuul的獨立應用會有更好的性能。
服務器升級到8核32G內存會怎麼樣呢?
咱們繼續評估8核32G內存的服務器配置。Nginx和Zuul的壓測結果以下
在8核32G的配置上,Zuul跑贏了Nginx。咱們想找到Netflix的Zuul實例部署在哪一種類型的ec2服務器上,可是咱們沒有找到任何信息。一些博客中,有人說了Zuul的性能,而且詢問Netflix如何處理的。咱們認爲這多是答案,Zuul使用CPU綁定。
Linkerd壓測
Linkerd是CNCF的項目,是Scala開發的service mesh應用。他提供反向代理能力用於擴展service mesh能力,例如服務發現。咱們評估Linkerd性能而且給出以下結果。Linkerd跟Zuul的性能很接近。
Spring Cloud Gateway性能測試
Spring Cloud組織也開發了一個Gateway模塊。儘管官方尚未正式版本,咱們以爲仍是有必要跟其餘選擇進行對比。可是,咱們按照咱們的測試環境修改了Gateway的例子。
咱們用Apache的ab使用了20個線程、發了總共10000個請求作了一樣的壓測。測試結果在下面這張圖中:
由上圖可見,Spring Cloud Gateway每秒能處理873個請求,單次請求平均耗時229ms。根據咱們的測試結果,Spring Cloud Gateway不能達到Zuul、Linkerd、Nginx的性能水平,這是他們目前最新版本測試的結果。Nginx、Zuul、Linkerd和Spring Cloud Gateway的最後一次測試結果上面已經給出。
接下來呢?
這篇文章中,咱們使用Apache的工具ab對比了Zuul、Nginx、Linkerd和Spring Cloud Gateway的性能。下一步咱們的計劃以下:
- 咱們計劃去評估Envoy。事實上,Envoy不止是API網關,它是service mesh,可是也提供了API網關功能,能放在應用的前面。
- Undertow也有反向代理能力,因此咱們也計劃去評估一下。
- Netflix基於Netty的非阻塞從新設計了Zuul應用,新的版本叫「Zuul 2」。若是官方發佈了新版本的Zuul,咱們也會進行性能壓測,而後將壓測結果分享出來。
- Spring Cloud Gateway依然在開發中,基於Netty的非阻塞的Java網關,因此對咱們來講是一個很好的候選。咱們將會評估它的官方穩定版的性能。
- 一些API網關(Zuul 1)是阻塞的,另一些(Zuul 二、Linkerd、Envoy)是非阻塞的。阻塞架構對開發和跟蹤請求友好,可是阻塞可能產生擴展性問題。非阻塞架構對於團隊開發和跟蹤更復雜,可是有更好的可擴展和彈性。咱們以後將會決定使用阻塞架構仍是使用非阻塞架構。
- 咱們將使用Gatling作性能測試,將在咱們的下一篇博客中共享結果。
咱們將會在博客中共享每一步的成功結果,敬請期待!
文中連接
[1] http://www.businessinsider.com/jeff-bezos-two-pizza-rule-for-productive-meetings-2013-10
[2] https://martinfowler.com/articles/microservices.html
[3] http://microservices.io/patterns/microservices.html
[4] http://microservices.io/patterns/apigateway.html
[5] https://github.com/Netflix/zuul
[6] http://www.nginx.com/
[7] https://github.com/spring-cloud/spring-cloud-gateway
[8] https://linkerd.io/
[9] http://envoyproxy.io/
[10] http://undertow.io/
[11] https://httpd.apache.org/docs/2.4/programs/ab.html
[12] http://instea.sk/2015/04/netflix-zuul-vs-nginx-performance/
[13] https://gatling.io/
本文做者Turgay Çelik,由鄧啓明翻譯,轉載本文請註明出處,技術原創及架構實踐文章,歡迎經過公衆號菜單「聯繫咱們」進行投稿。
相關閱讀:
高可用架構