SpringCloud第十三篇:Spring Cloud Gateway服務(wù)化和過濾器

1. 注冊(cè)中心

1.1 準(zhǔn)備服務(wù)和注冊(cè)中心

上篇主要講解了網(wǎng)關(guān)代理單個(gè)服務(wù)的使用語法,在實(shí)際的工作中,服務(wù)的相互調(diào)用都是依賴于服務(wù)中心提供的入口來使用,服務(wù)中心往往注冊(cè)了很多服務(wù),如果每個(gè)服務(wù)都需要單獨(dú)配置的話,這將是一份很枯燥的工作。Spring Cloud Gateway 提供了一種默認(rèn)轉(zhuǎn)發(fā)的能力,只要將 Spring Cloud Gateway 注冊(cè)到服務(wù)中心,Spring Cloud Gateway 默認(rèn)就會(huì)代理服務(wù)中心的所有服務(wù),下面用代碼演示。(了解源碼可+求求: 1791743380)

在介紹Zuul的時(shí)候,我們用到了Eureka和producer,本次演示還是需要他們兩個(gè),將他們兩個(gè)CV過來。

1.2 服務(wù)網(wǎng)關(guān)注冊(cè)到注冊(cè)中心

上一篇用到的gateway也CV過來,在依賴文件里面加入:

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

添加對(duì)eureka的依賴,在啟動(dòng)文件加入注解@EnableEurekaClient。

修改配置文件application.yml:

server:? port:8080spring:? application:? ? name:api-gateway? cloud:? ? gateway:? ? ? discovery:? ? ? ? locator:? ? ? ? ? enabled:trueeureka:? client:? ? service-url:? ? ? defaultZone:http://localhost:8761/eureka/logging:? level:org.springframework.cloud.gateway:debug

配置說明:

spring.cloud.gateway.discovery.locator.enabled:是否與服務(wù)注冊(cè)于發(fā)現(xiàn)組件進(jìn)行結(jié)合,通過 serviceId 轉(zhuǎn)發(fā)到具體的服務(wù)實(shí)例。默認(rèn)為 false,設(shè)為 true 便開啟通過服務(wù)中心的自動(dòng)根據(jù) serviceId 創(chuàng)建路由的功能。

eureka.client.service-url.defaultZone指定注冊(cè)中心的地址,以便使用服務(wù)發(fā)現(xiàn)功能

logging.level.org.springframework.cloud.gateway 調(diào)整相 gateway 包的 log 級(jí)別,以便排查問題

修改完成后啟動(dòng) gateway 項(xiàng)目,訪問注冊(cè)中心地址?http://localhost:8761/?即可看到名為 API-GATEWAY的服務(wù)。

1.3 測試

將 gateway 注冊(cè)到服務(wù)中心之后,網(wǎng)關(guān)會(huì)自動(dòng)代理所有的在注冊(cè)中心的服務(wù),訪問這些服務(wù)的語法為:

http://網(wǎng)關(guān)地址:端口/服務(wù)中心注冊(cè) serviceId/具體的url

比如我們的 producer 項(xiàng)目有一個(gè) /hello 的服務(wù),訪問此服務(wù)的時(shí)候會(huì)返回:"hello "+name+",producer is ready"。

比如訪問地址:http://localhost:8081/hello?name=spring,頁面返回:hello?spring,producer is ready。

按照上面的語法我們通過網(wǎng)關(guān)來訪問,瀏覽器輸入:http://localhost:8080/SPRING-CLOUD-PRODUCER/hello?name=spring?同樣返回:hello spring,producer is ready。證明服務(wù)網(wǎng)關(guān)轉(zhuǎn)發(fā)成功。

我們將項(xiàng)目 producer 復(fù)制一份為 producer1,將/hello服務(wù)的返回值修改為 hello spring,producer1 is ready。修改端口號(hào)為 8082 ,修完完成后重啟,這時(shí)候訪問注冊(cè)中心后臺(tái)會(huì)發(fā)現(xiàn)有兩個(gè)名為 SPRING-CLOUD-PRODUCER的服務(wù)。

在瀏覽器多次訪問地址:http://localhost:8888/SPRING-CLOUD-PRODUCER/hello,頁面交替返回以下信息

hello spring,producer is ready。

hello spring,producer1 is ready。

說明后端服務(wù)自動(dòng)進(jìn)行了均衡負(fù)載。

2. 基于 Filter(過濾器) 實(shí)現(xiàn)的高級(jí)功能

在Zuul高級(jí)篇中大概介紹過 Filter 的概念。

Spring Cloud Gateway 的 Filter 的生命周期不像 Zuul 的那么豐富,它只有兩個(gè):“pre” 和 “post”。

PRE: 這種過濾器在請(qǐng)求被路由之前調(diào)用。我們可利用這種過濾器實(shí)現(xiàn)身份驗(yàn)證、在集群中選擇請(qǐng)求的微服務(wù)、記錄調(diào)試信息等。

POST:這種過濾器在路由到微服務(wù)以后執(zhí)行。這種過濾器可用來為響應(yīng)添加標(biāo)準(zhǔn)的 HTTP Header、收集統(tǒng)計(jì)信息和指標(biāo)、將響應(yīng)從微服務(wù)發(fā)送給客戶端等。

Spring Cloud Gateway 的 Filter 分為兩種:GatewayFilter 與 GlobalFilter。GlobalFilter 會(huì)應(yīng)用到所有的路由上,而 GatewayFilter 將應(yīng)用到單個(gè)路由或者一個(gè)分組的路由上。

Spring Cloud Gateway 內(nèi)置了9種 GlobalFilter,比如 Netty Routing Filter、LoadBalancerClient Filter、Websocket Routing Filter 等,根據(jù)名字即可猜測出這些 Filter 的作者。

利用 GatewayFilter 可以修改請(qǐng)求的 Http 的請(qǐng)求或者響應(yīng),或者根據(jù)請(qǐng)求或者響應(yīng)做一些特殊的限制。 更多時(shí)候我們會(huì)利用 GatewayFilter 做一些具體的路由配置,下面我們做一些簡單的介紹。

2.1 快速上手 Filter 使用

我們以 AddRequestParameter GatewayFilter 來演示一下,如何在項(xiàng)目中使用 GatewayFilter,AddRequestParameter GatewayFilter 可以在請(qǐng)求中添加指定參數(shù)。

2.1.1 配置application.yml示例

server:? port:8080spring:? application:? ? name:api-gateway? cloud:? ? gateway:? ? ? discovery:? ? ? ? locator:? ? ? ? ? enabled:true? ? ? routes:? ? ? ? - id:add_request_parameter_route? ? ? ? ? uri:http://localhost:8081? ? ? ? ? filters:? ? ? ? ? ? -AddRequestParameter=foo,bar? ? ? ? ? predicates:? ? ? ? ? ? -Method=GETeureka:? client:? ? service-url:? ? ? defaultZone:http://localhost:8761/eureka/logging:? level:org.springframework.cloud.gateway:debug

這里的 routes 手動(dòng)指定了服務(wù)的轉(zhuǎn)發(fā)地址,設(shè)置所有的 GET 方法都會(huì)自動(dòng)添加foo=bar,http://localhost:8081?是 producer 項(xiàng)目,我們?cè)诖隧?xiàng)目中添加一個(gè) foo() 方法,用來接收轉(zhuǎn)發(fā)中添加的參數(shù) foo。

@RequestMapping("/foo")publicStringfoo(String foo){return"hello "+foo+"!";}

修改完成后重啟 gateway、producer 項(xiàng)目。訪問地址?http://localhost:8081/foo?頁面返回:hello null!,說明并沒有接受到參數(shù) foo;通過網(wǎng)關(guān)來調(diào)用此服務(wù),瀏覽器訪問地址?http://localhost:8080/foo?頁面返回:hello bar!,說明成功接收到參數(shù) foo 參數(shù)的值 bar ,證明網(wǎng)關(guān)在轉(zhuǎn)發(fā)的過程中已經(jīng)通過 filter 添加了設(shè)置的參數(shù)和值。

2.2 服務(wù)化路由轉(zhuǎn)發(fā)

面我們使用 uri 指定了一個(gè)服務(wù)轉(zhuǎn)發(fā)地址,單個(gè)服務(wù)這樣使用問題不大,但是我們?cè)谧?cè)中心往往會(huì)使用多個(gè)服務(wù)來共同支撐整個(gè)服務(wù)的使用,這個(gè)時(shí)候我們就期望可以將 Filter 作用到每個(gè)應(yīng)用的實(shí)例上,spring cloud gateway 工了這樣的功能,只需要簡單配置即可。

為了測試兩個(gè)服務(wù)提供者是否都被調(diào)用,我們?cè)?producer1 項(xiàng)目中也同樣添加 foo() 方法。

@RequestMapping("/foo")publicStringfoo(String foo){return"hello "+foo+"!@@@@";}

為了和 producer 中 foo() 方法有所區(qū)別,這里使用了多加了4個(gè)@。同時(shí)將 gateway 項(xiàng)目配置文件中的 uri 內(nèi)容修改如下:

#格式為:lb://應(yīng)用注冊(cè)服務(wù)名uri: lb://spring-cloud-producer

修改完之后,重新啟動(dòng)項(xiàng)目 gateway、producer1,瀏覽器訪問地址:?http://localhost:8080/foo?頁面交替出現(xiàn):

hello bar!

hello bar!@@@@

證明請(qǐng)求依據(jù)均勻轉(zhuǎn)發(fā)到后端服務(wù),并且后端服務(wù)均接收到了 filter 增加的參數(shù) foo 值。

這里其實(shí)默認(rèn)使用了全局過濾器 LoadBalancerClient ,當(dāng)路由配置中 uri 所用的協(xié)議為 lb 時(shí)(以u(píng)ri: lb://spring-cloud-producer為例),gateway 將使用 LoadBalancerClient 把 producer 通過 eureka 解析為實(shí)際的主機(jī)和端口,并進(jìn)行負(fù)載均衡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容