一、為什么需要服務(wù)網(wǎng)關(guān):
1、什么是服務(wù)網(wǎng)關(guān)
? ? ??傳統(tǒng)的單體架構(gòu)中只需要開放一個服務(wù)給客戶端調(diào)用,但是微服務(wù)架構(gòu)中是將一個系統(tǒng)拆分成多個微服務(wù),如果沒有網(wǎng)關(guān),客戶端只能在本地記錄每個微服務(wù)的調(diào)用地址,當(dāng)需要調(diào)用的微服務(wù)數(shù)量很多時,它需要了解每個服務(wù)的接口,這個工作量很大。那有了網(wǎng)關(guān)之后,能夠起到怎樣的改善呢?
? ? ?網(wǎng)關(guān)作為系統(tǒng)的唯一流量入口,封裝內(nèi)部系統(tǒng)的架構(gòu),所有請求都先經(jīng)過網(wǎng)關(guān),由網(wǎng)關(guān)將請求路由到合適的微服務(wù),所以,使用網(wǎng)關(guān)的好處在于: ?
(1)簡化客戶端的工作。網(wǎng)關(guān)將微服務(wù)封裝起來后,客戶端只需同網(wǎng)關(guān)交互,而不必調(diào)用各個不同服務(wù);
(2)降低函數(shù)間的耦合度。 一旦服務(wù)接口修改,只需修改網(wǎng)關(guān)的路由策略,不必修改每個調(diào)用該函數(shù)的客戶端,從而減少了程序間的耦合性
(3)解放開發(fā)人員把精力專注于業(yè)務(wù)邏輯的實(shí)現(xiàn)。由網(wǎng)關(guān)統(tǒng)一實(shí)現(xiàn)服務(wù)路由(灰度與ABTest)、負(fù)載均衡、訪問控制、流控熔斷降級等非業(yè)務(wù)相關(guān)功能,而不需要每個服務(wù) API 實(shí)現(xiàn)時都去考慮
2、網(wǎng)關(guān)的作用
- 對用戶請求做身份認(rèn)證,權(quán)限校驗(yàn)
- 將用戶請求路由到微服務(wù),并實(shí)現(xiàn)負(fù)載均衡
- 對用戶請求做限流
二、搭建網(wǎng)關(guān)服務(wù)的步驟
1、創(chuàng)建新的module,引入SpringCloudGateway的依賴和nacos的服務(wù)發(fā)現(xiàn)依賴
<!--網(wǎng)關(guān)依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<! --nacos服務(wù)發(fā)現(xiàn)依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
?2、編寫路由配置即nacos地址
server:
port: 10010 # 網(wǎng)關(guān)端口
spring:
application:
name: gateway # 服務(wù)名稱
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: # 網(wǎng)關(guān)路由配置
- id: user-service # 路由id,自定義,只要唯一即可
# uri: http://127.0.0.1:8081 # 路由的目標(biāo)地址 http就是固定地址
uri: lb://userservice # 路由的目標(biāo)地址 lb就是負(fù)載均衡,后面跟服務(wù)名稱
predicates: # 路由斷言,也就是判斷請求是否符合路由規(guī)則的條件
- Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求
我們將符合 path 規(guī)則的一切請求,都代理到 uri 參數(shù)指定的地址。
本例中,我們將?
/user/**
開頭的請求,代理到lb://userservice
,lb是負(fù)載均衡,根據(jù)服務(wù)名拉取服務(wù)列表,實(shí)現(xiàn)負(fù)載均衡。
路由配置包括:
路由id:路由的唯一標(biāo)示
路由目標(biāo)(uri):路由的目標(biāo)地址,http代表固定地址,lb代表根據(jù)服務(wù)名負(fù)載均衡
路由斷言(predicates):判斷路由的規(guī)則,
路由過濾器(filters):對請求或響應(yīng)做處理
?三、斷言工廠
?PredicateFactory的作用:
- 讀取用戶定義的斷言條件,對請求做出判斷
Path=/user/**是什么含義?
- 路徑是以/user開頭的就認(rèn)為是符合的
四、過濾器工廠
GatewayFilter是網(wǎng)關(guān)中提供的一種過濾器,可以對進(jìn)入網(wǎng)關(guān)的請求和微服務(wù)返回的響應(yīng)做處理:
?Spring提供了31種不同的路由過濾器工廠。例如:
1、請求頭過濾器
下面我們以AddRequestHeader 為例來講解。
需求:給所有進(jìn)入userservice的請求添加一個請求頭:Truth=itcast is freaking awesome!
?只需要修改gateway服務(wù)的application.yml文件,添加路由過濾即可:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
filters: # 過濾器
- AddRequestHeader=Truth, Itcast is freaking awesome! # 添加請求頭
?當(dāng)前過濾器寫在userservice路由下,因此僅僅對訪問userservice的請求有效。
2、默認(rèn)過濾器(default-filters)
如果要對所有的路由都生效,則可以將過濾器工廠寫到default下。格式如下:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
default-filters: # 默認(rèn)過濾項(xiàng)
- AddRequestHeader=Truth, Itcast is freaking awesome!
總結(jié)?
過濾器的作用
① 對路由的請求或響應(yīng)做加工處理,比如添加請求頭
② 配置在路由下的過濾器只對當(dāng)前路由的請求生效
?3、全局過濾器
需求:定義全局過濾器,攔截請求,判斷請求的參數(shù)是否滿足下面條件:
參數(shù)中是否有authorization,
authorization參數(shù)值是否為admin
如果同時滿足則放行,否則攔截
實(shí)現(xiàn):
在gateway中定義一個過濾器:
- 實(shí)現(xiàn)GlobalFilter接口
- 添加@Order注解或?qū)崿F(xiàn)Ordered接口
- 編寫處理邏輯
package cn.itcast.gateway.filters;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.獲取請求參數(shù)
MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
// 2.獲取authorization參數(shù)
String auth = params.getFirst("authorization");
// 3.校驗(yàn)
if ("admin".equals(auth)) {
// 放行
return chain.filter(exchange);
}
// 4.攔截
// 4.1.禁止訪問,設(shè)置狀態(tài)碼
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
// 4.2.結(jié)束處理
return exchange.getResponse().setComplete();
}
}
全局過濾器的作用:對所有路由都生效,并且可以自定義處理邏輯
4、過濾器執(zhí)行順序
請求進(jìn)入網(wǎng)關(guān)會碰到三類過濾器:當(dāng)前路由的過濾器、DefaultFilter、GlobalFilter
請求路由后,會將當(dāng)前路由過濾器和DefaultFilter、GlobalFilter,合并到一個過濾器鏈(集合)中,排序后依次執(zhí)行每個過濾器:文章來源:http://www.zghlxwxcb.cn/news/detail-478737.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-478737.html
?排序規(guī)則:
- 每一個過濾器都必須指定一個int類型的order值,order值越小,優(yōu)先級越高,執(zhí)行順序越靠前。
- GlobalFilter通過實(shí)現(xiàn)Ordered接口,或者添加@Order注解來指定order值,由我們自己指定
- 路由過濾器和defaultFilter的order由Spring指定,默認(rèn)是按照聲明順序從1遞增。
- 當(dāng)過濾器的order值一樣時,會按照 defaultFilter > 路由過濾器 > GlobalFilter的順序執(zhí)行。
到了這里,關(guān)于SpringCloud第三篇:GateWay服務(wù)網(wǎng)關(guān)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!