spring cloud中gateway存在的意義是什麼?

王瑜瑜


先讓我們看這樣一個場景吧,一個電商網站做了服務化,後端服務分別拆成了用戶服務、商品服務、支付服務、物流服務(為了舉例,做了簡化,實際場景會遠比這個複雜);前端有網頁版和 APP,前端的所有操作都需要調用後端的各個服務。

在這個過程中,可能會有這樣的問題:

問題1.

前端應用需要知道後端每個服務的地址,或者必須接入服務中心;但是服務的地址和端口可能會動態變化。


問題2.

每個服務的技術棧必須相同,遵守相同的接口規範,接口協議必須相同,否則對於前度極度不友好。


問題3

網頁版和 APP 展示相同的內容時,可能粒度不同,要麼服務端提供粗粒度和細粒度兩種 API,要麼只提供一組最細粒度的 API,前者增加了後端的開發量,後者可能會導致一次前端需要多次調用細粒度的 API,才能得到想要的數據。


問題4

不同的客戶端設備展示的數據不同,比如網頁版能展示的數據更詳細一些,APP 展示的數據少,那麼也會有“提供一個大而全的接口”還是“為不同的調用方提供不同接口”的問題。


問題5

日誌、認證和鑑權、計費、監控等等功能,需要各個後端來完善,或者接入到對應的公共組件中(接入也是需要開發的),這就多多少少增加了後端服務的工作。


API Gateway 就是為了解決以上種種問題的;API Gateway 是系統的唯一入口,它屏蔽掉了系統的內部架構,為調用方定製了統一的 API。

單節點網關


多網關集群


我們可以看到 API Gateway 的作用:

  • 把後端各個服務的 API 聚合起來,提供統一且唯一規範的入口,這樣使得內部的架構對於調用方透明,客戶端和服務端的耦合度降低;各個後端服務之間,可以採用不同的實現方案,而 API Gateway 會屏蔽掉這些差異;

  • 後端的每個服務也都是在不斷迭代和升級的,API Gateway 可以將請求路由到不同的接口版本上,可以實現灰度發佈;

  • API Gateway 可以進行服務編排,實現數據聚合,也就是調用方一次請求,API Gateway 調用多個服務拿到數據後返回;

  • API Gateway 知道所有服務實例的地址,可以對不同的服務採用不同的路由策略;

  • 日誌、認證和鑑權、計費、監控等等功能都可以在 API Gateway 上實現;

  • API Gateway 還可以對流量進行控制,通過熔斷、降級、限流等方式,保護後端服務。


我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注;關注我後,可私信發送數字【1】,獲取海量學習資料。


會點代碼的大叔


一、微服務和Spring Cloud介紹

微服務,關鍵其實不僅僅是微服務本身,而是系統要提供一套基礎的架構,這種架構使得微服務可以獨立的部署、運行、升級,不僅如此,這個系統架構還讓微服務與微服務之間在結構上“松耦合”,而在功能上則表現為一個統一的整體。這種所謂的“統一的整體”表現出來的是統一風格的界面,統一的權限管理,統一的安全策略,統一的上線過程,統一的日誌和審計方法,統一的調度方式,統一的訪問入口等。微服務的目的是有效的拆分應用,實現敏捷開發和部署 。

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發便利性巧妙地簡化了分佈式系統基礎設施的開發,如服務發現註冊、配置中心、消息總線、負載均衡、斷路器、數據監控等,都可以用Spring Boot的開發風格做到一鍵啟動和部署。Spring Cloud並沒有重複製造輪子,它只是將各家公司開發的比較成熟、經得起實際考驗的服務框架組合起來,通過Spring Boot風格進行再封裝屏蔽掉了複雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分佈式系統開發工具包。

二、API網關在微服務架構體系中作用

採用API網關,實現一個API網關接管所有的入口流量,是系統的唯一入口,將所有用戶的請求轉發給後端的服務器,但網關做的不僅僅只是簡單的轉發,也會針對流量做一些擴展。從面向對象設計的角度看,它與外觀模式類似。API網關封裝了系統內部架構,為每個客戶端提供一個定製的API。

比如鑑權、限流、權限、熔斷、協議轉換、錯誤碼統一、緩存、日誌、監控、告警等,這樣將通用的邏輯抽出來,由網關統一去做,業務方也能夠更專注於業務邏輯,提升迭代的效率。

通過引入API網關,客戶端只需要與API網關交互,而不用與各個業務方的接口分別通訊,但多引入一個組件就多引入了一個潛在的故障點,因此要實現一個高性能、穩定的網關,也會涉及到很多點。

API網關方式的核心要點是,所有的客戶端和消費端都通過統一的網關接入微服務,在網關層處理所有的非業務功能。通常,網關也是提供REST/HTTP的訪問API。服務端通過API-GW註冊和管理服務。

三、當前各種API網關技術方案對比

使用一個組件時,尤其是這種比較流行的架構,組件肯定存在開源的,我們不必自己去從零開始去實現一個網關,自己開發一個網關的工作量是相當可觀的,現在比較流行的開源 API:

Spring Cloud Gateway

Spring Cloud Gateway是一款非常實用的微服務網關,在Spring Cloud微服務架構體系中發揮非常大的作用。Spring Cloud Gateway 是 Spring Cloud 微服務平臺的一個子項目,屬於 Spring 開源社區,依賴名叫:spring-cloud-starter-gateway。

https://spring.io/projects/spring-cloud-gateway

Spring Cloud Gateway構建於 Spring 5+,基於 Spring Boot 2.x 響應式的、非阻塞式的 API。同時,它支持 websockets,和 Spring 框架緊密集成,開發體驗相對來說十分不錯。

Zuul

Zuul 是 Netflix 公司的開源項目,Spring Cloud 在 Netflix 項目中也已經集成了 Zuul,依賴名叫:spring-cloud-starter-netflix-zuul。

https://github.com/Netflix/zuul

Spring Cloud Gateway網關和Zuul網關對比

四、Spring Cloud Gateway核心要點

網關提供API全託管服務,豐富的API管理功能,輔助企業管理大規模的API,以降低管理成本和安全風險,包括協議適配、協議轉發、安全策略、防刷、流量、監控日誌等貢呢。一般來說網關對外暴露的URL或者接口信息,我們統稱為路由信息。如果研發過網關中間件或者使用過Zuul的人,會知道網關的核心是Filter以及Filter Chain(Filter責任鏈)。Sprig Cloud Gateway也具有路由和Filter的概念。

Spring Cloud Gateway主要特性:

  • 基於Spring Framework 5、Project Reactor和Spring Boot 2.0構建

  • 能夠在任意請求屬性上匹配路由

  • predicates(謂詞) 和 filters(過濾器)是特定於路由的

  • 集成了Hystrix斷路器

  • 集成了Spring Cloud DiscoveryClient

  • 易於編寫謂詞和過濾器

  • 請求速率限制

  • 路徑重寫

下面介紹一下Spring Cloud Gateway中幾個重要的概念。

  • 路由。路由是網關最基礎的部分,路由信息有一個ID、一個目的URL、一組斷言和一組Filter組成。如果斷言路由為真,則說明請求的URL和配置匹配

  • 斷言。Java8中的斷言函數。Spring Cloud Gateway中的斷言函數輸入類型是Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的斷言函數允許開發者去定義匹配來自於http request中的任何信息,比如請求頭和參數等。

  • 過濾器。一個標準的Spring webFilter。Spring cloud gateway中的filter分為兩種類型的Filter,分別是Gateway Filter和Global Filter。過濾器Filter將會對請求和響應進行修改處理。

如上圖所示,Spring Cloud Gateway發出請求。然後再由Gateway Handler Mapping中找到與請求相匹配的路由,將其發送到Gateway web handler。Handler再通過指定的過濾器鏈將請求發送到我們實際的服務執行業務邏輯,然後返回。


軟件新視界


網關網關,一夫當關萬夫莫開。最重要的意義就是為軟件系統提供安全保障了,人們往往把API鑑權放到網關上來做,因為這樣處理簡單高效,而且能夠很好的保護後端應用。這樣能夠很好的控制網絡請求,而不必將所有後端服務暴露在外部環境中從而有潛在的安全風險。


其次就是為前端提供了統一的API入口,相當於規範了API路徑,這為前後端API對接提供了很大的便利。使得團隊開發變得高效。所以說這個網關還是非常重要滴。


程序猿藍天


Java開發者都知道大名鼎鼎的Spring,可以這樣說,目前市面上所需要的功能Spring全家桶(Spring、Spring Boot、Spring Cloud)都提供了完美的解決方案。

Spring Cloud它是基於Spring Boot的一款微服務開發框架,它提供了配置管理、服務發現、熔斷器、路由、服務跟蹤及治理等微服務開發一整套的解決方案。

微服務技術中的網關(Gateway)技術

網關(Gateway)是任何微服務架構中最為重要的一部分,網關就好比是一個門衛,嚴格把關外來訪客與內部微服務之間的溝通聯繫。其實,網關是微服務對外的唯一入口!外部發起的所有請求都是要經過網關的,由網關來決定不同的請求到不同的微服務程序去處理。

Spring Cloud中的網關技術

Spring Cloud中的網關不止一種,Spring Cloud中最早期的網關採用的是Zuul,後來改用了Spring Cloud Gateway。

1、Zuul不是Spring Cloud官方推出的

Zuul網關其實是Netflix開發的,它是阻塞式API,而且不支持長連接和Websocket,所以是有一定缺陷的。

2、Spring Cloud Gateway是用來替代Zuul網關的

Spring 5起就推出了自己的網關:Spring Cloud Gateway。它是基於Spring Boot開發的,性能上比Zuul要好,而且在配置及使用上都要比Zuul更方便。

總結

Spring Cloud Gateway是用來替代Zuul網關的,是由Spring官方開發維護的,無論在性能還是操作上都優於Zuul。在新一代Spring Cloud項目中推薦使用。


網絡圈


SpringCloudGateway和SpringCloudZuul一樣是微服務網關,不過Gateway是SpringCloud官方推出的,而Zuul是Netflix推出的。

看其他人的一些文章說是Gateway是用於取代Zuul的第二代網關,這個我在官方找不到資料說明。

主要術語

default-filters: 裡面可以定義一些共同的filter,對所有路由都起作用

routes:具體的路由信息,是一個數組,每一個路由基本包含部分:

id:這個路由的唯一id,不定義的話為一個uuid

uri:http請求為lb://前綴 + 服務id;ws請求為lb:ws://前綴 + 服務id;表示將請求負載到哪一個服務上

predicates:表示這個路由的請求匹配規則,只有符合這個規則的請求才會走這個路由。為一個數組,每個規則為並且的關係。

filters:請求轉發前的filter,為一個數組。

order:這個路由的執行order

網關請求

SpringCloudGateway限流原理與實踐

緩存、降級和限流是開發高併發系統的三把利器。緩存的目的是提升系統訪問速度和增大系統能處理的容量,可謂是抗高併發流量的銀彈;降級是當服務出現問題或者影響到核心流程的性能則需要暫時屏蔽,待高峰或者問題解決後再打開;而有些場景並不能用緩存和降級來解決,比如稀缺資源、寫服務、頻繁的複雜查詢,因此需有一種手段來限制這些場景的併發/請求量,即限流。

限流的目的是通過對併發訪問/請求進行限速,或對一個時間窗口內的請求進行限速來保護系統。一旦達到限制速率則可以拒絕服務、排隊或等待、降級。

一般開發高併發系統常見的限流有:限制總併發數、限制瞬時併發數、限制時間窗口內的平均速率、限制遠程接口的調用速率、限制MQ的消費速率,或根據網絡連接數、網絡流量、CPU或內存負載等來限流。

本文主要就分佈式限流方法,對Spring Cloud Gateway的限流原理進行分析。

分佈式限流最關鍵的是要將限流服務做成原子化,常見的限流算法有:令牌桶、漏桶等,Spring Cloud Gateway使用Redis+Lua技術實現高併發和高性能的限流方案。

令牌桶算法

令牌桶算法是一個存放固定容量令牌的桶,按照固定速率往桶裡添加令牌。令牌桶算法的描述如下:

假如用戶配置的平均速率為r,則每隔1/r秒一個令牌被加入到桶中;

假設桶最多可以存發b個令牌。如果令牌到達時令牌桶已經滿了,那麼這個令牌會被丟棄;

當一個n個字節大小的數據包到達,將從桶中刪除n個令牌,接著數據包被髮送到網絡上;

如果令牌桶中少於n個令牌,那麼不會刪除令牌,並且認為這個數據包在流量限制之外;

算法允許最長b個字節的突發,但從長期運行結果看,數據包的速率被限制成常量r。對於在流量限制外的數據包可以以不同的方式處理:

它們可以被丟棄;

它們可以排放在隊列中以便當令牌桶中累積了足夠多的令牌時再傳輸;

它們可以繼續發送,但需要做特殊標記,網絡過載的時候將這些特殊標記的包丟棄。

漏桶算法

漏桶作為計量工具(The Leaky Bucket Algorithm as a Meter)時,可以用於流量整形(Traffic Shaping)和流量控制(Traffic Policing),漏桶算法的描述如下:

一個固定容量的漏桶,按照常量固定速率流出水滴;

如果桶是空的,則不需流出水滴;

可以以任意速率流入水滴到漏桶;

如果流入水滴超出了桶的容量,則流入的水滴溢出了(被丟棄),而漏桶容量是不變的。

實踐

SpringCloudGateway限流方案

Spring Cloud Gateway 默認實現 Redis限流,如果擴展只需要實現Ratelimter接口即可,同時也可以通過自定義KeyResolver來指定限流的Key,比如我們需要根據用戶、IP、URI來做限流等等,通過exchange對象可以獲取到請求信息,比如:

用戶限流

@Bean

public KeyResolver ipKeyResolver() {

return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());

}

SpringCloudGateway默認提供的RedisRateLimter 的核心邏輯為判斷是否取到令牌的實現,通過調用 META-INF/scripts/request_rate_limiter.lua 腳本實現基於令牌桶算法限流


分享到:


相關文章: