Gateway網(wǎng)關(guān)
gitee:springcloud_study: springcloud:服務(wù)集群、注冊中心、配置中心(熱更新)、服務(wù)網(wǎng)關(guān)(校驗(yàn)、路由、負(fù)載均衡)、分布式緩存、分布式搜索、消息隊(duì)列(異步通信)、數(shù)據(jù)庫集群、分布式日志、系統(tǒng)監(jiān)控鏈路追蹤。
1. 概述簡介
官網(wǎng):Spring Cloud Gateway
Gateway該項(xiàng)目提供了一個構(gòu)建在Spring生態(tài)系統(tǒng)之上的API網(wǎng)關(guān),包括:Spring 5、Spring Boot 2和project Reactor。Spring Cloud Gateway旨在提供一種簡單而有效的方法來路由到API,并為它們提供跨領(lǐng)域的關(guān)注點(diǎn),例如:安全性、監(jiān)控/度量和彈性。SpringCloud Gateway作為 Spring Cloud 生態(tài)系統(tǒng)中的網(wǎng)關(guān),目標(biāo)是替代zuul,在Spring Cloud 2.0以上版本中,沒有對新版本的Zuul 2.0以上最新高性能版本進(jìn)行集成,仍然還是使用的Zuul 1.x非Reactor模式的老版本。而為了提升網(wǎng)關(guān)的性能,SpringCloud Gateway是基于WebFlux框架實(shí)現(xiàn)的,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty。 Netty異步非阻塞
Gateway能做反向代理、鑒權(quán)、流量控制、熔斷、日志監(jiān)控...
Gateway特性:
基于Spring Framework 5, Project Reactor和Spring Boot 2.0進(jìn)行構(gòu)建; 動態(tài)路由:能夠匹配任何請求屬性; 可以對路由指定Predicate (斷言)和 Filter (過濾器);集成Hystrix的斷路器功能; 集成 Spring Cloud服務(wù)發(fā)現(xiàn)功能; 易于編寫的 Predicate (斷言)和Filter(過濾器); 請求限流功能; 支持路徑重寫。
Gateway與Zuul區(qū)別:
在SpringCloud Finchley 正式版之前,Spring Cloud推薦的網(wǎng)關(guān)是Netflix提供的Zuul: 1、Zuul 1.x,是一個基于阻塞!/O的API Gateway 2、Zuul 1.基于Servlet 2.5使用阻塞架構(gòu)它不支持任何長連接(如WebSocket)zuul的設(shè)計模式和Nginx較像,每次VО操作都是從工作線程中選擇一個執(zhí)行,請求線程被阻塞到工作線程完成,但是差別是Ngink用C++實(shí)現(xiàn),Zuul用Java實(shí)現(xiàn),而JVM本身會有第一次加載較慢的情況,使得Zuul的性能相對較差。 3、Zuul 2.x理念更先進(jìn),想基于Netty非阻塞和支持長連接,但SpringCloud目前還沒有整合。Zuul .x的性能較Zul 1.x有較大提升。在性能方面,根據(jù)官方提供的基準(zhǔn)測試,Spring Cloud Gateway的RPS(每秒請求數(shù))是Zuul的1.6倍。 4、Spring Cloud Gateway建立在Spring Framework 5、Project Reactor和Spring Boot 2之上,使用非阻塞API。 5、Spring Cloud Gateway還支持WebSocket,并且與Spring緊密集成擁有更好的開發(fā)體驗(yàn)
SpringMVC與Spring WebFlux
傳統(tǒng)的Web框架,比如說: struts2,springmvc等都是基于Servlet API與Servlet容器基礎(chǔ)之上運(yùn)行的。但是 在Servlet3.1之后有了異步非阻寒的支持。而WebFlux是一個典型非阻塞異步的框架,它的核心是基于Reactor的相關(guān)API實(shí)現(xiàn)的。相對于傳統(tǒng)的web框架來說,它可以運(yùn)行在諸如Netty,Undertow及支持Servlet3.1的容器上。非阻塞式+函數(shù)式編程(Spring5必須讓你使用java8) Spring WebFlux是Spring 5.0 引入的新的響應(yīng)式框架,區(qū)別于Spring MVC,它不需要依賴Servlet API,它是完全異步非阻塞的,并且基于Reactor來實(shí)現(xiàn)響應(yīng)式流規(guī)范。
2. 三大核心概念
Router(路由)
Route: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates, and a collection of filters. A route is matched if the aggregate predicate is true. 路由是構(gòu)建網(wǎng)關(guān)的基本模塊,它由ID,目標(biāo)URI,一系列的斷言和過濾器組成,如果斷言為true則匹配該路由
Predicate(斷言)
Predicate: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters. 參考的是Java8的java.util.function.Predicate 開發(fā)人員可以匹配HTTP請求中的所有內(nèi)容(例如請求頭或請求參數(shù)),如果請求與斷言相匹配則進(jìn)行路由
Filter(過濾)
Filter: These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request. 指的是Spring框架中GatewayFilter的實(shí)例,使用過濾器,可以在請求被路由前或者之后對請求進(jìn)行修改。
工作流程原理:
客戶端向 Spring Cloud 網(wǎng)關(guān)發(fā)出請求。如果網(wǎng)關(guān)處理程序映射確定請求與路由匹配,則會將其發(fā)送到網(wǎng)關(guān) Web 處理程序。 此處理程序通過特定于請求的篩選器鏈運(yùn)行請求。 篩選器用虛線劃分的原因是篩選器可以在發(fā)送代理請求之前和之后運(yùn)行邏輯。 執(zhí)行所有“預(yù)”過濾器邏輯。然后發(fā)出代理請求。發(fā)出代理請求后,將運(yùn)行“post”篩選器邏輯。核心邏輯就是路由轉(zhuǎn)發(fā)+執(zhí)行過濾器鏈
3. 入門配置
新建cloud-gateway-gateway9527項(xiàng)目
-
pom文件
<dependency>
? ?<groupId>org.springframework.cloud</groupId>
? ?<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
-
application.yaml
server:
port: 9527
spring:
application:
? name: cloud-gateway
eureka:
instance:
? hostname: cloud-gateway-service
client:
? service-url:
? ? defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
? register-with-eureka: true
? fetch-registry: true
-
主啟動類
@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
? ?public static void main(String[] args) {
? ? ? ?SpringApplication.run(GatewayMain9527.class,args);
? }
}
-
9527做網(wǎng)關(guān)的路由映射,增加yaml(考慮像eureka一樣直接一個集群注入,不用每一項(xiàng)寫入)
spring:
application:
? name: cloud-gateway
cloud:
? gateway:
? ? routes:
? ? ? - id: payment_routh #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
? ? ? ? uri: http://localhost:8001 #匹配后提供服務(wù)的路由地址
? ? ? ? predicates: #斷言,路徑相匹配的進(jìn)行路由
? ? ? ? ? - Path=/payment/get/**
? ? ? - id: payment_routh2
? ? ? ? uri: http://localhost:8001
? ? ? ? predicates:
? ? ? ? ? - Path=/payment/lb/**
-
gateway網(wǎng)關(guān)不需要web的jar,去除:
<dependency>
? ?<groupId>org.springframework.boot</groupId>
? ?<artifactId>spring-boot-starter-web</artifactId>
</dependency>
測試:
代碼中注入RouteLocator的Bean
上面是在yaml中配置,截下來是在代碼中直接注入:
@Configuration
public class GatewayConfig {
? ?@Bean
? ?public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
? ? ? ?RouteLocatorBuilder.Builder builder=routeLocatorBuilder.routes();
? ? ? ?builder.route("path_route_yicai",
? ? ? ? ? ? ? ?r->r.path("/qq_53957101/article/details/130376180")
? ? ? ? ? ? ? ? ? ? ? .uri("https://blog.csdn.net/")).build();
? ? ? ?return builder.build();
? }
}
測試:
后面不穩(wěn)定一下就跳動,建議可以使用自己的項(xiàng)目來做映射。
4. 通過微服務(wù)名實(shí)現(xiàn)動態(tài)路由
默認(rèn)情況下Gateway會根據(jù)注冊中心注冊的服務(wù)列表,以注冊中心上微服務(wù)名為路徑創(chuàng)建動態(tài)路由進(jìn)行轉(zhuǎn)發(fā),從而實(shí)現(xiàn)動態(tài)路由的功能。
yaml文件修改:
spring:
application:
? name: cloud-gateway
cloud:
? gateway:
? ? discovery:
? ? ? locator:
? ? ? ? enabled: true #開啟從注冊中心動態(tài)創(chuàng)建路由的功能,利用徼服務(wù)名進(jìn)行路由
? ? routes:
? ? ? - id: payment_routh #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
# ? ? ? ? uri: http://localhost:8001 #匹配后提供服務(wù)的路由地址
? ? ? ? uri: lb://cloud-payment-service #匹配后提供服務(wù)的路由地址
? ? ? ? predicates: #斷言,路徑相匹配的進(jìn)行路由
? ? ? ? ? - Path=/payment/get/**
? ? ? - id: payment_routh2
# ? ? ? ? uri: http://localhost:8001
? ? ? ? uri: lb://cloud-payment-service
? ? ? ? predicates:
? ? ? ? ? - Path=/payment/lb/**
測試:
5. Predicate的使用
1.路由后謂詞工廠采用一個參數(shù),即日期時間。 此謂詞匹配在指定日期時間之后發(fā)生的請求。 2.路由之前謂詞工廠采用一個參數(shù) . 此謂詞匹配在指定的。 3.路由謂詞工廠采用兩個參數(shù),和 。 此謂詞匹配在 之后和之前發(fā)生的請求。參數(shù)必須位于之后。 4.cookie 路由謂詞工廠采用兩個參數(shù),即 cookie 名稱和正則表達(dá)式。 此謂詞匹配具有給定名稱且其值與正則表達(dá)式匹配的 Cookie。 5.標(biāo)頭路由謂詞工廠采用兩個參數(shù),即標(biāo)頭名稱和正則表達(dá)式。 此謂詞與具有給定名稱的標(biāo)頭匹配,該標(biāo)頭的值與正則表達(dá)式匹配。 ...
操作:
日期
-
闖將一個測試類T2
public class T2 {
? ?public static void main(String[] args) {
? ? ? ?ZonedDateTime zbj=ZonedDateTime.now();
? ? ? ?System.out.println(zbj);
? }
}
-
修改配置yaml
- id: payment_routh2
# ? ? ? ? uri: http://localhost:8001
? ? ? ? uri: lb://cloud-payment-service
? ? ? ? predicates:
? ? ? ? ? - Path=/payment/lb/**
? ? ? ? ? - After=2023-07-09T10:44:16.126+08:00[Asia/Shanghai]
測試: 一個剛剛:
一個幾小時后:
Cookie
-
修改yaml
? ? ? - id: payment_routh2
# ? ? ? ? uri: http://localhost:8001
? ? ? ? uri: lb://cloud-payment-service
? ? ? ? predicates:
? ? ? ? ? - Path=/payment/lb/**
? ? ? ? ? - Cookie=username,zzyy
使用Curl測試:
Header
-
修改yaml
? ? ? - id: payment_routh2
# ? ? ? ? uri: http://localhost:8001
? ? ? ? uri: lb://cloud-payment-service
? ? ? ? predicates:
? ? ? ? ? - Path=/payment/lb/**
? ? ? ? ? - Header=X-Request-Id,\d+
使用curl測試:
6. Filter的使用
官網(wǎng)自帶
生命周期:pre/post 種類:GatewayFilter/GlobalFilter
-
yaml修改,添加AddRequestParameter
? ? ? ? filters: ? ? ? ? ? - AddRequestParameter=X-Request-Id,1024 #過濾器工廠會在陣單的請求頭加上一對請求頭,名稱為X-Request-Id值為1024
自定義過濾器(自定義全局GlobalFilter)
@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {
?
? ?@Override
? ?public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
? ? ? ?log.info("*********come in MyLogGlobalGatewayFilter:"+new Date());
? ? ? ?String uname=exchange.getRequest().getQueryParams().getFirst("uname");
? ? ? ?if(uname==null){
? ? ? ? ? ?log.info("非法");
? ? ? ? ? ?exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
? ? ? ? ? ?return exchange.getResponse().setComplete();
? ? ? }
? ? ? ?return chain.filter(exchange);
? }
?
? ?@Override
? ?public int getOrder() {
? ? ? ?return 0;
? }
}
測試:文章來源:http://www.zghlxwxcb.cn/news/detail-761593.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-761593.html
到了這里,關(guān)于第八章 Gateway網(wǎng)關(guān)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!