提示:以下是本篇文章正文內(nèi)容,SpringCloud 系列學(xué)習(xí)將會(huì)持續(xù)更新
Gateway 路由網(wǎng)關(guān)
官網(wǎng)地址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/
說到路由,想必各位一定最先想到的就是家里的路由器了,那么我們家里的路由器充當(dāng)?shù)氖且粋€(gè)什么角色呢?
我們知道,如果我們需要連接互聯(lián)網(wǎng),那么就需要將手機(jī)或是電腦連接到家里的路由器才可以,而路由器則連接光貓,光貓?jiān)偻ㄟ^光纖連接到互聯(lián)網(wǎng),也就是說,互聯(lián)網(wǎng)方向發(fā)送過來的數(shù)據(jù),需要經(jīng)過路由器才能到達(dá)我們的設(shè)備。而路由器充當(dāng)?shù)木褪菙?shù)據(jù)包中轉(zhuǎn)站,所有的局域網(wǎng)設(shè)備都無法直接與互聯(lián)網(wǎng)連接,而是需要經(jīng)過路由器進(jìn)行中轉(zhuǎn),我們一般說路由器下的網(wǎng)絡(luò)是內(nèi)網(wǎng),而互聯(lián)網(wǎng)那一端是外網(wǎng)。
我們的局域網(wǎng)設(shè)備,無法被互聯(lián)網(wǎng)上的其他設(shè)備直接訪問,肯定是能夠保證到安全性的。并且互聯(lián)網(wǎng)發(fā)送過來的數(shù)據(jù),需要經(jīng)過路由器進(jìn)行解析,識(shí)別到底是哪一個(gè)設(shè)備的數(shù)據(jù)包,然后再發(fā)送給對(duì)應(yīng)的設(shè)備。
而我們的微服務(wù)也是這樣,一般情況下,可能并不是所有的微服務(wù)都需要直接暴露給外部調(diào)用,這時(shí)我們就可以使用路由機(jī)制,添加一層防護(hù),讓所有的請(qǐng)求全部通過路由來轉(zhuǎn)發(fā)到各個(gè)微服務(wù),并且轉(zhuǎn)發(fā)給多個(gè)相同微服務(wù)實(shí)例也可以實(shí)現(xiàn)負(fù)載均衡。
在之前,路由的實(shí)現(xiàn)一般使用 Zuul,但是已經(jīng)停更,而現(xiàn)在新出現(xiàn)了由 SpringCloud 官方開發(fā)的Gateway 路由,它相比 Zuul 不僅性能上得到了一定的提升,并且是官方推出,契合性也會(huì)更好,所以我們這里就主要講解 Gateway。
回到目錄…
一、部署網(wǎng)關(guān)
??①添加依賴
現(xiàn)在我們來創(chuàng)建一個(gè)新的項(xiàng)目 gateway-server,作為我們的網(wǎng)關(guān),這里需要添加兩個(gè)依賴:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
第一個(gè)依賴就是網(wǎng)關(guān)的依賴,而第二個(gè)則跟其他微服務(wù)一樣,需要注冊(cè)到 Eureka 才能生效,注意不要添加 Web 依賴,使用的是 WebFlux
框架。
??②設(shè)置配置文件
我們來完善一下配置文件:設(shè)置端口、注冊(cè)到 Eureka 中
server:
port: 8500
eureka:
client:
service-url:
defaultZone: http://localhost:8801/eureka, http://localhost:8802/eureka
spring:
application:
name: gateway
??③創(chuàng)建啟動(dòng)類
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
現(xiàn)在就可以啟動(dòng)了:
??④路由功能配置
現(xiàn)在還沒有配置任何的路由功能,我們接著將路由功能進(jìn)行配置,給剛剛的配置文件添加配置項(xiàng):
spring:
application:
name: gateway
cloud:
gateway:
routes: # 配置路由,注意這里是個(gè)列表,每一項(xiàng)都包含了很多信息
- id: borrow-service # 路由名稱
uri: lb://borrowservice # 路由的地址,lb表示使用負(fù)載均衡到微服務(wù),也可以使用 http 正常轉(zhuǎn)發(fā)
predicates: # 路由規(guī)則,斷言什么請(qǐng)求會(huì)被路由
- Path=/borrow/** # 只要是訪問的這個(gè)路徑,一律都被路由到上面指定的服務(wù)
路由規(guī)則的詳細(xì)列表(斷言工廠列表)在這里:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories,可以指定多種類型,包括指定時(shí)間段、Cookie 攜帶情況、Header 攜帶情況、訪問的域名地址、訪問的方法、路徑、參數(shù)、訪問者IP 等。也可以使用配置類進(jìn)行配置,但是還是推薦直接配置文件,省事。
??⑤路由訪問服務(wù)
此時(shí)依然可以通過原有的服務(wù)地址進(jìn)行訪問:http://localhost:8082/borrow/2
我們現(xiàn)在也可以直接通過路由來訪問我們的服務(wù)了:http://localhost:8500/borrow/2
這樣我們就可以將不需要外網(wǎng)直接訪問的微服務(wù)全部放到內(nèi)網(wǎng)環(huán)境下,而只依靠網(wǎng)關(guān)來對(duì)外進(jìn)行交涉。
回到目錄…
二、路由過濾器
2.1 單個(gè)過濾器: 配置文件
路由過濾器支持以某種方式修改傳入的 HTTP 請(qǐng)求或傳出的 HTTP 響應(yīng),路由過濾器的范圍是某一個(gè)路由,跟之前的斷言一樣,Spring Cloud Gateway 也包含許多內(nèi)置的路由過濾器工廠。
詳細(xì)列表:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
比如,我們現(xiàn)在希望在請(qǐng)求到達(dá)時(shí),在請(qǐng)求頭中添加一些信息再轉(zhuǎn)發(fā)給我們的服務(wù),那么這個(gè)時(shí)候就可以使用路由過濾器來完成,我們只需要對(duì)配置文件進(jìn)行修改:
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: borrow-service
uri: lb://borrowservice
predicates:
- Path=/borrow/**
# 繼續(xù)添加新的路由配置,這里就以書籍管理服務(wù)為例
- id: book-service
uri: lb://bookservice
predicates:
- Path=/book/**
filters: # 添加過濾器
- AddRequestHeader=Test, HelloBook!
# AddRequestHeader 就是添加請(qǐng)求頭信息,其他工廠請(qǐng)查閱官網(wǎng)
接著我們?cè)?BookController 中打印一下請(qǐng)求頭的日志,看看是不是成功添加了:
@Slf4j
@RestController
public class BookController {
@Resource
private BookService bookService;
@GetMapping("/book/{bid}")
public Book findBookById(@PathVariable("bid") int bid, HttpServletRequest req) {
log.info("book-service 的請(qǐng)求頭: " + req.getHeader("Test"));
return bookService.getBookById(bid);
}
}
??當(dāng)我們不通過 Gateway 訪問我們的圖書管理服務(wù)時(shí):就沒有請(qǐng)求頭。
??現(xiàn)在我們通過 Gateway 訪問我們的圖書管理服務(wù)時(shí):就成功獲取到網(wǎng)關(guān)添加的請(qǐng)求頭了。
回到目錄…
2.2 全局過濾器: 自定義類
除了針對(duì)于某一個(gè)路由配置過濾器之外,我們也可以自定義全局過濾器,它能夠作用于全局。
比如我們要實(shí)現(xiàn)攔截沒有攜帶指定請(qǐng)求參數(shù)的請(qǐng)求:
①自定義全局過濾器類,實(shí)現(xiàn) GlobalFilter
接口,重寫 filter()
方法,實(shí)現(xiàn)具體過濾策略。
@Slf4j
@Component // 需要注冊(cè)為Bean
public class TestFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 先獲取 ServerHttpRequest 對(duì)象,注意不是 HttpServletRequest
ServerHttpRequest request = exchange.getRequest();
// 打印一下所有的請(qǐng)求參數(shù)
log.info("請(qǐng)求參數(shù): " + request.getQueryParams());
// 判斷是否包含 val 參數(shù),且參數(shù)值為 1
List<String> value = request.getQueryParams().get("val");
if(value != null && value.contains("1")) {
// 將 ServerWebExchange 向過濾鏈的下一級(jí)傳遞(跟 JavaWeb 中介紹的過濾器其實(shí)是差不多的)
return chain.filter(exchange);
}else {
// 直接在這里攔截,然后返回響應(yīng)
return exchange.getResponse().setComplete();
}
}
}
可以看到結(jié)果:成功實(shí)現(xiàn)規(guī)則判斷和攔截操作。
②當(dāng)然,過濾器肯定是可以存在很多個(gè)的,所以我們可以手動(dòng)指定過濾器之間的順序:
- Order 的值越小,優(yōu)先級(jí)越高。
- 無論是在配置文件中的單個(gè)路由過濾器,還是全局路由過濾器,都會(huì)受到 Order 值影響。
(單個(gè)路由的過濾器 Order 值按從上往下的順序從1開始遞增)。 - 最終是按照 Order 值決定哪個(gè)過濾器優(yōu)先執(zhí)行,當(dāng) Order 值一樣時(shí),全局路由過濾器執(zhí)行
優(yōu)于
單獨(dú)的路由過濾器執(zhí)行。
配置文件中的單個(gè)路由過濾器 Order 值:
filters: # 過濾器
- AddRequestHeader=Test, HelloBook! # Order = 1
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue # Order = 2
- AddRequestParameter=red, blue # Order = 3
全局路由過濾器指定 Order 值: 實(shí)現(xiàn) Ordered
接口,默認(rèn)為 0
@Component
public class TestFilter implements GlobalFilter, Ordered { // 實(shí)現(xiàn) Ordered 接口
@Override
public int getOrder() {
return 0;
}
}
回到目錄…文章來源:http://www.zghlxwxcb.cn/news/detail-737480.html
總結(jié):
提示:這里對(duì)文章進(jìn)行總結(jié):
本文是對(duì)SpringCloud的學(xué)習(xí),學(xué)習(xí)了部署 Gateway路由網(wǎng)關(guān),并且在配置文件中設(shè)置單個(gè)路由過濾器,以及通過自定義類實(shí)現(xiàn)全局過濾器的方法。之后的學(xué)習(xí)內(nèi)容將持續(xù)更新!?。?/font>文章來源地址http://www.zghlxwxcb.cn/news/detail-737480.html
到了這里,關(guān)于SpringCloud之 Gateway路由網(wǎng)關(guān)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!