一、API網(wǎng)關(guān)概述
1、什么是API網(wǎng)關(guān)
(1)為啥需要API網(wǎng)關(guān)
計算機科學(xué)領(lǐng)域的任何問題都可以通過增加一個間接的中間層來解決。
— David Wheeler
- API網(wǎng)關(guān)的觀念其實和當(dāng)前流行的SOA架構(gòu)和微服務(wù)架構(gòu)模式有關(guān)。在傳統(tǒng)大型企業(yè)比較流行的SOA架構(gòu)中,有一個企業(yè)服務(wù)總線(ESB)的概念,再ESB中融合了管理、注冊、中介、編排、治理等功能,是一個訪問高度頻繁、功能高度集中的地方,因此常常也是性能瓶頸所在。而在微服務(wù)架構(gòu)中,伴隨著去中心化的理念,幾乎沒有EBS的的概念,分布式服務(wù)架構(gòu)技術(shù)不再依賴于具體的服務(wù)中心容器技術(shù)( ESB),而是將服務(wù)尋址和調(diào)用完全分開,這樣就不需要通過容器作為服務(wù)代理,在運行期實現(xiàn)最高效的直連調(diào)用。
- 在微服務(wù)架構(gòu)中,服務(wù)的粒度被進一步細分,各個業(yè)務(wù)服務(wù)可以被獨立的設(shè)計、開發(fā)、測試、部署和管理。各個獨立部署單元可以用不同的開發(fā)測試團隊維護,可以使用不同的編程語言和技術(shù)平臺進行設(shè)計,這就要求必須使用一種語言和平臺無關(guān)的服務(wù)協(xié)議作為各個單元間的通訊方式。而REST API 由于其簡單、高效、跨平臺、易開發(fā)、易測試、易集成,成為了不二選擇。此時如果都是采用客戶端和服務(wù)器直連的話,那么此時系統(tǒng)就會出現(xiàn)大量的冗余代碼和功能,維護起來工作量巨大,而且隨著服務(wù)增多,出錯性也大大的增加。因此一個類似綜合前置的系統(tǒng)就產(chǎn)生了,這就是 API 網(wǎng)關(guān)(API Gateway)。API 網(wǎng)關(guān)作為分散在各個業(yè)務(wù)系統(tǒng)微服務(wù)的 API 聚合點和統(tǒng)一接入點,外部請求通過訪問這個接入點,即可訪問內(nèi)部所有的 REST API 服務(wù)。
(2)API網(wǎng)關(guān)定義
網(wǎng)關(guān)的角色是作為一個 API 架構(gòu),用來保護、增強和控制對于 API 服務(wù)的訪問。
- API 網(wǎng)關(guān)是一個處于應(yīng)用程序或服務(wù)(提供 REST API 接口服務(wù))之前的系統(tǒng),用來管理授權(quán)、訪問控制和流量限制等,這樣 REST API 接口服務(wù)就被 API 網(wǎng)關(guān)保護起來,對所有的調(diào)用者透明。因此,隱藏在 API 網(wǎng)關(guān)后面的業(yè)務(wù)系統(tǒng)就可以專注于創(chuàng)建和管理服務(wù),而不用去處理這些策略性的基礎(chǔ)設(shè)施。
- 通俗的說API網(wǎng)關(guān)中就是做一些通用的基礎(chǔ)設(shè)施功能。類似AOP中的橫切關(guān)注點概念,把業(yè)務(wù)系統(tǒng)中涉及的一些通用功能(日志分析、鑒權(quán)、路由等)抽取到API網(wǎng)關(guān)中統(tǒng)一管理。API 網(wǎng)關(guān)不是一個典型的業(yè)務(wù)系統(tǒng), 而是一個為了讓業(yè)務(wù)系統(tǒng)更專注與業(yè)務(wù)服務(wù)本身,給API服務(wù)提供更多附加能力的一個中間層。
(3)API網(wǎng)關(guān)的四大職能
請求接入:作為所有 API 接口服務(wù)請求的接入點,管理所有的接入請求;
業(yè)務(wù)聚合:作為所有后端業(yè)務(wù)服務(wù)的聚合點,所有的業(yè)務(wù)服務(wù)都可以在這里被調(diào)用;
中介策略:實現(xiàn)安全、驗證、路由、過濾、流控,緩存等策略,進行一些必要的中介處理;
統(tǒng)一管理:提供配置管理工具,對所有 API 服務(wù)的調(diào)用生命周期和相應(yīng)的中介策略進行統(tǒng)一管理。
(4)API網(wǎng)關(guān)關(guān)注點
(1)開發(fā)維護簡單,節(jié)約人力成本和維護成本。
(2)高性能,節(jié)約設(shè)備成本,提高系統(tǒng)吞吐能力。
(3)高可用(非常重要)
(4)方便靈活地實現(xiàn)安全、驗證、過濾、聚合、限流、監(jiān)控等各種策略。
二、API網(wǎng)關(guān)分類
- 如上圖所示,面對互聯(lián)網(wǎng)復(fù)雜的業(yè)務(wù)系統(tǒng),基本可以將API網(wǎng)關(guān)分成兩類:流量網(wǎng)關(guān)和業(yè)務(wù)網(wǎng)關(guān)。
流量網(wǎng)關(guān):跟具體的后端業(yè)務(wù)系統(tǒng)和服務(wù)完全無關(guān)的部分,比如安全策略、全局性流控策略、流量分發(fā)策略等。流量網(wǎng)關(guān)的功能跟 Web 應(yīng)用防火墻(WAF)非常類似。WAF一般是基于 Nginx/OpenResty 的 ngx_lua 模塊開發(fā)的 Web 應(yīng)用防火墻。
業(yè)務(wù)網(wǎng)關(guān):針對具體的后端業(yè)務(wù)系統(tǒng),或者是服務(wù)和業(yè)務(wù)有一定關(guān)聯(lián)性的部分,并且一般被直接部署在業(yè)務(wù)服務(wù)的前面。業(yè)務(wù)網(wǎng)關(guān)一般部署在流量網(wǎng)關(guān)之后,業(yè)務(wù)系統(tǒng)之前,比流量網(wǎng)關(guān)更靠近系統(tǒng)。我們大部分情況下說的 API 網(wǎng)關(guān),狹義上指的是業(yè)務(wù)網(wǎng)關(guān)。并且如果系統(tǒng)的規(guī)模不大,我們也會將兩者合二為一,使用一個網(wǎng)關(guān)來處理所有的工作
三、開源API網(wǎng)關(guān)介紹
目前常見的開源網(wǎng)關(guān)大致上按照語言分類有如下幾類:
Nginx+lua:Open Resty、Kong、Orange、Abtesting gateway 等
Java:Zuul/Zuul2、Spring Cloud Gateway、Kaazing KWG、gravitee、Dromara soul 等
Go:Janus、fagongzi、Grpc-gateway
Dotnet:Ocelot
NodeJS:Express Gateway、Micro Gateway
按照使用數(shù)量、成熟度等來劃分,主流的有 4 個:
OpenResty
Kong
Zuul/Zuul2
Spring Cloud Gateway
1、Nginx+Lua(Open Resty)
- OpenResty 基于 Nginx,集成了 Lua 語言和 Lua 的各種工具庫,可用的第三方模塊,這樣我們就在 Nginx 既有的高效 HTTP 處理的基礎(chǔ)上,同時獲得了 Lua 提供的動態(tài)擴展能力。官網(wǎng)是這么介紹的:
OpenResty? 是一個基于 Nginx 與 Lua 的高性能 Web 平臺,其內(nèi)部集成了大量精良的 Lua 庫、第三方模塊以及大多數(shù)的依賴項。用于方便地搭建能夠處理超高并發(fā)、擴展性極高的動態(tài) Web 應(yīng)用、Web 服務(wù)和動態(tài)網(wǎng)關(guān)。
OpenResty? 通過匯聚各種設(shè)計精良的 Nginx 模塊(主要由 OpenResty 團隊自主開發(fā)),從而將 Nginx 有效地變成一個強大的通用 Web 應(yīng)用平臺。這樣,Web 開發(fā)人員和系統(tǒng)工程師可以使用 Lua 腳本語言調(diào)動 Nginx 支持的各種 C 以及 Lua 模塊,快速構(gòu)造出足以勝任 10K 乃至 1000K 以上單機并發(fā)連接的高性能 Web 應(yīng)用系統(tǒng)。
OpenResty? 的目標(biāo)是讓你的 Web 服務(wù)直接跑在 Nginx 服務(wù)內(nèi)部,充分利用 Nginx 的非阻塞 I/O 模型,不僅僅對 HTTP 客戶端請求,甚至于對遠程后端諸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都進行一致的高性能響應(yīng)。
2、kong
項目地址:
https://konghq.com/
https://github.com/kong/kongKong 基于 OpenResty,是一個云原生、快速、可擴展、分布式的微服務(wù)抽象層(Microservice Abstraction Layer),也叫 API 網(wǎng)關(guān)(API Gateway),在 Service Mesh 里也叫 API 中間件(API Middleware)。
Kong 開源于 2015 年,核心價值在于高性能和擴展性。從全球 5000 強的組織統(tǒng)計數(shù)據(jù)來看,Kong 是現(xiàn)在依然在維護的,在生產(chǎn)環(huán)境使用最廣泛的 API 網(wǎng)關(guān)。
Kong 宣稱自己是世界上最流行的開源微服務(wù) API 網(wǎng)關(guān)(The World’s Most Popular Open Source Microservice API Gateway)。
3、Zuul/Zuul2
項目地址:https://github.com/Netflix/zuul
Zuul 是 Netflix 開源的 API 網(wǎng)關(guān)系統(tǒng),它的主要設(shè)計目標(biāo)是動態(tài)路由、監(jiān)控、彈性和安全。
Zuul 的內(nèi)部原理可以簡單看做是很多不同功能 filter 的集合
-
Zuul 1.x 基于同步 IO,也是 Spring Cloud 全家桶的一部分,可以方便的配合 Spring Boot/Spring Cloud 配置和使用。在 Zuul 1.x 里,filter 的種類和處理流程可以參見下圖,最主要的就是 pre、routing、post 這三種過濾器,分別作用于調(diào)用業(yè)務(wù)服務(wù) API 之前的請求處理、直接響應(yīng)、調(diào)用業(yè)務(wù)服務(wù) API 之后的響應(yīng)處理。
zuul1.x架構(gòu)圖 -
Zuul 2.x 最大的改進就是基于 Netty Server 實現(xiàn)了異步 IO 來接入請求,同時基于 Netty Client 實現(xiàn)了到后端業(yè)務(wù)服務(wù) API 的請求。這樣就可以實現(xiàn)更高的性能、更低的延遲。此外也調(diào)整了 filter 類型,將原來的三個核心 filter 顯式命名為:Inbound Filter、Endpoint Filter 和 Outbound Filter。
zuul2.x架構(gòu)圖
4、Spring Cloud Gateway
項目地址:
https://github.com/spring-cloud/spring-cloud-gateway/
Spring Cloud Gateway 基于 Java 8、Spring 5.0、Spring Boot 2.0、Project Reactor,發(fā)展的比 Zuul 2 要早,目前也是 Spring Cloud 全家桶的一部分。
Spring Cloud Gateway 可以看做是一個 Zuul 1.x 的升級版和代替品,比 Zuul 2 更早的使用 Netty 實現(xiàn)異步 IO,從而實現(xiàn)了一個簡單、比 Zuul 1.x 更高效的、與 Spring Cloud 緊密配合的 API 網(wǎng)關(guān)。
- Spring Cloud Gateway 里明確的區(qū)分了 Router 和 Filter,并且一個很大的特點是內(nèi)置了非常多的開箱即用功能,并且都可以通過 SpringBoot 配置或者手工編碼鏈?zhǔn)秸{(diào)用來使用。
5、四大開源網(wǎng)關(guān)框架對比
網(wǎng)關(guān) | 限流 | 鑒權(quán) | 監(jiān)控 | 易用性 | 可維護性 | 成熟度 |
---|---|---|---|---|---|---|
SGW | 可以通過IP,用戶,集群限流,提供了相應(yīng)的接口進行擴展 | 普通鑒權(quán)、auth2.0 | Gateway Metrics Filter | 簡單易用 | spring系列可擴展強,易配置 可維護性好 | spring社區(qū)成熟,但gateway資源較少 |
Zuul2.x | 可以通過配置文件配置集群限流和單服務(wù)器限流亦可通過filter實現(xiàn)限流擴展 | filter中實現(xiàn) | filter中實現(xiàn) | 參考資料較少 | 可維護性較差 | 開源不久,資料少 |
Kong | 根據(jù)秒,分,時,天,月,年,根據(jù)用戶進行限流。可在原碼的基礎(chǔ)上進行開發(fā) | 普通鑒權(quán),Key Auth鑒權(quán),HMAC,auth2.0 | 可上報datadog,記錄請求數(shù)量,請求數(shù)據(jù)量,應(yīng)答數(shù)據(jù)量,接收于發(fā)送的時間間隔,狀態(tài)碼數(shù)量,kong內(nèi)運行時間 | 簡單易用,api轉(zhuǎn)發(fā)通過管理員接口配置,開發(fā)需要lua腳本 | 可維護性較差,將來需要維護大量lua庫 | 相對成熟,用戶問題匯總,社區(qū),插件開源 |
Open Resty | 需要lua開發(fā) | 需要lua開發(fā) | 需要開發(fā) | 簡單易用,但是需要進行的lua開發(fā)很多 | 可維護性較差,將來需要維護大量lua腳本 | 很成熟資料很多 |
- 對 Zuul/Zuul2/Spring Cloud Gateway 的一些功能點分析可以參考 Spring Cloud Gateway 作者 Spencer Gibb 的文章:
https://spencergibb.netlify.com/preso/detroit-cf-api-gateway-2017-03/
6、四大開源網(wǎng)關(guān)性能對比
(1)實測情況是性能 SCG~Zuul2 << OpenResty ~< Kong << Direct(直連);
(2)Spring Cloud Gateway、Zuul2 的性能差不多,大概是直連的40%;
(3)OpenResty、Kong 差不多,大概是直連的 60-70%;
(4)大并發(fā)下,例如模擬 200 并發(fā)用戶、1000 并發(fā)用戶時,Zuul2 會有很大概率返回出錯。zuul2.x的可用性不好。
- 以上測試用到的模擬服務(wù)和網(wǎng)關(guān) demo 代碼,大部分可以在這里找到:
7、開源網(wǎng)關(guān)的選擇
脫離場景談性能,脫離業(yè)務(wù)談架構(gòu),都是耍流氓。
- (1)Kong 的性能非常不錯,非常適合做流量網(wǎng)關(guān),并且對于 service、route、upstream、consumer、plugins 的抽象,也是自研網(wǎng)關(guān)值得借鑒的。對于復(fù)雜系統(tǒng),不建議業(yè)務(wù)網(wǎng)關(guān)用 Kong,或者更明確的說是不建議在 Java 技術(shù)棧的系統(tǒng)深度定制 Kong 或 OpenResty,主要是工程性方面的考慮。畢竟維護lua腳本的工作量和成本不低。
- (2)pring Cloud Gateway/Zuul2 對于 Java 技術(shù)棧來說比較方便,可以依賴業(yè)務(wù)系統(tǒng)的一些 common jar。Lua 不方便,不光是語言的問題,更是復(fù)用基礎(chǔ)設(shè)施的問題。另外,對于網(wǎng)關(guān)系統(tǒng)來說,性能不是差一個數(shù)量級,問題不大,多加 2 臺機器就可以搞定。
- (3)目前來看 Zuul2 的坑還是比較多的,因此作為java技術(shù)棧,比較建議使用 Spring Cloud Gateway 作為基礎(chǔ)骨架。