偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

SpringCloud,這份架構(gòu)圖幫你梳理全部知識(shí)點(diǎn)

開發(fā) 架構(gòu)
Spring Cloud Gateway 是一款基于 Spring 5,Project Reactor 以及 Spring Boot 2 構(gòu)建的 API 網(wǎng)關(guān),是 Spring Cloud 微服務(wù)生態(tài)的主要組件之一。Spring Cloud Gateway 主要負(fù)責(zé)接口請(qǐng)求的路由分發(fā),并且支持對(duì)請(qǐng)求的安全驗(yàn)證,流量監(jiān)控和流量控制等擴(kuò)展操作。

思維導(dǎo)圖

 

SpringCloud,這份架構(gòu)圖幫你梳理全部知識(shí)點(diǎn)

認(rèn)識(shí) Spring Cloud Gateway

Spring Cloud Gateway 是一款基于 Spring 5,Project Reactor 以及 Spring Boot 2 構(gòu)建的 API 網(wǎng)關(guān),是 Spring Cloud 微服務(wù)生態(tài)的主要組件之一。Spring Cloud Gateway 主要負(fù)責(zé)接口請(qǐng)求的路由分發(fā),并且支持對(duì)請(qǐng)求的安全驗(yàn)證,流量監(jiān)控和流量控制等擴(kuò)展操作。另外值得一提的點(diǎn)是,Spring Cloud Gateway 默認(rèn)采用了非阻塞 I/O 模型實(shí)現(xiàn)請(qǐng)求路由的分發(fā)。對(duì)于處理一些I/O 耗時(shí)長的請(qǐng)求上,相比其他一樣用 Java 編寫采用的同步阻塞I/O 模型的網(wǎng)關(guān)性能更高,處理的并發(fā)數(shù)也更高,避免了因?yàn)?I/O 阻塞(網(wǎng)絡(luò)調(diào)用,數(shù)據(jù)庫操作等)導(dǎo)致線程空閑下來,仍能繼續(xù)處理響應(yīng)其他請(qǐng)求。

Spring Cloud Gateway 適用場景

作為 API 網(wǎng)關(guān),Spring Cloud Gateway 所提供的功能也很強(qiáng)大,集成了對(duì)負(fù)載均衡,動(dòng)態(tài)路由,訪問控制,限流熔斷,埋點(diǎn)監(jiān)控等功能的支持。如果現(xiàn)有的微服務(wù)體系是以 Java 生態(tài)甚至 Spring 生態(tài)為基礎(chǔ)的,那么就十分適合使用 Spring Cloud Gateway 作為 API 應(yīng)用網(wǎng)關(guān)了,讓聚合管理多個(gè)微服務(wù) API,對(duì)外進(jìn)行統(tǒng)一的輸出。

同時(shí)秉承 Spring 家族的傳統(tǒng),Spring Cloud Gateway 也旨在提供一個(gè)簡單,且高效的方式來進(jìn)行 API 路由和請(qǐng)求關(guān)注點(diǎn)的擴(kuò)展,對(duì)于已經(jīng)熟悉 Spring 或者 Spring Boot 的開發(fā)者來說,Spring Cloud Gateway 學(xué)習(xí)成本并不高,利用底層框架所帶的注解驅(qū)動(dòng)和自動(dòng)化配置等特性,使用和擴(kuò)展起來難度都不算高。

快速上手 Spring Cloud Gateway

利用 Spring Cloud Gateway 能快速搭建一個(gè) API 網(wǎng)關(guān),但在這之前,先介紹一下使用 Spring Cloud Gateway 框架所涉及的一些專用概念,來加深對(duì) Spring Cloud Gateway 的認(rèn)識(shí),方便后面的使用。

  • 路由:是 Spring Cloud Gateway 中基礎(chǔ)的組件,通常由一個(gè) id 標(biāo)識(shí),目標(biāo) URI,以及一系列斷言(Predicate)和過濾器組成。
  • 斷言(Predicate):是 Java 8 函數(shù)庫的 Predicate 對(duì)象,具體類型為 Predicate ,用于匹配 HTTP 請(qǐng)求上數(shù)據(jù)信息,如請(qǐng)求頭信息,請(qǐng)求體信息。如果對(duì)于某個(gè)請(qǐng)求的斷言為 true,那么它所關(guān)聯(lián)的路由就算匹配成功,然后將請(qǐng)求給這個(gè)路由處理。
  • 過濾器:用于某一個(gè)路由的請(qǐng)求或者響應(yīng)進(jìn)行修改的組件,在 Spring Cloud Gateway 都要實(shí)現(xiàn) GatewayFilter 接口,并且需要由基于 GatewayFilterFactory 具體實(shí)現(xiàn)類構(gòu)造。

 

SpringCloud,這份架構(gòu)圖幫你梳理全部知識(shí)點(diǎn)

認(rèn)識(shí)上面三個(gè)概念之后,再看上圖所示,就能清楚看出 Spring Cloud Gateway 對(duì)客戶端請(qǐng)求的處理過程了,這幫助我們用好 Spring Cloud Gateway 幫助很大。

  • 客戶端請(qǐng)求首先被 GatewayHandlerMapping 獲取,然后根據(jù)斷言匹配找到對(duì)應(yīng)的路由
  • 找到路由后,走完所關(guān)聯(lián)的一組請(qǐng)求過濾器的處理方法,請(qǐng)求到目標(biāo) URI 所對(duì)應(yīng)的服務(wù)程序,獲得服務(wù)響應(yīng)。
  • 網(wǎng)關(guān)收到響應(yīng)后,通過關(guān)聯(lián)的響應(yīng)過濾器的處理方法后,同樣由 GatewayHandlerMapping 返回響應(yīng)給客戶端。

額外需要注意的是 Spring Cloud Gateway 的過濾器是有序執(zhí)行的,統(tǒng)一以 order 值的大小決定執(zhí)行順序,值越小優(yōu)先級(jí)越高,就越先執(zhí)行。

如何實(shí)現(xiàn) API 聚合

認(rèn)識(shí) Spring Cloud Gateway 整體處理請(qǐng)求過程之后,我們現(xiàn)在就快速構(gòu)建一個(gè)基于 Spring Cloud Gateway 的 API 網(wǎng)關(guān),看看在實(shí)際應(yīng)用中還需要注意的哪些地方,需要注意的是本文所使用的 Spring Cloud Gateway 屬于最新的里程碑版本 2.2.3,對(duì)應(yīng) Spring Boot 版本為 2.3.1, 并且 Spring Cloud 版本為 Hoxton.SR6 。利用 Spring Initializr ,選擇對(duì)應(yīng)的版本和依賴后快速新建一個(gè)項(xiàng)目 spring-cloud-gateway-quick-start ,并且為了實(shí)現(xiàn)請(qǐng)求的路由,表現(xiàn)網(wǎng)關(guān)的效果,再分別新建用戶服務(wù)應(yīng)用 demo-userservice 和訂單服務(wù)應(yīng)用 demo-orderservice ,各自提供一個(gè)可調(diào)用 API 接口。

用戶服務(wù)暴露 8071 端口,提供 /user/get 接口:

  1. // demo-userservice  項(xiàng)目 
  2. @RestController 
  3. @RequestMapping("/user"
  4. public class UserServiceController { 
  5.     @RequestMapping("/get"
  6.     public User get() { 
  7.         return User.mock(); 
  8.     } 

類似,訂單服務(wù)暴露 8061 端口,提供 /order/get 接口:

  1. // demo-orderservice 項(xiàng)目 
  2. @RestController 
  3. @RequestMapping("/order"
  4. public class OrderServiceController { 
  5.     @RequestMapping("/get"
  6.     public Order get() { 
  7.         return Order.mock(); 
  8.     } 

接下來要通過 Spring Cloud Gateway 將兩個(gè)服務(wù)接口聚合在 spring-cloud-gateway-quick-start 項(xiàng)目中,首先來看下利用 Spring Cloud Gateway API 方式的實(shí)現(xiàn):

  1. @SpringBootApplication 
  2. public class DemogatewayApplication { 
  3.     public static void main(String[] args) { 
  4.         SpringApplication.run(DemogatewayApplication.class, args); 
  5.     } 
  6.  
  7.     @Bean 
  8.     public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { 
  9.         return builder.routes().route("user-service", r -> r.path("/user/*").uri("http://localhost:8071")) 
  10.                 .route("order-service", r -> r.path("/order/*").uri("http://localhost:8061")) 
  11.                 .build(); 
  12.     } 

接下來要通過 Spring Cloud Gateway 將兩個(gè)服務(wù)接口聚合在 spring-cloud-gateway-quick-start 項(xiàng)目中,首先來看下利用 Spring Cloud Gateway API 方式的實(shí)現(xiàn):

上述代碼就已經(jīng)實(shí)現(xiàn) API 路由的功能,是不是很快速,同時(shí)啟動(dòng) spring-cloud-gateway-quick-start 和其他服務(wù)應(yīng)用,就可以統(tǒng)一通過網(wǎng)關(guān)應(yīng)用訪問用戶服務(wù)和訂單服務(wù)了:

  1. one@192 ~ % curl http://localhost:8080/user/get 
  2. {"id":4720186416534735290,"token":"86b6118d-7dc6-4d30-a5f3-3d5fc6348f9a"
  3.    
  4. one@192 ~ % curl http://localhost:8080/order/get 
  5. {"id":5832646761962425508,"title":"My Order"

回到 API 實(shí)現(xiàn)的代碼, DemogatewayApplication#customRouteLocator 方法中定義了兩個(gè) id 分別為 user-service 和 order-service 的路由,并且設(shè)置了匹配請(qǐng)求的斷言,以及真正目標(biāo)請(qǐng)求地址。這里路由的斷言采用了路徑匹配的規(guī)則,只要原始請(qǐng)求地址符合對(duì)應(yīng)的規(guī)則就算匹配到此路由,但 Spring Cloud Gate 還支持豐富的斷言規(guī)則,如主機(jī)匹配,請(qǐng)求體字段匹配,請(qǐng)求數(shù)據(jù)匹配等等,足以滿足定制路由斷言的規(guī)則了。

由于使用 API 就是硬編碼方式將路由規(guī)則定義在程序里了,這樣做擴(kuò)展性很差,也不好維護(hù)。于是更推薦另外一種實(shí)現(xiàn)方式:配置化。來看下要實(shí)現(xiàn)相同功能,在 application.properties 里該如何配置:

  1. spring.cloud.gateway.routes[0].id=order-service 
  2. spring.cloud.gateway.routes[0].uri=http://localhost:8061 
  3. spring.cloud.gateway.routes[0].predicates[0].name=Path 
  4. spring.cloud.gateway.routes[0].predicates[0].args[pattern]=/order/* 
  5. spring.cloud.gateway.routes[1].id=user-service 
  6. spring.cloud.gateway.routes[1].uri=http://localhost:8071 
  7. spring.cloud.gateway.routes[1].predicates[0].name=Path 
  8. spring.cloud.gateway.routes[1].predicates[0].args[pattern]=/user/* 

使用上面的配置,重啟網(wǎng)關(guān)應(yīng)用,同樣能完成之前 API 方式的效果,由于路由規(guī)則轉(zhuǎn)移到了配置文件中,就大大方便對(duì) API 的管理,為實(shí)現(xiàn)動(dòng)態(tài)路由也提供了可能。當(dāng)然需要實(shí)現(xiàn)動(dòng)態(tài)路由,除了路由配置,還需要進(jìn)行額外的擴(kuò)展實(shí)現(xiàn)路由規(guī)則的動(dòng)態(tài)刷新,涉及 Spring Cloud Gateway 更高級(jí)的用法,本文就不再詳細(xì)贅述了,可以等后續(xù)進(jìn)階使用和分析的文章或者參考網(wǎng)上其他實(shí)現(xiàn)資料。

如何自定義過濾器

為了能對(duì) API 的請(qǐng)求或者響應(yīng)處理,Spring Cloud Gateway 提供過濾器組件來實(shí)現(xiàn)這一功能,并且內(nèi)置了很多功能強(qiáng)大。另外過濾器分兩類,全局過濾器和網(wǎng)關(guān)過濾器,對(duì)于全局過濾器,所有匹配到路由的請(qǐng)求處理時(shí)都會(huì)經(jīng)過全局過濾器處理;而網(wǎng)關(guān)過濾器只有顯示在指定路由上時(shí)才會(huì)起到左右。

Spring Cloud Gateway 默認(rèn)的全局過濾器有 8個(gè):

  • ForwardRoutingFilter
  • LoadBalancerClientFilter(棄用)
  • ReactiveLoadBalancerClientFilter
  • WebClientHttpRoutingFilter
  • NettyWriteResponseFilter
  • RouteToRequestUrlFilter
  • WebsocketRoutingFilter
  • GatewayMetricsFilter

而網(wǎng)關(guān)過濾器就更多了,并且由對(duì)應(yīng)工廠類來構(gòu)造,比如用于熔斷的 HystrixGatewayFilterFactory ,用于限流的 RequestRateLimiterGatewayFilterFactory,用于修改請(qǐng)求數(shù)據(jù)的 ModifyRequestBodyGatewayFilterFactory 等等,當(dāng)然也支持開發(fā)者進(jìn)行定義自己的過濾器。

首先來看下如何自定義一個(gè)全局過濾器,代碼實(shí)現(xiàn)比較簡單:

  1. @Component 
  2. public class CustomGlobalFilter implements GlobalFilter, Ordered { 
  3.     private Logger log = LoggerFactory.getLogger(MyAuthFilterFactory.class); 
  4.  
  5.     @Override 
  6.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { 
  7.         log.info("執(zhí)行自定過濾器"); 
  8.         return chain.filter(exchange); 
  9.     } 
  10.  
  11.     @Override 
  12.     public int getOrder() { 
  13.         return -1; 
  14.     } 

這樣就可以為所有路由添加一個(gè)全局的過濾器了。不同于全局過濾器的定義,網(wǎng)關(guān)過濾器必須在指定路由上進(jìn)行申明才能生效,參考官方內(nèi)置的網(wǎng)關(guān)攔截器,自定義一個(gè)用于授權(quán)的簡易網(wǎng)關(guān)攔截器工廠如下:

  1. @Component 
  2. public class MyAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<MyAuthGatewayFilterFactory.Config> { 
  3.     private Logger logger = LoggerFactory.getLogger(MyAuthGatewayFilterFactory.class); 
  4.  
  5.     public MyAuthGatewayFilterFactory() { 
  6.         super(Config.class); 
  7.     } 
  8.  
  9.     @Override 
  10.     public GatewayFilter apply(Config config) { 
  11.         return new GatewayFilter() { 
  12.             @Override 
  13.             public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { 
  14.                 ServerHttpRequest request = exchange.getRequest(); 
  15.                 MultiValueMap<String, String> queryParams = request.getQueryParams(); 
  16.                 String from = queryParams.getFirst(config.getAuthKey()); 
  17.                 ServerHttpResponse response = exchange.getResponse(); 
  18.                 logger.warn("校驗(yàn)授權(quán)開始"); 
  19.                 if (config.getAuthValue().equals(from)) { 
  20.                     logger.warn("校驗(yàn)授權(quán)成功"); 
  21.                     return chain.filter(exchange); 
  22.                 } else { 
  23.                     logger.warn("校驗(yàn)授權(quán)失敗"); 
  24.                     response.setStatusCode(HttpStatus.OK); 
  25.                     response.getHeaders().setContentType(MediaType.valueOf("text/html;charset=utf-8")); 
  26.                     DataBuffer wrap = response.bufferFactory().wrap(config.getAuthFailMsg().getBytes(Charset.forName("UTF-8"))); 
  27.                     return response.writeWith(Flux.just(wrap)); 
  28.                 } 
  29.             } 
  30.         }; 
  31.     } 
  32.  
  33.     public static class Config { 
  34.         private String authKey = "from"
  35.         private String authValue = "system"
  36.         private String authFailMsg = "授權(quán)失敗"
  37.  
  38.         public String getAuthKey() { 
  39.             return authKey; 
  40.         } 
  41.  
  42.         public void setAuthKey(String authKey) { 
  43.             this.authKey = authKey; 
  44.         } 
  45.  
  46.         public String getAuthValue() { 
  47.             return authValue; 
  48.         } 
  49.  
  50.         public void setAuthValue(String authValue) { 
  51.             this.authValue = authValue; 
  52.         } 
  53.  
  54.         public String getAuthFailMsg() { 
  55.             return authFailMsg; 
  56.         } 
  57.  
  58.         public void setAuthFailMsg(String authFailMsg) { 
  59.             this.authFailMsg = authFailMsg; 
  60.         } 
  61.     } 

如果要在 user-service 路由下使用,需要在 application.properties 配置文件添加如下配置:

  1. spring.cloud.gateway.routes[1].filters[0].name=MyAuth 

這里的名稱就需要跟 MyAuthGatewayFilterFactory 類的 MyAuth 保持一致,Spring Cloud Gateway 會(huì)自動(dòng)拼接上 AuthGatewayFilterFactory 去查找對(duì)應(yīng)的網(wǎng)關(guān)過濾器,沒有找到就會(huì)導(dǎo)致啟動(dòng)失敗,拋出異常:

  1. java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name MyAuth2 

配置完對(duì)網(wǎng)關(guān)應(yīng)用進(jìn)行重啟,這是使用原來的方式去請(qǐng)求用戶服務(wù),已經(jīng)無法正常訪問,只會(huì)返回校驗(yàn)授權(quán)失敗的信息,必須以 http://localhost:8080/user/get?from=system 方式訪問才能成功獲取到數(shù)據(jù),說明定義的授權(quán)攔截器已經(jīng)起了作用。

這里我們就將全局?jǐn)r截器和網(wǎng)關(guān)攔截器都實(shí)現(xiàn)了自定義,通常情況我們都會(huì)在網(wǎng)關(guān)攔截器上進(jìn)行擴(kuò)展定制,也結(jié)合內(nèi)置的過濾器使用。

責(zé)任編輯:未麗燕 來源: 今日頭條
相關(guān)推薦

2017-09-26 13:52:52

深度學(xué)習(xí)機(jī)器學(xué)習(xí)思維導(dǎo)圖

2018-01-16 12:31:33

Python爬蟲數(shù)據(jù)

2018-11-27 15:51:10

MySQL數(shù)據(jù)庫查詢優(yōu)化

2020-07-16 15:00:56

MySQL索引數(shù)據(jù)庫

2018-10-21 15:36:13

UI適配iOS

2025-04-25 10:00:00

2011-04-15 12:25:21

BGP路由

2010-08-17 14:56:00

HCNE認(rèn)證

2016-05-30 17:31:34

Spring框架

2010-08-18 10:52:46

Linux筆試

2010-09-02 10:11:11

華為認(rèn)證

2025-05-07 08:55:00

2020-10-07 15:15:41

Python

2025-05-19 10:00:00

MySQL數(shù)據(jù)庫InnoDB

2009-12-18 17:34:38

Ruby線程

2010-07-27 15:49:28

Flex

2009-08-06 17:42:32

C#知識(shí)點(diǎn)

2010-06-17 16:42:04

UML

2021-01-18 10:33:53

Java反射模塊

2019-09-23 10:47:52

Kafka架構(gòu)微服務(wù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)