8.統(tǒng)一網(wǎng)關(guān)Gateway
網(wǎng)關(guān)功能:
- 身份認證和權(quán)限校驗
- 服務(wù)路由、負載均衡
- 請求限流
網(wǎng)關(guān)的技術(shù)實現(xiàn)
在SpringCloud中網(wǎng)關(guān)的實現(xiàn)包括兩種:
- gateway
- zuul
Zuul是基于Servlet的實現(xiàn),屬于阻塞式編程。而SpringCloudGateway則是基于Spring5中提供的WebFlux,屬于響應(yīng)式編程的實現(xiàn),具備更好的性能。
a.搭建網(wǎng)關(guān)服務(wù)
搭建網(wǎng)關(guān)服務(wù)的步驟:
1.創(chuàng)建新的module,引入SpringCloudGateway的依賴和nacos的服務(wù)發(fā)現(xiàn)依賴:
<!--nacos服務(wù)注冊發(fā)現(xiàn)依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--網(wǎng)關(guān)gateway依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2.編寫路由配置及nacos地址,在application.yml中編寫
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes:
- id: user-service # 路由標(biāo)識,必須唯一
uri: lb://userservice # 路由的目標(biāo)地址
predicates: # 路由斷言,判斷請求是否符合規(guī)則
- Path=/user/** # 路徑斷言,判斷路徑是否是以/user開頭,如果是則符合
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
b.路由斷言工廠
網(wǎng)關(guān)路由可以配置的內(nèi)容包括:
- 路由id:路由唯一標(biāo)示
- uri:路由目的地,支持lb和http兩種
- predicates:路由斷言,判斷請求是否符合要求,符合則轉(zhuǎn)發(fā)到路由目的地
- filters:路由過濾器,處理請求或響應(yīng)
路由斷言工廠Route Predicate Factory
- 我們在配置文件中寫的斷言規(guī)則只是字符串,這些字符串會被Predicate Factory讀取并處理,轉(zhuǎn)變?yōu)槁酚膳袛嗟臈l件
- 例如Path=/user/**是按照路徑匹配,這個規(guī)則是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory類來處理的
- 像這樣的斷言工廠在SpringCloudGateway還有十幾個
- PredicateFactory的作用是什么?
- 讀取用戶定義的斷言條件,對請求做出判斷
- Path=/user/**是什么含義?
- 路徑是以/user開頭的就認為是符合的
c.路由過濾器GatewayFilter
GatewayFilter是網(wǎng)關(guān)中提供的一種過濾器,可以對進入網(wǎng)關(guān)的請求和微服務(wù)返回的響應(yīng)做處理:
案例:給所有進入userservice的請求添加一個請求頭
給所有進入userservice的請求添加一個請求頭:Truth=ABCDEFGHIJKLMN
實現(xiàn)方式:在gateway中修改application.yml文件,給userservice的路由添加過濾器:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
filters: # 過濾器
- AddRequestHeader=Truth, ABCDEFGHIJKLMN # 添加請求頭
默認過濾器
如果要對所有的路由都生效,則可以將過濾器工廠寫到default下。格式如下:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
- Before=2031-01-20T17:42:47.789-07:00[Asia/Shanghai]
default-filters: # 默認過濾器,會對所有的路由請求都生效
- AddRequestHeader=Truth, ABCDEFGHIJKLMN # 添加請求頭
需要在相應(yīng)的Controller中,獲取請求頭的參數(shù)與打印
過濾器的作用是什么?
- 對路由的請求或響應(yīng)做加工處理,比如添加請求頭
- 配置在路由下的過濾器只對當(dāng)前路由的請求生效
defaultFilters的作用是什么?
- 對所有路由都生效的過濾器
d.全局過濾器GlobalFilter
全局過濾器的作用也是處理一切進入網(wǎng)關(guān)的請求和微服務(wù)響應(yīng),與GatewayFilter的作用一樣。
區(qū)別在于GatewayFilter通過配置定義,處理邏輯是固定的。而GlobalFilter的邏輯需要自己寫代碼實現(xiàn)。
案例:定義全局過濾器,攔截并判斷用戶身份
需求:定義全局過濾器,攔截請求,判斷請求的參數(shù)是否滿足下面條件:
- 參數(shù)中是否有authorization,
- authorization參數(shù)值是否為admin
如果同時滿足則放行,否則攔截
創(chuàng)建AuthorizeFilter方法實現(xiàn)GlobalFilter接口:
添加@Order注解或?qū)崿F(xiàn)Ordered接口
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.獲取請求參數(shù)
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
// 2.獲取參數(shù)中的 authorization 參數(shù)
String auth = params.getFirst("authorization");
// 3.判斷參數(shù)值是否等于 admin
if ("admin".equals(auth)){
// 4.是,放行
return chain.filter(exchange);
}
// 5.否,攔截
// 5.1.設(shè)置狀態(tài)碼
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 5.2.攔截請求
return exchange.getResponse().setComplete();
}
}
e.過濾器的執(zhí)行順序
請求進入網(wǎng)關(guān)會碰到三類過濾器:當(dāng)前路由的過濾器、DefaultFilter、GlobalFilter
請求路由后,會將當(dāng)前路由過濾器和DefaultFilter、GlobalFilter,合并到一個過濾器鏈(集合)中,排序后依次執(zhí)行每個過濾器
- 每一個過濾器都必須指定一個int類型的order值,order值越小,優(yōu)先級越高,執(zhí)行順序越靠前。
- GlobalFilter通過實現(xiàn)Ordered接口,或者添加@Order注解來指定order值,由我們自己指定
- 路由過濾器和defaultFilter的order由Spring指定,默認是按照聲明順序從1遞增。
- 當(dāng)過濾器的order值一樣時,會按照 defaultFilter > 路由過濾器 > GlobalFilter的順序執(zhí)行。
f.網(wǎng)關(guān)的cors跨域配置
跨域問題處理
跨域:域名不一致就是跨域,主要包括:
- 域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com
- 域名相同,端口不同:localhost:8080和localhost8081
跨域問題:瀏覽器禁止請求的發(fā)起者與服務(wù)端發(fā)生跨域ajax請求,請求被瀏覽器攔截的問題
解決方案:CORS文章來源:http://www.zghlxwxcb.cn/news/detail-679539.html
網(wǎng)關(guān)處理跨域采用的同樣是CORS方案,并且只需要簡單配置即可實現(xiàn):文章來源地址http://www.zghlxwxcb.cn/news/detail-679539.html
spring:
cloud:
gateway:
globalcors: # 全局的跨域處理
add-to-simple-url-handler-mapping: true # 解決options請求被攔截問題
corsConfigurations:
'[/**]':
allowedOrigins: # 允許哪些網(wǎng)站的跨域請求
- "http://localhost:8090"
- "http://www.leyou.com"
allowedMethods: # 允許的跨域ajax的請求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允許在請求中攜帶的頭信息
allowCredentials: true # 是否允許攜帶cookie
maxAge: 360000 # 這次跨域檢測的有效期
到了這里,關(guān)于微服務(wù)中間件--統(tǒng)一網(wǎng)關(guān)Gateway的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!