亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                SpringCloud系列-10Spring Cloud Gateway網(wǎng)關(guān)

                SpringCloud系列-10Spring Cloud Gateway網(wǎng)關(guān)

                學(xué)習(xí)目標(biāo)

              1. Gateway是什么?它有什么作用?
              2. Gateway中的斷言使用
              3. Gateway中的過濾器使用
              4. Gateway中的路由使用
              5. 第1章 網(wǎng)關(guān)

                1.1 網(wǎng)關(guān)的概念

                簡單來說,網(wǎng)關(guān)就是一個網(wǎng)絡(luò)連接到另外一個網(wǎng)絡(luò)的“關(guān)口”。如下圖所示,當(dāng)我們所在的本地網(wǎng)絡(luò)(局域網(wǎng))要訪問外部網(wǎng)絡(luò)的數(shù)據(jù)時,需要通過路由器進(jìn)行轉(zhuǎn)發(fā),而這里的路由器就充當(dāng)了網(wǎng)關(guān)的角色。

                1.2 網(wǎng)關(guān)的作用

                網(wǎng)關(guān)的作用,是可以實(shí)現(xiàn)不同網(wǎng)絡(luò)之間的互聯(lián),同時,還可以使得在不同的通信協(xié)議、數(shù)據(jù)格式等系統(tǒng)之間實(shí)現(xiàn)轉(zhuǎn)發(fā)。

                我們今天要講解的Gateway,它也是網(wǎng)關(guān)的一種,我們稱為應(yīng)用網(wǎng)關(guān),也稱為API網(wǎng)關(guān)。為什么需要API網(wǎng)關(guān)呢? 還得從架構(gòu)演變過程來說明:

                前面我們說過,在微服務(wù)架構(gòu)中,每個微服務(wù)都是一個獨(dú)立運(yùn)行的組件,這些組件通過Rest API風(fēng)格的接口給到H5、Android、IOS等客戶端程序調(diào)用。(移動互聯(lián)時代,為了盡快迭代)。而在一個UI界面中,通常會展示很多數(shù)據(jù),這些數(shù)據(jù)可能來自不同的微服務(wù),比如在一個電商系統(tǒng)中,執(zhí)行一個下單請求,必然需要

              6. 從營銷服務(wù)中查詢促銷信息
              7. 從會員服務(wù)中查詢會員等級和會員積分等
              8. 從商品服務(wù)查詢商品詳情
              9. 調(diào)用訂單服務(wù)進(jìn)行下單。
              10. 1.3 出現(xiàn)的背景

                那么早期的微服務(wù)架構(gòu),面對這樣的情況的處理方式,出現(xiàn)了如下圖所示的調(diào)用方式。

                在這種調(diào)用方式中,不難發(fā)現(xiàn)問題會比較多:

              11. 客戶端和內(nèi)部微服務(wù)的耦合度較高,任何一邊發(fā)生變化,都會對另外一邊造成影響
              12. 客戶端需要維護(hù)內(nèi)部微服務(wù)的地址等信息,如果微服務(wù)地址發(fā)生變化也會影響客戶端的通信
              13. 客戶端需要調(diào)用多次接口請求,造成服務(wù)端請求過多
              14. 這種方式存在較多的問題,所以一般我們會在客戶端與微服務(wù)之間引入BFF層(即 Backend For Frontend(服務(wù)于前端的后端)),也就是服務(wù)器設(shè)計API時會考慮前端的使用,并在服務(wù)端直接進(jìn)行業(yè)務(wù)邏輯的處理,又稱為用戶體驗(yàn)適配器。

                如下圖所示,BFF層為客戶端提供了統(tǒng)一的聚合服務(wù),我們可以在BFF層為不同的端或者不同的業(yè)務(wù)提供更加友好和統(tǒng)一的客戶端。

                引入BFF層的好處是

              15. 客戶端和內(nèi)部微服務(wù)之間不存在之間耦合,使得兩端的變化可以獨(dú)立
              16. 當(dāng)APP端有新的需求時,可以通過BFF層進(jìn)行評比,減少后端團(tuán)隊的溝通成本,如果后端微服務(wù)設(shè)計得足夠好的話,很多的需求在BFF層就可以搞定。
              17. 但是這種方式仍然存在問題,客戶端發(fā)起請求進(jìn)入到BFF層時,需要考慮到安全問題,需要做鑒權(quán)、限流等,而這些功能需要在每一個BFF模塊中都需要編寫,增加了很多的重復(fù)代碼,而且維護(hù)起來非常不靈活導(dǎo)致開發(fā)效率下降。

                所以,引入了API網(wǎng)關(guān),整體結(jié)構(gòu)如下圖所示

                網(wǎng)關(guān)是微服務(wù)架構(gòu)不可或缺的一部分,作為微服務(wù)架構(gòu)的唯一入口,將所有請求轉(zhuǎn)發(fā)到后端對應(yīng)的微服務(wù)上去,同時又可以將各個微服務(wù)中的通用功能集中到網(wǎng)關(guān)去做,而不是在每個微服務(wù)都實(shí)現(xiàn)一遍,

              18. 身份驗(yàn)證和授權(quán)
              19. 限流
              20. 版本控制
              21. 緩存
              22. 統(tǒng)一日志
              23. 同時,增加網(wǎng)關(guān)后,把各個BFF模塊的橫切功能剝離到網(wǎng)關(guān)中,BFF模塊開發(fā)人員只需要關(guān)注在業(yè)務(wù)邏輯的交付上。

                常見的開源網(wǎng)關(guān)

              24. OpenResty(Nginx+lua)
              25. Zuul,是spring cloud生態(tài)下提供的一個網(wǎng)關(guān)服務(wù),性能相對來說不是很高
              26. Spring Cloud Gateway,是Spring團(tuán)隊開發(fā)的高性能網(wǎng)關(guān)
              27. 1.4 Gateway簡介

                Spring Cloud Gateway 是 Spring 官方團(tuán)隊研發(fā)的 API 網(wǎng)關(guān)技術(shù),它的目的是取代 Zuul 為微服務(wù)提供一種簡單高效的 API 網(wǎng)關(guān)。一般來說,Spring 團(tuán)隊不會重復(fù)造輪子,為什么又研發(fā)出一個 Spring Cloud Gateway 呢?有幾方面原因。

                • Zuul1.x 采用的是傳統(tǒng)的 thread per connection 方式來處理請求,也就是針對每一個請求,會為這個請求專門分配一個線程來進(jìn)行處理,直到這個請求完成之后才會釋放線程,一旦后臺服務(wù)器響應(yīng)較慢,就會使得該線程被阻塞,所以它的性能不是很好。
                • Zuul 本身存在的一些性能問題不適合于高并發(fā)的場景,雖然后來 Netflix 決定開發(fā)高性能版 Zuul 2.x,但是 Zuul 2.x 的發(fā)布時間一直不確定。雖然 Zuul 2.x 后來已經(jīng)發(fā)布并且開源了,但是 Spring Cloud 并沒有打算集成進(jìn)來。Spring Cloud Gateway 是依賴于 Spring Boot 2.0、Spring WebFlux 和 Project Reactor 等技術(shù)開發(fā)的網(wǎng)關(guān),它不僅提供了統(tǒng)一的路由請求的方式,還基于過濾鏈的方式提供了網(wǎng)關(guān)最基本的功能。

                1.5 Gateway基本概念

                Spring Cloud Gateway的基本工作原理如下圖所示。

                客戶端向Spring Cloud Gateway發(fā)出請求。然后在Gateway Handler Mapping中找到與請求相匹配的路由,將其發(fā)送到Gateway Web Handler。Handler 再通過指定的過濾器鏈來將請求發(fā)送到我們實(shí)際的服務(wù)執(zhí)行業(yè)務(wù)邏輯,然后返回。

                過濾器之間用虛線分開是因?yàn)檫^濾器可能會在發(fā)送代理請求之前(“pre”)或之后(“post”)執(zhí)行業(yè)務(wù)邏輯。

                • Filter在“pre”類型的過濾器可以做參數(shù)校驗(yàn)、權(quán)限校驗(yàn)、流量監(jiān)控、日志輸出、協(xié)議轉(zhuǎn)換等,
                • 在“post”類型的過濾器中可以做響應(yīng)內(nèi)容、響應(yīng)頭的修改,日志的輸出,流量監(jiān)控等有著非常重要的作用。

                在Spring Cloud Gateway中有三個重要的對象,分別是:

                • Route路由,它是網(wǎng)關(guān)的基礎(chǔ)元素,包含ID、目標(biāo)URI、斷言、過濾器組成,當(dāng)前請求到達(dá)網(wǎng)關(guān)時,會通過Gateway Handler Mapping,基于斷言進(jìn)行路由匹配,當(dāng)斷言為true時,匹配到路由進(jìn)行轉(zhuǎn)發(fā)
                • Predicate斷言,學(xué)過java8的同學(xué)應(yīng)該知道這個函數(shù),它可以允許開發(fā)人員去匹配HTTP請求中的元素,一旦匹配為true,則表示匹配到合適的路由進(jìn)行轉(zhuǎn)發(fā)
                • Filter過濾器,可以在請求發(fā)出的前后進(jìn)行一些業(yè)務(wù)上的處理,比如授權(quán)、埋點(diǎn)、限流等。

                具體的工作原理如下圖所示:

                它的整體工作原理如下。

                其中,predicate就是我們的匹配條件;而filter,就可以理解為一個無所不能的攔截器。有了這兩個元素,再加上目標(biāo)uri,就可以實(shí)現(xiàn)一個具體的路由了。

                客戶端向 Spring Cloud Gateway 發(fā)出請求,如果請求與網(wǎng)關(guān)程序定義的路由匹配,則該請求就會被發(fā)送到網(wǎng)關(guān) Web 處理程序,此時處理程序運(yùn)行特定的請求過濾器鏈。

                過濾器之間用虛線分開的原因是過濾器可能會在發(fā)送代理請求的前后執(zhí)行邏輯。所有 pre 過濾器邏輯先執(zhí)行,然后執(zhí)行代理請求;代理請求完成后,執(zhí)行 post 過濾器邏輯。

                第2章 Predicate應(yīng)用

                下面我們通過一些案例演示來初步了解Spring Cloug Gateway.

                1.在上文的基礎(chǔ)之上,整個項(xiàng)目拷貝過來,并改名為gateway-**

                2.在上面的框架基礎(chǔ)之上,修改user項(xiàng)目中的HelloController和UserController

                @RestControllerpublic class HelloController { @Autowired OrderServiceClient orderServiceClient; @Value(“${server.port}”) private int port; @GetMapping(“/hello/{name}”) public String get(@PathVariable(“name”) String name){ String result = “”; //同步 result = new HelloCommand(name,orderServiceClient).execute(); return “當(dāng)前user端口為:”+port+”,結(jié)果為:”+result; }}@RestControllerpublic class UserController { @Autowired OrderServiceClient orderServiceClient; @Value(“${server.port}”) private int port; @HystrixCommand(commandProperties = { @HystrixProperty(name=”circuitBreaker.requestVolumeThreshold”,value = “10”), @HystrixProperty(name=”circuitBreaker.sleepWindowInMilliseconds”,value=”5000″), @HystrixProperty(name=”circuitBreaker.errorThresholdPercentage”,value=”50″), },fallbackMethod = “fallback”) @GetMapping(“/get/{num}”) public String get(@PathVariable(“num”) int num){ if(num%2==0){ return “當(dāng)前user端口為:”+port+”,結(jié)果為:正常訪問”; } return “當(dāng)前user端口為:”+port+”,結(jié)果為:”+orderServiceClient.orderLists(num); } public String fallback(int num){ return “觸發(fā)降級”; }}

                并分別開啟兩個user項(xiàng)目,端口為8080和8081;開啟兩個order項(xiàng)目,端口分別為8088和8099

                3.創(chuàng)建新的springboot項(xiàng)目gateway-common

                4.配置pom

                4.0.0 eclipse2019-demo com.example 1.0-SNAPSHOT com.example gateway-common 0.0.1-SNAPSHOT gateway-common Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-starter-gateway org.springframework.cloud spring-cloud-starter-netflix-eureka-client

                5.配置yml,如果用的是nacos,一般這些配置可以寫在nacos里面

                server: port: 9527 spring: application: name: gateway cloud: gateway: routes: # 路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名 – id: getUser # 匹配后提供服務(wù)的路由地址 uri: http://localhost:8080 # 斷言,路徑相匹配的進(jìn)行路由 predicates: – Path=/get/** – id: sayHello uri: http://localhost:8081 predicates: – Path=/hello/** – id: heihei uri: https://www.baidu.com/ predicates: – Path=/heihei/** filters: – StripPrefix=1 #去掉地址中的第一部分 – StripPrefix=2 #去掉地址中的第二部分eureka: instance: hostname: gateway-9527 client: service-url: register-with-eureka: true fetch-registry: true defaultZone: http://127.0.0.1:8761/eureka

                6.啟動類

                @SpringBootApplication@EnableDiscoveryClientpublic class GatewayCommonApplication { public static void main(String[] args) { SpringApplication.run(GatewayCommonApplication.class, args); } }

                7.測試

                2.1 Predicate規(guī)則

                上述案例中,我們使用了Gateway中的 Path匹配規(guī)則,也就是根據(jù)請求的uri地址,使用前綴匹配規(guī)則完成請求地址的匹配。

                Gateway內(nèi)置了是多種Predicate匹配規(guī)則,具體如下圖所示

                2.1.1 Query斷言

                Query 路由斷言工廠接收兩個參數(shù),一個必需的參數(shù)和一個可選的正則表達(dá)式。

                spring: cloud: gateway: routes: – id: query_route uri: https://www.baidu.com/ predicates: – Query=name, eclipse2019.*shuai

                如果請求包含一個name的參數(shù),值是eclipse2019開頭,shuaiqi結(jié)尾,則此路由將匹配。第二個參數(shù)是正則表達(dá)式。

                測試鏈接:http://localhost:9527/?name=feichangshuaiqieclipse2019

                2.1.2 Method斷言

                Method 路由斷言工廠接收一個參數(shù),即要匹配的 HTTP 方法。

                spring: cloud: gateway: routes: – id: method_route uri: https://www.douyu.com/ predicates: – Method=GET

                2.1.3 Header斷言

                Header 路由斷言工廠接收兩個參數(shù),分別是請求頭名稱和正則表達(dá)式。

                spring: cloud: gateway: routes: – id: header_route uri: https://www.douyin.com/ predicates: – Header=X-Request-Id, d+

                如果請求中帶有請求頭名為 X-Request-Id,其值與 d+ 正則表達(dá)式匹配(值為一個或多個數(shù)字),則此路由匹配。

                2.1.4 Cookie斷言

                spring: cloud: gateway: routes: – id: cookie_route uri: https://www.huya.com/ predicates: – Cookie=name,eclipse2019

                通過postman,訪問http://localhost:9527 ; 并且在請求中攜帶cookie name=eclipse2019。 即可匹配到路由進(jìn)行轉(zhuǎn)發(fā)。

                2.2 自定義Predicate

                除了使用到官方提供的斷言工廠之外,如果我們有個性化的需求,也是可以實(shí)現(xiàn)自定義斷言工廠的。自定義路由斷言工廠需要繼承 AbstractRoutePredicateFactory 類,重寫 apply 方法的邏輯。在 apply 方法中可以通過 exchange.getRequest() 拿到 ServerHttpRequest 對象,從而可以獲取到請求的參數(shù)、請求方式、請求頭等信息。

                apply 方法的參數(shù)是自定義的配置類,在使用的時候配置參數(shù),在 apply 方法中直接獲取使用。

                命名需要以 RoutePredicateFactory 結(jié)尾,比如 AuthRoutePredicateFactory,那么在使用的時候Auth 就是這個路由斷言工廠的名稱。代碼如下所示。

                1.自定義AuthRoutePredicateFactory

                @Componentpublic class AuthRoutePredicateFactory extends AbstractRoutePredicateFactory{ Logger logger= LoggerFactory.getLogger(AuthRoutePredicateFactory.class); public static final String NAME_KEY = “name”; public AuthRoutePredicateFactory() { super(Config.class); } @Override public List shortcutFieldOrder() { return Arrays.asList(NAME_KEY); } @Override public Predicate apply(Config config) { logger.info(“AuthRoutePredicateFactory Start”); //只要請求的header中包含yml配置的Authorization,就允許匹配路由 return exchange -> { HttpHeaders headers=exchange.getRequest().getHeaders(); List header=headers.get(config.getName()); return header.size()>0; }; } public static class Config{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }}

                2.在配置文件中添加如下配置信息

                – id: define_route uri: https://www.baidu.com predicates: – Path=/define/** – Auth=Authorization filters: – StripPrefix=1

                3.訪問測試

              28. postman中訪問url:http://localhost:9527/define/1測試: 在header中添加Authorization 以及不添加 Authorization的效果。
              29. 第3章 Filter應(yīng)用

                filter是網(wǎng)關(guān)中的核心,它起到了請求過濾的作用。在gateway中,會對請求做pre和post的過濾,pre表示請求進(jìn)來之前,post表示請求處理完成之后返回給客戶端之前。

                • pred類型的過濾器可以做授權(quán)認(rèn)證、流量監(jiān)控、協(xié)議轉(zhuǎn)化等工作
                • post過濾器可以做響應(yīng)內(nèi)容的修改、日志的輸出等。

                下圖表示的是請求和響應(yīng),經(jīng)過filter的處理流程。

                3.1 Filter分類

                在Spring Cloud Gateway中,F(xiàn)ilter按照作用范圍可以分為兩類

                全局過濾器,針對所有的請求都會被攔截

                局部過濾器,只針對某一個指定的route有效

                我們先來了解一下局部過濾器,在前面講Predicate的時候,其實(shí)已經(jīng)涉及到了Filter的使用。

                在Spring Cloud Gateway中,內(nèi)置了非常多的過濾器,如下圖所示

                3.2 常用Filter

                3.2.1 AddRequestParameter

                針對所有匹配的請求,添加一個查詢參數(shù)。

                下面這段配置,會針對所有請求增加一個tn=baiduimage&word=%E7%BE%8E%E5%A5%B3的參數(shù)

                spring: cloud: gateway: routes: – id: add_request_parameter_route uri: https://image.baidu.com/ predicates: – Path=/search/index/** filters: – AddRequestParameter=tn,baiduimage – AddRequestParameter=word,%E7%BE%8E%E5%A5%B3

                3.2.2 RequestRateLimiter

                該過濾器會對訪問到當(dāng)前網(wǎng)關(guān)的所有請求執(zhí)行限流過濾,如果被限流,默認(rèn)情況下會響應(yīng)HTTP 429-Too Many Requests。RequestRateLimiterGatewayFilterFactory 默認(rèn)提供了 RedisRateLimiter 的限流實(shí)現(xiàn),它采用令牌桶算法來實(shí)現(xiàn)限流功能

                spring: cloud: gateway: routes: – id: request_ratelimiter_route uri: https://www.taobao.com/ predicates: – Path=/tb/** filters: – StripPrefix=1 – name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 2 redis-rate-limiter.burstCapacity: 5 key-resolver: “#{@userkeyResolver}” #這個必須要配置,否則返回403

                redis-rate-limiter 過濾器有兩個配置屬性,如果大家了解令牌桶,就很容易知道它們的含義。

                • replenishRate:令牌桶中令牌的填充速度,代表允許每秒執(zhí)行的請求數(shù)。
                • burstCapacity:令牌桶的容量,也就是令牌桶最多能夠容納的令牌數(shù)。表示每秒用戶最大能夠執(zhí)行的請求數(shù)量。
                • key-resolver:關(guān)鍵字標(biāo)識的限流

                使用redis限流的話還要做一些事:

                1.pom中引包

                org.springframework.boot spring-boot-starter-data-redis-reactive

                2.設(shè)置redis的地址

                spring: redis: database: 1 password: eclipse2019 host: localhost

                3.在啟動類或者配置類中加如下代碼

                @BeanKeyResolver userkeyResolver(){ //根據(jù)請求的ip進(jìn)行限流 return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());}

                3.2.3 Retry

                Retry GatewayFilter Factory 為請求重試過濾器,當(dāng)后端服務(wù)不可用時,網(wǎng)關(guān)會根據(jù)配置參數(shù)來發(fā)起重試請求

                spring: cloud: gateway: routes: – id: retry_route uri: http://www.example.com predicates: – Path=/example/** filters: – name: Retry args: retries: 3 status: 503 – StripPrefix=1

                RetryGatewayFilter 提供 4 個參數(shù)來控制重試請求,參數(shù)說明如下。

                • retries:請求重試次數(shù),默認(rèn)值是 3。
                • status:HTTP 請求返回的狀態(tài)碼,針對指定狀態(tài)碼進(jìn)行重試,比如,在上述配置中,當(dāng)服務(wù)端返回的狀態(tài)碼是 503 時,才會發(fā)起重試,此處可以配置多個狀態(tài)碼。
                • methods:指定 HTTP 請求中哪些方法類型需要進(jìn)行重試,默認(rèn)是 GET。
                • series:配置錯誤碼段,表示符合某段狀態(tài)碼才發(fā)起重試,默認(rèn)值是 SERVER_ERROR(5),表示 5xx 段的狀態(tài)碼都會發(fā)起重試。如果 series 配置了錯誤碼段,但是 status 沒有配置,則仍然會匹配 series 進(jìn)行重試。

                3.2.4 全局過濾器

                全局過濾器和GatewayFilter的作用是相同的,只是GlobalFilter針對所有的路由配置生效。Spring Cloud Gateway默認(rèn)內(nèi)置了一些全局過濾器

                • GatewayMetricsFilter,提供監(jiān)控指標(biāo)。
                • ReactiveLoadBalancerClientFilter,整合 Ribbon 針對下游服務(wù)實(shí)現(xiàn)負(fù)載均衡。
                • ForwardRoutingFilter,用于本地 forward,請求不轉(zhuǎn)發(fā)到下游服務(wù)器。
                • NettyRoutingFilter,使用 Netty 的 HttpClient 轉(zhuǎn)發(fā) HTTP、HTTPS 請求
                • ….

                全局過濾鏈的執(zhí)行順序是,當(dāng) Gateway 接收到請求時,F(xiàn)iltering Web Handler 處理器會將所有的 GlobalFilter 實(shí)例及所有路由上所配置的 GatewayFilter 實(shí)例添加到一條過濾器鏈中。該過濾器鏈里的所有過濾器都會按照@Order 注解所指定的數(shù)字大小進(jìn)行排序。

                3.2.5 自定義過濾器

                雖然Spring Cloud Gateway提供了非常多的過濾器,但是在實(shí)際應(yīng)用中,我們必然會涉及到和業(yè)務(wù)有關(guān)的過濾器,比如日志記錄、鑒權(quán)、黑白名單等。Spring Cloud Gateway 提供了過濾器的擴(kuò)展功能,開發(fā)者可以根據(jù)實(shí)際業(yè)務(wù)需求來自定義過濾器,這樣我們就可以在網(wǎng)關(guān)層實(shí)現(xiàn)時鑒權(quán)、日志管理、協(xié)議轉(zhuǎn)化等功能。同樣,自定義過濾器也支持 GlobalFilter 和 GatewayFilter 兩種。

                3.2.5.1 自定義GatewayFilter

                首先創(chuàng)建一個自定義過濾器類MyDefineGatewayFilterFactory,繼承AbstractGatewayFilterFactory。

                @Componentpublic class MyDefineGatewayFilterFactory extends AbstractGatewayFilterFactory{ Logger logger= LoggerFactory.getLogger(MyDefineGatewayFilterFactory.class); public static final String NAME_KEY = “name”; public MyDefineGatewayFilterFactory() { super(MyConfig.class); } @Override public List shortcutFieldOrder() { return Arrays.asList(NAME_KEY); } @Override public GatewayFilter apply(MyConfig config) { return ((exchange, chain) -> { logger.info(“[Pre] Filter Request,name:”+config.getName()); //then接收一個變量,然后then前面處理的那個就結(jié)束了,后面開始處理then接收的這個變量 return chain.filter(exchange).then(Mono.fromRunnable(()->{ logger.info(“[Post] Response Filter”); })); }); } public static class MyConfig{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }}

                在上述代碼中,有幾點(diǎn)需要注意:

                • 類名必須要統(tǒng)一以GatewayFilterFactory結(jié)尾,因?yàn)槟J(rèn)情況下過濾器的 name 會采用該自定義類的前綴。這里的 name=MyDefine。
                • 在apply方法中,同時包含Pre和Post過濾。在then方法中是請求執(zhí)行結(jié)束之后的后置處理。
                • MyConfig 是一個配置類,該類中只有一個屬性 name。這個屬性可以在 yml 文件中使用。
                • 該類需要裝載到 Spring IoC 容器,此處使用@Component注解實(shí)現(xiàn)。

                接下來,修改application.yml,增加自定義過濾器配置

                spring: cloud: gateway: routes: – id: define_route uri: http://localhost:8080 predicates: – Path=/define/** filters: – MyDefine=My_Eclipse2019

                此時訪問到這個過濾器,就會輸出如下日志,說明進(jìn)入到了網(wǎng)關(guān)攔截器。

                2020-06-02 22:08:21.838 INFO 164 — [ioEventLoop-5-2] c.e.s.MyDefineGatewayFilterFactory : [Pre] Filter Request,name:My_Eclipse20192020-06-02 22:08:21.875 INFO 164 — [ctor-http-nio-5] c.e.s.MyDefineGatewayFilterFactory : [Post] Response Filter

                3.2.5.2 自定義GlobalFilter

                GlobalFilter 的實(shí)現(xiàn)比較簡單,它不需要額外的配置,只需要實(shí)現(xiàn) GlobalFilter 接口,自動會過濾所有的 Route

                @Servicepublic class MyDefineFilter implements GlobalFilter,Ordered{ Logger log= LoggerFactory.getLogger(MyDefineFilter.class); @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info(“[pre]-Enter MyDefineFilter”); return chain.filter(exchange).then(Mono.fromRunnable(()->{ log.info(“[post]-Return Result”); })); } @Override public int getOrder() { return 0; }}

                getOrder 表示該過濾器的執(zhí)行順序,值越小,執(zhí)行優(yōu)先級越高。需要注意的是,我們通過 AbstractGatewayFilterFactory 實(shí)現(xiàn)的局部過濾器沒有指定 order,它的默認(rèn)值是 0,如果想要設(shè)置多個過濾器的執(zhí)行順序,可以重寫 getOrder 方法。

                第4章 路由

                4.1 基于集群負(fù)載均衡路由

                當(dāng)被路由的目標(biāo)服務(wù)是一個集群節(jié)點(diǎn)時,就會涉及到集群路由,Spring Cloud Gateway提供了一個LoadBalancerClientFilter全局過濾器,來實(shí)現(xiàn)負(fù)載均衡的解析。

                1.增加jar包依賴

                org.springframework.cloud spring-cloud-starter-netflix-eureka-client

                2.user項(xiàng)目也要注冊到Eureka上面去

                3.修改application.yml配置

                spring: application: name: gateway redis:database: 1 password: eclipse2019 host: localhost cloud: gateway: routes: – id: getUser uri: lb://user # 修改這里 predicates: – Path=/get/** discovery: # 修改這里 locator: enabled: true lower-case-service-id: true server: port: 9527eureka: # 修改這 instance: hostname: gateway-9527 client: service-url: register-with-eureka: true fetch-registry: true defaultZone: http://127.0.0.1:8761/eureka

                增加部分的配置說明如下

                • lower-case-service-id:是否使用 service-id 的小寫,默認(rèn)是大寫。
                • spring.cloud.gateway.discovery.locator.enabled:開啟從注冊中心動態(tài)創(chuàng)建路由的功能。
                • uri 中配置的lb://表示從注冊中心獲取服務(wù),后面的user表示目標(biāo)服務(wù)在注冊中心上的服務(wù)名

                重啟gateway-common項(xiàng)目,訪問:http://localhost/get/3接口。

                4.2 動態(tài)路由的實(shí)現(xiàn)

                在實(shí)際應(yīng)用中, 我們還會存在一種:動態(tài)配置路由的需求。也就是在運(yùn)行過程中,動態(tài)增加或者修改網(wǎng)關(guān)路由配置,這個需求在Spring Cloud Gateway中如何實(shí)現(xiàn)呢?

                在Spring Cloud Gateway中,提供了GatewayControllerEndpoint這個類來實(shí)現(xiàn)路由的動態(tài)修改,可以通過actuator打開這些endpoint信息

                1.添加Pom依賴

                org.springframework.boot spring-boot-starter-actuator

                2.修改application.yml,開發(fā)所有endpoint

                management: endpoints: web: exposure: include: *

                4.2.1 檢索網(wǎng)關(guān)中定義的路由

                通過這個地址:http://localhost:9527/actuator/gateway/routes可以獲得當(dāng)前網(wǎng)關(guān)中所有定義的路由

                [ { predicate: “Paths: [/get/**], match trailing slash: true”, route_id: “getUser”, filters: [ ], uri: “lb://user”, order: 0, }]

                其中:

                • route_id 表示路由編號
                • route_object.predicate 表示路由的條件匹配謂詞
                • route_object.filters 表示網(wǎng)關(guān)過濾器
                • order 路由順序

                4.2.2 查找特定的路由信息。

                http://localhost:9527/actuator/gateway/routes/{route_id}

                4.2.3 刷新路由緩存

                {POST請求}http://localhost:9527/actuator/gateway/refresh

                4.2.4 增減、修改路由

                /gateway/routes/{id} @PostMapping 新增一個路由信息

                /gateway/routes/{id} @DeleteMapping 刪除一個路由信息

                1.案例演示(添加路由)

                • 通過POST請求添加一個路由信息,http://localhost:9527/actuator/gateway/routes/baidu_route

                { “uri”: “https://www.baidu.com”, “predicates”: [{ “args”: { “pattern”: “/baidu/**” }, “name”: “Path” }], “filters”: [{ “args”: { “_genkey_0”: 1 }, “name”: “StripPrefix” }]}

                • 執(zhí)行:{POST請求}http://localhost:9527/actuator/gateway/refresh刷新路由。
                • 通過訪問:http://localhost:9527/actuator/gateway/routes 查看當(dāng)前路由列表,可以發(fā)現(xiàn)多了一個段這樣的內(nèi)容。

                { predicate: “Paths: [/baidu/**], match trailing slash: true”, route_id: “baidu_route”, filters: [ “[[StripPrefix parts = 1], order = 1]” ], uri: “https://www.baidu.com:443”, order: 0,}

                • 此時我們訪問: http://localhost:9527/baidu ,就會路由到百度搜索引擎這個網(wǎng)址。

                2.案例演示(刪除路由)

                • 通過/gateway/routes/{id} @DeleteMapping 刪除一個路由信息
                • 通過postman調(diào)用 /gateway/routes/baidu_route (delete請求), 就可以刪除路由,刪除路由之后再次訪問路由列表頁面,此時可以發(fā)現(xiàn)路由信息是被刪除的。

                4.2.5 小結(jié)

                基于Spring Cloud Gateway默認(rèn)方法實(shí)現(xiàn)的動態(tài)路由就講解完了,但是通過這種形式是去更新的動態(tài)路由信息,是基于內(nèi)存來實(shí)現(xiàn)的。一旦服務(wù)重啟,新增的路由配置信息就會全部清空,所以這個時候我們可以參考GatewayControllerEndpoint這個類,來自己實(shí)現(xiàn)一套動態(tài)路由的方法。并且將路由信息持久化。

                在實(shí)際開發(fā)中也可以通過Nacos作為配置中心直接在Nacos上面增加。

                下文預(yù)告

              30. Gateway核心源碼分析
              31. 鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年7月11日 09:33
                下一篇 2022年7月11日 09:33

                相關(guān)推薦

                • 分享4條發(fā)微商朋友圈的方法(微商朋友圈應(yīng)該怎么發(fā))

                  對于微商朋友來說,朋友圈的重要性不言而喻了。 那么微商的朋友圈到底該怎么發(fā)呢? 為什么同樣是經(jīng)營一個朋友圈,有的微商看起來逼格滿滿,實(shí)際效果也不錯;而有的卻動都不動就被屏蔽甚至拉黑…

                  2022年11月27日
                • 存儲過程語法(sql server存儲過程語法)

                  今天小編給各位分享存儲過程語法的知識,其中也會對sql server存儲過程語法進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! oracle存儲過程基本語法…

                  2022年11月26日
                • 計算機(jī)網(wǎng)絡(luò)技術(shù)論文(計算機(jī)網(wǎng)絡(luò)技術(shù)論文七千字)

                  今天小編給各位分享計算機(jī)網(wǎng)絡(luò)技術(shù)論文的知識,其中也會對計算機(jī)網(wǎng)絡(luò)技術(shù)論文七千字進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! 計算機(jī)網(wǎng)絡(luò)方面的論文3000字…

                  2022年11月26日
                • 《寶可夢朱紫》夢特性怎么獲得?隱藏特性獲取方法推薦

                  寶可夢朱紫里有很多寶可夢都是擁有夢特性會變強(qiáng)的寶可夢,很多玩家不知道夢特性怎么獲得,下面就給大家?guī)韺毧蓧糁熳想[藏特性獲取方法推薦,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 …

                  2022年11月25日
                • 《寶可夢朱紫》奇魯莉安怎么進(jìn)化?奇魯莉安進(jìn)化方法分享

                  寶可夢朱紫中的奇魯莉安要怎么進(jìn)化呢?很多玩家都不知道,下面就給大家?guī)韺毧蓧糁熳掀骠斃虬策M(jìn)化方法分享,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 奇魯莉安進(jìn)化方法分享 奇魯莉安…

                  2022年11月25日
                • 鬧劇落下帷幕,曼聯(lián)官宣 C 羅離隊

                  1、鬧劇落下帷幕,曼聯(lián)官宣 C 羅離隊 在經(jīng)歷過半個賽季的激烈鬧劇、C 羅私自接受采訪炮轟曼聯(lián)之后,俱樂部終于做出了相對應(yīng)的措施:正式官宣 C 羅離隊。 在曼聯(lián)俱樂部發(fā)布的聲明中寫…

                  2022年11月24日
                • 淘寶直播平臺抽成多少(淘寶直播平臺抽成比例)

                  隨著時代的發(fā)展,現(xiàn)在直播帶貨已經(jīng)成為主要帶貨方式,其中淘寶是主流帶貨平臺,不少人在上面直播帶貨賺錢,一些小伙伴也想加入,那么淘寶直播平臺抽成多少?下面小編為大家?guī)硖詫氈辈テ脚_抽成…

                  2022年11月24日
                • iqoo11什么時候上市 iqoo11發(fā)布時間最新消息

                  iqoo11什么時候發(fā)布?隨著新一代旗艦芯片的發(fā)布,各家手機(jī)廠商也是公布了自己的旗艦機(jī),那么iqoo11什么時候發(fā)布呢?下面就讓小編為大家介紹一下,一起來看看吧。 iqoo11什么…

                  2022年11月24日
                • 銳龍97900x參數(shù)規(guī)格跑分評測 銳龍97900x屬于什么檔次

                  銳龍9 7900X是銳龍7000系列處理器中性能頂尖的型號之一,它采用了這一代標(biāo)配的zen4架構(gòu)和5nm制程工藝,那么它具體的參數(shù)跑分如何,在電腦上世紀(jì)發(fā)揮怎么樣呢,下面就來看看銳…

                  2022年11月24日
                • 曝小米13系列已量產(chǎn):起步價格或定在4500元左右

                  高通目前已經(jīng)發(fā)布第二代驍龍8芯片,首批機(jī)型已經(jīng)蓄勢待發(fā),小米此前也已經(jīng)宣布新旗艦要率先搭載。 據(jù)澎湃報道,小米13系列已經(jīng)正式量產(chǎn),全系均搭載4nm芯片,不出意外是標(biāo)配第二代驍龍8…

                  2022年11月24日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時間:周一至周五,10:30-18:30,節(jié)假日休息