spring Cloud網關之Spring Cloud Gateway
Spring Cloud Gateway是什麼?(官網地址://cloud.spring.io/spring-cloud-gateway/reference/html/)
Spring Cloud Gateway是建立在Spring 5, Spring Boot 2 and Project Reactor這幾個項目上的API網關,它是由spring團隊自己開發的,spring的親兒子。Spring Cloud Gateway旨在提供一種簡單而有效的方法來路由到api,並為它們提供跨領域的關注點,例如:安全性、監控/度量和彈性。
cloud全家桶在1.x版本中推薦用的網關是zuul,但是在2.x版本中,Zuul的升級一直跳票,spring團隊最後自己研發了一個網關代替Zuul,就是Spring Cloud Gateway。Spring Cloud Gateway是基於WebFlux框架實現的,而WebFlux框架底層則是使用了高性能的Reactor模式通訊框架Netty。
Spring Cloud Gateway有什麼用?
- 性能:API高可用,負載均衡,容錯機制。
- 安全:許可權身份認證、脫敏,流量清洗,後端簽名(保證全鏈路可信調用),黑名單(非法調用的限制)。
- 日誌:日誌記錄(spainid,traceid)一旦涉及分散式,全鏈路跟蹤必不可少。
- 快取:數據快取。
- 監控:記錄請求響應數據,api耗時分析,性能監控。
- 限流:流量控制,錯峰流控,可以定義多種限流規則。
- 灰度:線上灰度部署,可以減小風險。
- 路由:動態路由規則。
Spring Cloud Gateway的特性:
1、動態路由:能夠匹配任何請求屬性。
2、可以對路由指定Predicate(斷言)和Filter(過濾),斷言和過濾易於編寫。
3、集成Hystrix斷路器功能、Eureka服務發現功能。
4、請求限流功能,支援路徑重寫。
在Spring Cloud Finchley正式版之前推薦使用的網關是Netflex提供的Zuul,在此之後推薦使用的是Spring Cloud Gateway。
Spring Cloud Gateway和Zuul的區別:
1、Zuul 1.x是一個基於阻塞I/O的API網關。
2、Zuul 1.x是基於Servlet 2.5使用阻塞架構的,它不支援任何長連接(如WebSocket),Zuul的設計模式和Nginx較像,每次I/O操作都是從工作執行緒中選擇一個執行,請求執行緒阻塞到工作執行緒完成,但是差別是Nginx是用C++實現的,Zuul是用Java實現的,而JVM本身會有第一次載入比較慢的情況,使得Zuul性能會相對較差。
3、Zuul 2.x理念是基於Netty非阻塞和支援長連接,性能方面比Zuul 1.x有很大的提升,但是因為Netflex跳票,還沒有發布 。根據官方提供的基準測試,Spring Cloud Gateway的RPS(每秒請求數)是Zuul的1.6倍。
4、Spring Cloud Gateway是建立在Spring 5, Spring Boot 2 and Project Reactor之上,Spring Cloud Gateway是基於WebFlux框架實現的,而WebFlux框架底層則是使用了高性能的Reactor模式通訊框架Netty,是一個非阻塞I/O的API網關。
5、Spring Cloud Gateway還支援WebSocket,並且與Spring緊密集成擁有更好的開發體驗。
Spring Cloud Gateway三大核心概念:
1、Route(路由):路由是構建網關的基本模組,它是由ID、目標URI,一系列的斷言和過濾器組成,如果斷言為true則匹配該路由。
2、Predicate(斷言):參考的是Java8中的java.util.function.Predicate,開發人員匹配HTTP請求中的內容進行斷言,如果請求與斷言匹配則路由。
3、Filter(過濾):指的是Spring框架中GatewayFilter的實例,使用過濾器可以在請求被路由前或者之後對請求進行修改。
Spring Cloud Gateway工作流程如下官網提供的圖片:
1、客戶端向Spring Cloud Gateway發送請求,然後在Gateway Hangdler Mapping中找到與請求相匹配的路由,將其發送到Gateway Web Handler。
2、Handler再通過指定的過濾器鏈來將請求發送到我們實際的服務執行業務邏輯,然後返回。
3、過濾器之間用虛線分開是因為過濾器可能會在發送代理請求之前(「pre」)或者之後(「post」)執行業務邏輯。
4、Filter在「pre」類型的過濾器可以做參數校驗、許可權校驗、流量監控、日誌輸出、協議轉換等。在「post」類型的過濾器中可以做響應內容、響應頭的修改,日誌的輸出,流量監控等。
5、核心邏輯就是路由轉發和執行過濾器鏈。
Spring Cloud Gateway實踐
1、gateway在pom.xml加以下依賴包:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>2.2.4.BUILD-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
2、gateway配置文件如下進行配置:
server: port: 8080 tomcat: uri-encoding: UTF-8 basedir: /tmp/tomcat connection-timeout: 60000 spring: application: name: demo-gateway cloud: gateway: discovery: locator: #開啟從註冊中心動態創建路由的功能,利用微服務名進行路由 enabled: true routes: - id: demo-client #uri: http://localhost:8101 uri: lb://demo-client predicates: - Path=/consumer/consumer/** #路由的id,沒有固定規則,建議配合服務名使用 - id: demo-user #提供服務的路由地址 #uri: //localhost:8100 uri: lb://demo-user #斷言,路徑相匹配就進行路由 predicates: - Path=/user/user/** eureka: instance: hostname: gateway-service client: service-url: register-with-eureka: true fetch-registry: true defaultZone: //localhost:8761/eureka/
3、在GatewayApplication加上註解@EnableDiscoveryClient
4、訪問//localhost:8080/user/user/test?msg=1235
Spring Cloud Gateway服務網關github地址://github.com/yuanzipeng/spring-cloud-gateway