這篇文章,主要介紹微服務(wù)組件之Gateway實(shí)現(xiàn)動(dòng)態(tài)路由、配置路由映射規(guī)則、路由過濾器。
目錄
一、動(dòng)態(tài)路由配置
1.1、動(dòng)態(tài)URI路由配置
(1)引入eureka客戶端依賴
(2)添加路由配置
1.2、服務(wù)名稱轉(zhuǎn)發(fā)配置
二、斷言配置規(guī)則
2.1、路由斷言工廠類
2.2、Path路徑匹配
2.3、Query請(qǐng)求參數(shù)匹配
2.4、Method請(qǐng)求方式匹配
2.5、RemoteAddr遠(yuǎn)程地址匹配
2.6、Header請(qǐng)求頭匹配
三、路由過濾器
3.1、Path路徑過濾器
(1)RewritePath重寫路徑
(2)PrefixPath路徑前綴
(3)StripPrefix分隔前綴
(4)SetPath路徑參數(shù)
3.2、Parameter參數(shù)過濾器
3.3、Status狀態(tài)過濾器
3.4、自定義網(wǎng)關(guān)過濾器
(1)實(shí)現(xiàn)GatewayFilter接口
(2)配置自定義過濾器
3.5、自定義全局過濾器
(1)實(shí)現(xiàn)GlobalFilter接口
一、動(dòng)態(tài)路由配置
1.1、動(dòng)態(tài)URI路由配置
前一篇文章介紹了Gateway服務(wù)網(wǎng)關(guān)的基礎(chǔ)環(huán)境搭建,在基礎(chǔ)環(huán)境中,我們的路由地址uri是直接在application.yml配置文件中寫死的,這種方式不太靈活,因?yàn)橐坏┪⒎?wù)的IP和端口改變,此時(shí)就需要修改Gateway工程中的配置文件,然后重新啟動(dòng)網(wǎng)關(guān)工程。為了解決能夠讓路由不依賴于具體的IP和端口,這里就需要實(shí)現(xiàn)一個(gè)動(dòng)態(tài)路由的功能。
動(dòng)態(tài)路由,借助于eureka注冊(cè)中心就能夠?qū)崿F(xiàn),在Gateway工程中引入eureka-client客戶端依賴,從注冊(cè)中心獲取微服務(wù)可用列表,根據(jù)微服務(wù)名稱實(shí)現(xiàn)路由的配置。
(1)引入eureka客戶端依賴
<!-- 引入 Gateway 依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 引入eureka client依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
(2)添加路由配置
- 動(dòng)態(tài)路由配置中,必須使用【lb://微服務(wù)名稱】這種格式,【lb】是LoadBalanced的縮寫,表示負(fù)載均衡。
- 動(dòng)態(tài)路由本質(zhì)上就是根據(jù)配置的微服務(wù)名稱,去注冊(cè)中心獲取到對(duì)應(yīng)微服務(wù)的IP地址和Port端口。
server:
port: 9999
spring:
application:
name: gateway-eureka-server
# 配置 gateway 路由信息
cloud:
gateway:
# 指定路由信息
routes:
- id: consumer-client # 路由唯一標(biāo)識(shí),一般和微服務(wù)應(yīng)用名稱相同即可
# 目標(biāo)路由的服務(wù)名稱,這里采用的是動(dòng)態(tài)路由,格式必須是:【lb://微服務(wù)名稱】
uri: lb://consumer-client
# 配置斷言,也就是請(qǐng)求的URI滿足哪些規(guī)則,才可以匹配當(dāng)前這個(gè)routes路由信息
predicates:
# 這里使用路由斷言,所有 /api/consumer 開頭的請(qǐng)求,都將轉(zhuǎn)發(fā)到 http://localhost:8081/ 這個(gè)服務(wù)上面
- Path=/api/consumer/**
# eureka 配置
eureka:
instance:
prefer-ip-address: true # 開啟采用 IP 注冊(cè)形式
# ${spring.cloud.client.ip-address} 這個(gè)屬性可以獲取到當(dāng)前機(jī)器的 IP 地址
instance-id: ${spring.cloud.client.ip-address}:${server.port} # 設(shè)置當(dāng)前服務(wù)的實(shí)例ID,采用:IP+端口形式
client:
# 從 eureka 服務(wù)端獲取注冊(cè)信息
fetch-registry: true
# 將自身注冊(cè)到 eureka 服務(wù)端
register-with-eureka: true
service-url:
# eureka 服務(wù)端地址
defaultZone: http://localhost:8761/eureka/
到這里,動(dòng)態(tài)URI路由就配置成功啦。
1.2、服務(wù)名稱轉(zhuǎn)發(fā)配置
第一種動(dòng)態(tài)路由的配置方式中,每次新增一個(gè)微服務(wù)應(yīng)用都需要在Gateway工程的配置文件里面,新增一個(gè)路由配置信息,這樣也太麻煩了,Gateway還提供了一種動(dòng)態(tài)路由方式,叫做:服務(wù)名稱轉(zhuǎn)發(fā)。這種動(dòng)態(tài)路由的方式是將eureka注冊(cè)中心中的微服務(wù)名稱作為請(qǐng)求URI的前綴,然后客戶端訪問的時(shí)候,需要在對(duì)應(yīng)的請(qǐng)求接口地址中帶上微服務(wù)名稱,Gateway通過微服務(wù)名稱就可以實(shí)現(xiàn)服務(wù)的轉(zhuǎn)發(fā)功能。
spring:
application:
name: gateway-eureka-server
# 配置 gateway 路由信息
cloud:
gateway:
# 動(dòng)態(tài)服務(wù)轉(zhuǎn)發(fā)
discovery:
locator:
enabled: true # 啟用動(dòng)態(tài)路由服務(wù)名稱轉(zhuǎn)發(fā)功能
lower-case-service-id: true # 開啟服務(wù)名稱小寫
采用上面這種動(dòng)態(tài)路由配置方式,在訪問的時(shí)候,就需要指定微服務(wù)名稱,例如:【http://localhost:9999/consumer-client/api/consumer/getUserInfo?username=csdn2023】,這里訪問的時(shí)候,就是需要指定訪問的是【consumer-client】這個(gè)微服務(wù)應(yīng)用,然后Gateway就可以根據(jù)這個(gè)微服務(wù)名稱將這個(gè)請(qǐng)求轉(zhuǎn)發(fā)到這個(gè)應(yīng)用程序里面。
二、斷言配置規(guī)則
2.1、路由斷言工廠類
Gateway支持多種斷言方式,也就是支持多種路由配置規(guī)則,斷言是采用工廠模式創(chuàng)建的,這個(gè)工廠接口是RoutePredicateFactory,這個(gè)有很多個(gè)實(shí)現(xiàn)類,每一個(gè)實(shí)現(xiàn)類就是一種路由配置規(guī)則,常見的有下面這些:
使用最多的應(yīng)該是Path路徑匹配。
2.2、Path路徑匹配
Path是根據(jù)請(qǐng)求的URI進(jìn)行規(guī)則匹配,路徑匹配支持正則表達(dá)式,配置規(guī)則如下所示:
2.3、Query請(qǐng)求參數(shù)匹配
Gateway可以根據(jù)請(qǐng)求URI中的參數(shù)來進(jìn)行規(guī)則匹配,這種方式叫做:Query。Query參數(shù)匹配的格式:
- Query=參數(shù)名稱1,參數(shù)名稱2,...(多個(gè)參數(shù)采用逗號(hào)分隔)。
- 這種匹配模式下,如果請(qǐng)求的URI中包含對(duì)應(yīng)的參數(shù)(只要包含其中一個(gè)參數(shù),就可以匹配成功),就會(huì)滿足匹配規(guī)則。
- 注意:需要注意的是,這種只能夠?qū)RI中的請(qǐng)求參數(shù)生效。
- Query模式也支持正則表達(dá)式。
2.4、Method請(qǐng)求方式匹配
Method是根據(jù)HTTP接口的請(qǐng)求方式來進(jìn)行匹配。
Method匹配規(guī)則中,如果訪問的接口地址不滿足Gateway的匹配規(guī)則,則會(huì)報(bào)錯(cuò)404;如果是滿足Gateway匹配規(guī)則,但是服務(wù)提供者這不滿足調(diào)用方式,此時(shí)會(huì)報(bào)錯(cuò)405(表示請(qǐng)求方式不正確)。
2.5、RemoteAddr遠(yuǎn)程地址匹配
RemoteAddr是指定哪些IP地址可以訪問Gateway網(wǎng)關(guān),也就是說,Gateway會(huì)匹配對(duì)應(yīng)的IP地址來判斷是否滿足規(guī)則。
2.6、Header請(qǐng)求頭匹配
Header規(guī)則是根據(jù)請(qǐng)求中,是否包含指定的Header請(qǐng)求頭字段,并且還可以設(shè)置請(qǐng)求字段的值是否滿足規(guī)則,例如:【\d+】表示數(shù)字。
三、路由過濾器
Gateway中提供了兩種類型的過濾器,分別是:Gateway Filter網(wǎng)關(guān)過濾器和Global Filter全局過濾器。GatewayFilter網(wǎng)關(guān)過濾器需要在application.yml配置文件中,使用【spring.cloud.gateway.routes.filters】屬性進(jìn)行配置;GlobalFilter全局過濾器不需要在配置文件中設(shè)置,它是作用于所有的路由上面。
3.1、Path路徑過濾器
Path路徑過濾器可以對(duì)請(qǐng)求的URI路徑進(jìn)行一些操作,例如:重寫路徑。
(1)RewritePath重寫路徑
路徑重寫可以將客戶端的請(qǐng)求URI重新轉(zhuǎn)換成另外一個(gè)請(qǐng)求URI,例如:將【/api-gateway/api/consumer/demo】路徑重寫成【/api/consumer/demo】路徑,Gateway將采用重寫之后的請(qǐng)求,去調(diào)用下游系統(tǒng),從而實(shí)現(xiàn)接口的調(diào)用。
(2)PrefixPath路徑前綴
PrefixPath是路徑前綴過濾器,這個(gè)過濾器可以為請(qǐng)求添加URI前綴,例如:當(dāng)我們請(qǐng)求【/consumer/demo】接口的時(shí)候,并且設(shè)置PrefixPath等于【/api】,那么這個(gè)過濾器最終形成的請(qǐng)求將是【/api/consumer/demo】,Gateway會(huì)通過【/api/consumer/demo】調(diào)用下游系統(tǒng)的接口。
(3)StripPrefix分隔前綴
StripPrefix是一個(gè)用于分隔路徑的過濾器,它會(huì)根據(jù)【/】斜杠將請(qǐng)求分隔成一個(gè)數(shù)組,StripPrefix的參數(shù)值就是將前面幾個(gè)元素刪除,只保留剩余的路徑。例如:請(qǐng)求【/api/api/api/consumer/demo】接口,設(shè)置【StripPrefix=2】,表示將接口前兩個(gè)路徑分割掉,最終得到的路徑是【/api/consumer/demo】。
(4)SetPath路徑參數(shù)
SetPath用于路徑參數(shù)的一個(gè)過濾器,它可以將URI路徑中的路徑參數(shù)采用map保存起來,然后在過濾器中可以通過【{segment}】獲取出來。
3.2、Parameter參數(shù)過濾器
Parameter參數(shù)過濾器,可以對(duì)網(wǎng)關(guān)接收到的請(qǐng)求添加、刪除一些參數(shù)信息。
3.3、Status狀態(tài)過濾器
Status狀態(tài)過濾器,是用于設(shè)置接口響應(yīng)狀態(tài)碼的一個(gè)過濾器。正常情況下,接口調(diào)用成功之后,都是返回200的狀態(tài)碼,我們可以通過Status過濾器,修改返回的狀態(tài)碼。
3.4、自定義網(wǎng)關(guān)過濾器
自定義網(wǎng)關(guān)過濾器,只需要編寫一個(gè)類實(shí)現(xiàn)【GatewayFilter】接口,重寫其中的方法即可。
(1)實(shí)現(xiàn)GatewayFilter接口
package com.gitee.demo.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @version 1.0.0
* @Date: 2023/4/19 21:12
* @Copyright (C) ZhuYouBin
* @Description: 自定義網(wǎng)關(guān)過濾器
*/
public class CustomGatewayFilter implements GatewayFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("執(zhí)行自定義GatewayFilter網(wǎng)關(guān)過濾器......");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
(2)配置自定義過濾器
這里通過配置類的形式將我們自定義的網(wǎng)關(guān)過濾器加入到Gateway里面。
package com.gitee.demo.config;
import com.gitee.demo.filter.CustomGatewayFilter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @version 1.0.0
* @Date: 2023/4/19 21:15
* @Copyright (C) ZhuYouBin
* @Description: Gateway 網(wǎng)關(guān)路由配置類
*/
@Configuration
public class GatewayRouteConfig {
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
// 要按照順序調(diào)用
return builder.routes().route(r -> r
.path("/**")
.uri("lb://consumer-client")
.filters(new CustomGatewayFilter())
.id("consumer-client")).build();
}
}
啟動(dòng)工程,訪問接口,查看控制臺(tái)輸出日志。
3.5、自定義全局過濾器
Gateway已經(jīng)給我們提供了一些全局過濾器,不需要配置,因?yàn)檫@些默認(rèn)的過濾器都是全局生效的,但是Gateway也允許我們自定義全局過濾器,通過自定義全局過濾器,可以實(shí)現(xiàn)一些功能,例如:統(tǒng)一鑒權(quán)、訪問限流。
(1)實(shí)現(xiàn)GlobalFilter接口
package com.gitee.demo.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @version 1.0.0
* @Date: 2023/4/19 21:24
* @Copyright (C) ZhuYouBin
* @Description: 全局過濾器
*/
// 這里通過注解將其注入 IOC 容器里面即可
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("執(zhí)行全局過濾器......");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
啟動(dòng)工程,訪問任意接口,此時(shí)都會(huì)執(zhí)行全局過濾器。
到此,Gateway動(dòng)態(tài)路由、配置路由規(guī)則就介紹完啦。文章來源:http://www.zghlxwxcb.cn/news/detail-422819.html
綜上,這篇文章結(jié)束了,主要介紹微服務(wù)組件之Gateway實(shí)現(xiàn)動(dòng)態(tài)路由、配置路由映射規(guī)則、路由過濾器。文章來源地址http://www.zghlxwxcb.cn/news/detail-422819.html
到了這里,關(guān)于【微服務(wù)筆記17】微服務(wù)組件之Gateway實(shí)現(xiàn)動(dòng)態(tài)路由、配置路由規(guī)則、路由過濾器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!