javascript
【SpringCloud】Gateway新一代网关
提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- Gateway是什么
 - 三大核心
 - Gateway工作流程
 
- Gateway的使用
 - Gateway網關路由配置方式
 - 通過微服務名實現動態路由
 - Predicate(斷言)的使用
 - Filter的使用
 
Gateway是什么
Gateway是繼Zuul后的新一代網關,官網:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/
SpringCloud Gateway是Spring Cloud的一個全新項目,基于Spring 5.0+Spring Boot 2.0和Project Reactor等技術開發的網關,它旨在為微服務架構提供—種簡單有效的統一的API路由管理方式。
SpringCloud Gateway作為 Spring Cloud生態系統中的網關,目標是替代Zuul,在Spring Cloud 2.0以上版本中,沒有對新版本的Zuul 2.0以上最新高性能版本進行集成,仍然還是使用的Zuul 1.x非Reactor模式的老版本。而為了提升網關的性能SpringCloud Gateway是基于WebFlux框架實現的,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty。
Spring Cloud Gateway的目標提供統一的路由方式且基于Filter鏈的方式提供了網關基本的功能,例如:安全,監控/指標,和限流。
Cloud全家桶中有個很重要的組件就是網關,在1.x版本中都是采用的Zuul網關;但在2.x版本中,zuul的升級一直跳票,SpringCloud最后自己研發了一個網關替代Zuul,那就是SpringCloud Gateway一句話: gateway是原zuul1.x版的替代
小結
 (1)微服務架構中網關在哪里:網關是在微服務之前,擋著外部請求。
 (2)Spring Cloud Gateway 使用的Webflux中的reactor-netty響應式編程組件,底層使用了Netty通訊框架
 (3)WebFlux是:
 
(4)Spring Cloud Gateway 與Zuul的區別:
 在SpringCloud Finchley正式版之前,Spring Cloud推薦的網關是Netflix提供的Zuul:
- Zuul 1.x,是一個基于阻塞I/O的APl Gateway
 - Zuul 1.x基于Servlet 2.5使用阻塞架構它不支持任何長連接(如 WebSocket)Zuul的設計模式和Nginx較像,每次I/О操作都是從工作線程中選擇一個執行,請求線程被阻塞到工作線程完成,但是差別是Nginx用C++實現Zuul用Java實現,而JVM本身會有第—次加載較慢的情況,使得Zuul的性能相對較差。
 - Zuul 2.x理念更先進,想基于Netty非阻塞和支持長連接,但SpringCloud目前還沒有整合。Zuul 2.x的性能較Zuul 1.x有較大提升。在性能方面,根據官方提供的基準測試,Spring Cloud Gateway的RPS(每秒請求數)是Zuul的1.6倍。
 - Spring Cloud Gateway建立在Spring Framework 5、Project Reactor和Spring Boot 2之上,使用非阻塞API。
 - Spring Cloud Gateway還支持WebSocket,并且與Spring緊密集成擁有更好的開發體驗
(5)Spring Cloud Gateway具有如下特性: - 基于Spring Framework 5, Project Reactor和Spring Boot 2.0進行構建
 - 動態路由:能夠匹配任何請求屬性
 - 可以對路由指定 Predicate(斷言)和Filter (過濾器);集成Hystrix的斷路器功能
 - 集成Spring Cloud服務發現功能
 - 易于編寫的 Predicate (斷言)和Filter (過濾器)
 - 請求限流功能
 - 支持路徑重寫
 
三大核心
Route(路由)
路由是構建網關的基本模塊,它由ID,目標URI,一系列的斷言和過濾器組成,如果斷言為true則匹配該路由。
Predicate(斷言)
 參考的是java8的java.util.function.Predicate開發人員可以匹配HTTP請求中的所有內容(例如請求頭或請求參數),如果請求與斷言相匹配則進行路由。
Filter(過濾)
 指的是Spring框架中GatewayFilter的實例,使用過濾器,可以在請求被路由前或者之后對請求進行修改。
小結:
 
 web請求,通過一些匹配條件,定位到真正的服務節點。并在這個轉發過程的前后,進行一些精細化控制。
 predicate就是我們的匹配條件,而fiter,就可以理解為一個無斬不能的攔截器。有了這兩個元素,再加上目標uri,就可以實現一個具體的路由了。
Gateway工作流程
官網提供的流圖:
 The following diagram provides a high-level overview of how Spring Cloud Gateway works:
 
Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. This handler runs the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. All “pre” filter logic is executed. Then the proxy request is made. After the proxy request is made, the “post” filter logic is run.
大致可以這樣理解:
 客戶端向Spring Cloud Gateway發出請求。然后在Gateway Handler Mapping 中找到與請求相匹配的路由,將其發送到GatewayWeb Handler。
Handler再通過指定的過濾器鏈來將請求發送到我們實際的服務執行業務邏輯,然后返回。
 過濾器之間用虛線分開是因為過濾器可能會在發送代理請求之前(“pre”)或之后(“post")執行業務邏輯。
Filter在“pre”類型的過濾器可以做參數校驗、權限校驗、流量監控、日志輸出、協議轉換等,
 在“post”類型的過濾器中可以做響應內容、響應頭的修改,日志的輸出,流量監控等有著非常重要的作用。
核心邏輯:路由轉發+執行過濾器鏈
Gateway的使用
(1)訪問:http://localhost:8001/payment/1
(2)訪問:http://localhost:9527/payment/1
(3)有什么作用,我們可以暴露微服務的端口,通過網關配置路由,使用統一的9527端口
Gateway網關路由配置方式
有兩種,一種是前面通過配置文件配置application.yml配置,還有一種是下面的通過代碼中注入RouteLocator的Bean
官網使用案例:
例子:
 在9527配置GateWayConfig類:
解釋一下:http://localhost:9527/test來代替http://news.baidu.com/guonei
通過微服務名實現動態路由
之前我們是通過Ribbon(【SpringCloud】Ribbon負載均衡服務調用)來實現負載均衡的,輪流調用8001和8002,現在路由配置是寫死的
 我們的服務提供者不可能只有8001,那么怎樣不寫死了,就需要用到GateWay的動態路由。
只需要修改配置文件application.yml就可以實現,修改后完整的application.yml:
server:port: 9527 spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true #開啟從注冊中心動態創建路由的功能,利用微服務名進行路由routes:- id: payment_routh #路由的ID,沒有固定規則但要求唯一,建議配合服務名#uri: http://localhost:8001 #匹配后提供服務的路由地址uri: lb://cloud-provider-paymentpredicates:- Path=/payment/** #斷言,路徑相匹配的進行路由- id: payment_routh2#uri: http://localhost:8001 #匹配后提供服務的路由地址uri: lb://cloud-provider-paymentpredicates:- Path=/payment/lb/** #斷言,路徑相匹配的進行路由eureka:instance:hostname: cloud-gateway-serviceclient:service-url:register-with-eureka: truefetch-registry: truedefaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka添加了一個配置:開啟動態路由。
 修改了uri為lb://cloud-payment-service:uri的協議為lb,表示啟用Gateway的負載均衡功能,后面是微服務提供者的名稱。
測試:訪問http://localhost:9527/payment/lb,我們可以看到8001和8002兩個端口輪流調用。
Predicate(斷言)的使用
開啟9527Gateway服務時,控制臺:
 這些都是我們Predicate可以配置的,我們配置文件僅僅配置了Path
我們可以在官網中,找到是如何使用的:
舉例使用:
大致意思:匹配在指定日期時間之后才能請求
 使用:
怎樣獲得當前的時間
public class T2 {public static void main(String[] args) {ZonedDateTime zonedDateTime = ZonedDateTime.now();System.out.println(zonedDateTime);} }輸出:2021-01-30T00:26:35.219+08:00[Asia/Shanghai]
我們可以根據這個來修改上面的After
Cookie Route Predicate需要兩個參數,一個是Cookie name ,一個是正則表達式。
 路由規則會通過獲取對應的Cookie name值和正則表達式去匹配,如果匹配上就會執行路由,如果沒有匹配上則不執行
配置如下:
spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, ch.p小結:
 Predicate就是為了實現一組匹配規則,讓請求過來找到對應的Route進行處理。
Filter的使用
路由過濾器可用于修改進入的HTTP請求和返回的HTTP響應,路由過濾器只能指定路由進行使用。
 Spring Cloud Gateway內置了多種路由過濾器,他們都由GatewayFilter的工廠類來產生。官網:
 
可以直接在配置文件中配置即可:
spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgfilters:- AddRequestHeader=X-Request-red, blue除了官方給的,主要是自定義過濾器:
 下面以自定義全局GlobalFilter為例:
新建一個類MyLogGateWayFilter,加注解@Component和實現impiemerts GlobalFilter ,Ordered
@Component @Slf4j public class MyLogGateWayFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("*********come in MyLogGateWayFilter: "+new Date());String username = exchange.getRequest().getQueryParams().getFirst("username");if(StringUtils.isEmpty(username)){log.info("*****用戶名為Null 非法用戶,(┬_┬)");exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);//給人家一個回應return exchange.getResponse().setComplete();}return chain.filter(exchange);//交給下一個過濾器鏈}@Overridepublic int getOrder() {return 0;} }重啟服務即可,上面達到一個什么效果:訪問每一個網頁都需要帶上username=XXXX,不然訪問不了。
 例如:http://localhost:9527/payment/lb?username=z3
總結
以上是生活随笔為你收集整理的【SpringCloud】Gateway新一代网关的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Mac -- 启动ssh服务
 - 下一篇: AspectJ 使用介绍