如果您(或正在考慮)使用微服務,那么您應該熟悉,或者至少要碰到API gateway pattern
。Chris Richardson在microservices.io上詳細描述了這種模式。API網關充當系統的單一入口點,允許集中許多交叉問題,例如:路由機制,緩存管理,安全性,監控/指標和彈性。
在本文中,我們將探索Spring雲套件中的一個新項目:Spring Cloud Gateway項目,構建於Spring 5,Spring Boot 2和Project Reactor之上。
Spring Cloud網關
當談到選擇為您的微服務的API網關,也有多種選擇:Zuul來自Netflix,香港,Nginx的,HAProxy的,Traefik,雲供應商的解決方案,如亞馬遜的API網關或谷歌雲端點和(新的)春雲來自Pivotal的門戶。
Spring Cloud Gateway旨在提供一種簡單而有效的路由到API的方法。當它收到請求時,Spring Cloud Gateway會將其轉發到網關處理程序映射,該映射確定應該對匹配特定路由的請求執行的操作。
我寧願建立一個基於微服務的小型項目,而不是采用傳統方法並列出所有功能,而是展示和描述它的用法
入門
在[github]上公開提供的極簡主義項目(https://github.com/aboullaite/spring-cloud-gateway)由2個服務(BookStore和MovieStore),一個網關(顯然基於Spring雲網關)組成,服務發現(Eureka服務器)和Hystrix儀表板。該項目還需要運行和監聽redis實例,以利用Spring Cloud Gateway的request.rate限制功能,
路由
Spring Cloud Gateway支持兩種形式的創建路由:純java(使用RouteLocator
)或配置文件。我們的項目使用第二種方法!
讓我們來看看從一個片段application.yml
從gateway
模塊:
spring: cloud: gateway: routes: - id: movie-store uri: lb://movie-store predicates: - Path=/api/movies/** filters: - name: RequestRateLimiter args: key-resolver: '#{@userKeyResolver}' redis-rate-limiter.replenishRate: 2 redis-rate-limiter.burstCapacity: 2 - RewritePath=/api/(?<movies>.*), /$\{movies} - AddResponseHeader=X-Some-Header, aboullaite.me
此配置告訴Spring Cloud Gateway將對網關發出的所有請求路由/api/movies/
到movie-store
服務。請注意謂詞和過濾器的使用,因此我們可以根據特定條件路由句柄,並根據需要更改請求/響應。
值得一提的是,Spring Cloud Gateway有3個主要構建塊:
- 路由:網關的主要API。它由ID,目標URI,謂詞集合和過濾器集合定義。如果聚合謂詞為真,則匹配路由。
- 謂詞:Java 8函數謂詞。它可以匹配HTTP請求中的任何內容,例如標頭或參數。
- 過濾器:標准Spring框架
WebFilter
,可在發送下游請求之前或之后修改請求和響應。
您可能已經注意到,在上面的代碼片段中我們使用了3 filters
:
AddResponseHeader
過濾以添加X-Some-Header
包含aboullaite.me
響應中的值的標頭。RewritePath
過濾重寫從請求路徑/api/movies/**
到/movies/**
RequestRateLimiter
實施請求率限制器。
要閱讀有關路由過濾器的更多信息,請參閱此鏈接。
限速
速率限制主要用於控制網絡上發送或接收的流量速率。它有助於防止服務質量下降甚至由於高流量導致的中斷,並提高API的可靠性。存在不同類型的速率限制,每種速率限制用於針對特定需求。
與zuul
沒有集成開箱即用的速率限制解決方案不同,Spring Cloud Gateway附帶了一個RequestRateLimiter
過濾器,用於確定是否允許當前請求繼續進行。目前唯一支持的實現是redis
,需要使用spring-boot-starter-data-redis-reactive
Spring Boot啟動器。
該RequestRateLimiter
有一個可選的keyResolver
參數和參數具體到速率限制器。請注意,key-resolver
引用帶有名稱的bean的SpEL表達式userKeyResolver
。此bean實現了KeyResolver
有助於派生限制請求的密鑰的接口:
@Bean KeyResolver userKeyResolver() { return exchange -> Mono.just("fero"); }
我們還宣布了另外兩個參數:
replenishRate
:表示允許用戶每秒執行的請求數。burstCapacity
:定義用戶在一秒鍾內允許執行的最大請求數。
此外,此過濾器還添加了額外的標頭,指示客戶端的速率限制以及使用速度有多快:
X-RateLimit-Replenish-Rate
表示該replenishRate
值。X-RateLimit-Burst-Capacity
表示該burstCapacity
值。X-RateLimit-Remaining
表示您剩余的通話次數。
當請求提交超過補充率和突發限制時,網關會超出超出限制的請求並向429 Too Many Requests
客戶端返回錯誤響應。
使用Hystrix
斷路器是一種有趣的模式,可以提高您的API可靠性並防止網絡或服務故障級聯到其他服務和客戶端。Spring Cloud Gateway附帶Hystrix支持,這是一個實現斷路器模式的Netflix庫。
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 2000 spring: cloud: gateway: routes: - id: book-store uri: lb://book-store predicates: - Path=/api/books/** filters: - name: RequestRateLimiter args: key-resolver: '#{@userKeyResolver}' redis-rate-limiter.replenishRate: 2 redis-rate-limiter.burstCapacity: 2 - RewritePath=/api/(?<books>.*), /$\{books} - name: Hystrix args: name: booksFallbackCommand fallbackUri: forward:/fallback/books
該/books/danger
IN端點books-store
模塊模擬性能差,需要一個很長的時間來發送它的響應的端點。我們還包裹,使用在該API的路線HystrixCommand
:booksFallbackCommand
。現在當Hystrix包裹的路由超時(即花費超過2秒)時,它將/fallback/books
在Gateway應用程序中調用端點,該應用程序只返回一個空列表:
@RestController @RequestMapping("/fallback") public class FallbackController { @GetMapping("/books") public ResponseEntity<List> booksFallback(){ return ResponseEntity.ok(Arrays.asList()); } }
請注意,此示例還通過lb
目標URI 上的前綴演示了Spring Cloud Netflix功能區負載平衡。
就是這篇文章!我們探討了Spring Cloud Gateway中的一些功能和組件,主要是速率限制和斷路器功能!我用過的項目可以在github上找到。