0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

網(wǎng)關(guān)GateWay的基本概念和使用詳解

jf_ro2CN3Fa ? 來源:CSDN-流水武qin ? 2023-08-08 09:39 ? 次閱讀

一、網(wǎng)關(guān)的基本概念

SpringCloudGateway網(wǎng)關(guān)是所有微服務(wù)的統(tǒng)一入口。

1.1 它的主要作用是:

反向代理(請(qǐng)求的轉(zhuǎn)發(fā))

路由和負(fù)載均衡

身份認(rèn)證和權(quán)限控制

對(duì)請(qǐng)求限流

1.2 相比于Zuul的優(yōu)勢(shì):

SpringCloudGateway基于Spring5中提供的WebFlux,是一種響應(yīng)式編程的實(shí)現(xiàn),性能更加優(yōu)越。

Zuul的實(shí)現(xiàn)方式比較老式,基于Servlet的實(shí)現(xiàn),它是一種阻塞式編程,在高并發(fā)下性能性能不佳。

拓展:

其實(shí)Nginx也可以作為網(wǎng)關(guān),但是要使用Nginx自主實(shí)現(xiàn)網(wǎng)關(guān)的相關(guān)功能,還需要借助lua腳本語言,學(xué)習(xí)成本是比較高的,現(xiàn)在一般也不會(huì)使用它來做網(wǎng)關(guān),但是只按性能來講Nginx,性能是最高的。

1.3 SpringCloudGateway架構(gòu)圖:

c472cb74-358b-11ee-9e74-dac502259ad0.png

微服務(wù)只接收來自網(wǎng)關(guān)的請(qǐng)求,而其它直接訪問微服務(wù)本身的請(qǐng)求拒絕。

這樣可以極大保護(hù)微服務(wù)免受不法侵害。

同時(shí)在請(qǐng)求壓力激增時(shí),可以實(shí)施服務(wù)限流,保護(hù)微服務(wù)集群。

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

二、SpringBoot中配置GateWay

2.1 引入GateWay的Maven依賴

 

org.springframework.cloud
spring-cloud-starter-gateway

 

com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery

2.2 配置application.yml文件

server:
port:10086#網(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)地址(直接寫死地址的方式,不推薦)
uri:lb://userservice#路由的目標(biāo)地址lb是負(fù)載均衡,后面跟服務(wù)名稱(推薦)
predicates:#路由斷言,判斷請(qǐng)求是否符合路由規(guī)則的條件
-Path=/user/**#按照路徑匹配,以/user/開頭的請(qǐng)求就符合要求
-id:card-service
uri:lb://cardservice
predicates:
-Path=/card/**

gateway配置中的注意點(diǎn):

1.routes 后面的路由可以配置多個(gè),相當(dāng)于配置個(gè)數(shù)組,一個(gè)-開頭的配置就是其中的一個(gè)數(shù)組元素。

2.uri為什么選擇以服務(wù)名+負(fù)載均衡的方式?

主要是寫死地址的話,今后如果userservice的地址變了,那么又要去修改yml配置文件。而lb://userservice可以讓程序員一眼認(rèn)出這是哪個(gè)微服務(wù),以后地址變了也無需修改yml配置文件。

上述配置詳解:

將 /user/**開頭的請(qǐng)求,代理到lb://userservice。

將 /card/**開頭的請(qǐng)求,代理到lb://cardservice。

lb是負(fù)載均衡,根據(jù)服務(wù)名拉取服務(wù)列表,實(shí)現(xiàn)負(fù)載均衡。

http://127.0.0.1:10086/user/99 就算是/user/**開頭的請(qǐng)求,不要把協(xié)議、ip和端口計(jì)算在內(nèi)。

有多少個(gè)需要配置的路由,都按上面的格式配置即可

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

三、GateWay路由配置詳解

路由主要有四個(gè)配置:

路由id(id)

路由目標(biāo)(uri)

路由斷言(predicates):判斷路由的規(guī)則,

路由過濾器(filters):對(duì)請(qǐng)求或響應(yīng)做處理

3.1 路由id

當(dāng)前路由的唯一標(biāo)識(shí)。

3.2 路由目標(biāo)

路由的目標(biāo)地址,http代表固定地址,lb代表根據(jù)服務(wù)名負(fù)載均衡。

一般都不會(huì)選擇寫死http固定地址的方式。而是選擇可維護(hù)性更強(qiáng)的lb根據(jù)服務(wù)名負(fù)載均衡的方式。

具體優(yōu)勢(shì)如上所言。

3.3 路由斷言

路由斷言主要用來判斷路由的規(guī)則。

配置文件中寫的斷言規(guī)則只是字符串,這些字符串會(huì)被Predicate Factory讀取并處理。

例如Path=/user/**是按照路徑匹配,這個(gè)規(guī)則是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory類來處理。

像這樣的斷言工廠在SpringCloudGateway還有十幾個(gè):

名稱 說明 示例
After 是某個(gè)時(shí)間點(diǎn)后的請(qǐng)求 - After=2022-01-20T1427.789-07:00[Asia/Shanghai]
Before 是某個(gè)時(shí)間點(diǎn)之前的請(qǐng)求 - Before=2022-04-13T1547.433+08:00[Asia/Shanghai]
Between 是某兩個(gè)時(shí)間點(diǎn)之前的請(qǐng)求 - Between=2021-01-20T1747.789-07:00[Asia/Shanghai], 2023-01-21T1747.789-07:00[Asia/Shanghai]
Cookie 請(qǐng)求必須包含某些cookie - Cookie=chocolate
Header 請(qǐng)求必須包含某些header - Header=asd, cas
Host 請(qǐng)求必須是訪問某個(gè)host(域名) - Host=baidu.com, jd.com
Method 請(qǐng)求方式必須是指定方式 - Method=GET,POST
Path 請(qǐng)求路徑必須符合指定規(guī)則 - Path=/user/{params},/card/**
Query 請(qǐng)求參數(shù)必須包含指定參數(shù) - Query=name, Jack
RemoteAddr 請(qǐng)求者的ip必須是指定范圍 - RemoteAddr=192.168.1.1/24
Weight 權(quán)重處理

實(shí)際使用時(shí),根絕業(yè)務(wù)要求選擇使用即可。

不過一般來講,最常用的是使用Path這種斷言工廠,僅用它就能滿足常見的需求了。

關(guān)于Path斷言工廠的補(bǔ)充:

Path=/card/**代表 以/card/路徑開頭的多級(jí)路徑請(qǐng)求,這么寫多級(jí)路徑請(qǐng)求和一級(jí)路徑請(qǐng)求都生效。

Path=/card/*代表 以/card/路徑開頭的一級(jí)路徑請(qǐng)求,這么寫多級(jí)路徑請(qǐng)求將不會(huì)生效。

今后如果有復(fù)雜的斷言工廠配置,可以參照官網(wǎng)文檔上的例子去實(shí)現(xiàn)。

3.4 路由過濾器(filters)

路由過濾器對(duì)請(qǐng)求或響應(yīng)做處理。

c48d02fa-358b-11ee-9e74-dac502259ad0.png

客戶端請(qǐng)求先找到路由,路由匹配時(shí)經(jīng)過過濾器層層篩選,最終訪問到微服務(wù)。

當(dāng)然微服務(wù)的請(qǐng)求反悔時(shí),也會(huì)經(jīng)過過濾器的篩選,只不過我們一般只對(duì)請(qǐng)求過濾,而不會(huì)對(duì)響應(yīng)過濾。

SpringCloudGateWay目前已經(jīng)提供了34種不同的過濾器工廠。

常用的幾個(gè)有:

名稱 說明
AddRequestHeader 給當(dāng)前請(qǐng)求添加一個(gè)請(qǐng)求頭
RemoveRequestHeader 移除請(qǐng)求中的一個(gè)請(qǐng)求頭
AddResponseHeader 給響應(yīng)結(jié)果中添加一個(gè)響應(yīng)頭
RemoveResponseHeader 從響應(yīng)結(jié)果中移除有一個(gè)響應(yīng)頭
RequestRateLimiter 限制請(qǐng)求的流量

3.4.1 請(qǐng)求頭過濾器配置示例(局部過濾器)

spring:
cloud:
gateway:
routes:
-id:user-service
uri:lb://userservice
predicates:
-Path=/user/**
filters:#過濾器配置
-AddRequestHeader=token,test#添加請(qǐng)求頭

上述過濾器的含義:

給所有進(jìn)入userservice的請(qǐng)求添加一個(gè)請(qǐng)求頭。

請(qǐng)求頭的key為token,value為test。

由于當(dāng)前前過濾器寫在微服務(wù)的userservice路由下,因此僅僅對(duì)訪問微服務(wù)userservice的請(qǐng)求有效。

3.4.2 默認(rèn)過濾器配置示例(全局過濾器)

spring:
cloud:
gateway:
routes:
-id:user-service
uri:lb://userservice
predicates:
-Path=/user/**
default-filters:#默認(rèn)過濾器配置
-AddRequestHeader=token,test#添加請(qǐng)求頭

default-filters的配置和routes平級(jí)。

只要配置在default-filters下面的過濾器,會(huì)對(duì)routes配置的所有路由都生效。

過濾器工廠官方文檔:

今后如果有復(fù)雜的斷言工廠配置,可以參照官網(wǎng)文檔上的例子去實(shí)現(xiàn)。

四、自定義全局路由過濾器

有時(shí)候SpringCloudGateWay提供的過濾器工廠不能滿足自己的要求。

可能有時(shí)候需要在過濾時(shí)做一些其它的邏輯操作。

那么這時(shí)候可以選擇使用java代碼自定義全局過濾器。

代碼示例:

@Component
publicclassGateWayFilterimplementsGlobalFilter,Ordered{

@Override
publicMonofilter(ServerWebExchangeexchange,GatewayFilterChainchain){

//1.獲取請(qǐng)求參數(shù)
//1.這里的request并不是servlet中的request
//2.返回值是一個(gè)多鍵的map集合、也就是說這個(gè)map集合的鍵可以重復(fù)
MultiValueMapparams=exchange.getRequest().getQueryParams();
//2.獲取userName參數(shù)
StringuserName=params.getFirst("userName");
//3.校驗(yàn)
if("root".equals(userName)){
//放行
returnchain.filter(exchange);
}
//4.攔截
//4.1.禁止訪問,設(shè)置狀態(tài)碼
exchange.getResponse().setStatusCode(500);
//4.2.結(jié)束處理
returnexchange.getResponse().setComplete();
}

@Override
publicintgetOrder(){
return-1;
}
}

當(dāng)有多個(gè)過濾器時(shí),Order的值決定了過濾器的執(zhí)行順序。

數(shù)值越大優(yōu)先級(jí)越低, 負(fù)的越多, 優(yōu)先級(jí)越高。

設(shè)置Order的值有兩種方式:

1. 實(shí)現(xiàn)Ordered接口,并且重寫getOrder方法

@Component
publicclassGateWayFilterimplementsGlobalFilter,Ordered{

@Override
publicMonofilter(ServerWebExchangeexchange,GatewayFilterChainchain){

}

@Override
publicintgetOrder(){
return-1;
}
}

2. 使用@Order注解

@Order(-1)
@Component
publicclassGateWayFilterimplementsGlobalFilter,Ordered{
@Override
publicMonofilter(ServerWebExchangeexchange,GatewayFilterChainchain){

}
}

五、過濾路由過濾器的執(zhí)行順序

5.1 過濾器的種類

SpringCloudGateWay中,有三種過濾器:

默認(rèn)過濾器default-filters

只對(duì)具體某個(gè)路由生效的局部過濾器filters

使用java代碼編寫的全局過濾器GlobalFilter

5.2 過濾器的執(zhí)行順序

c4afba7a-358b-11ee-9e74-dac502259ad0.png

由上圖知過濾器的執(zhí)行順序?yàn)椋耗J(rèn)過濾器 → 當(dāng)前路由過濾器 → 全局過濾器。

六、網(wǎng)關(guān)的跨域問題

6.1 跨域的概念和原理

跨域:請(qǐng)求位置和被請(qǐng)求位置不同源就會(huì)發(fā)生跨域。

這里的不同源包括兩個(gè)點(diǎn):

域名不同:www.baidu.com 和 www.taobao.com。(IP不同也是相同道理)

端口不同:127.0.0.1:8080和127.0.0.1:8081。

而瀏覽器又會(huì)禁止請(qǐng)求的發(fā)起者與服務(wù)端發(fā)生跨域AJAX請(qǐng)求。

如果發(fā)生了跨域請(qǐng)求,服務(wù)器端是能夠正常響應(yīng)的,但是響應(yīng)的結(jié)果會(huì)被瀏覽器攔截。

6.2 跨域常見解決方案

使用CORS方式。

CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)。

它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest請(qǐng)求,從而克服了AJAX只能同源使用的限制。

6.3 gateway中如何解決跨域問題

方式一:配置application.yml文件:

spring:
cloud:
gateway:
globalcors:#全局的跨域配置
add-to-simple-url-handler-mapping:true#解決options請(qǐng)求被攔截問題
#options請(qǐng)求就是一種詢問服務(wù)器是否瀏覽器可以跨域的請(qǐng)求
#如果每次跨域都有詢問服務(wù)器是否瀏覽器可以跨域?qū)π阅芤彩菗p耗
#可以配置本次跨域檢測(cè)的有效期maxAge
#在maxAge設(shè)置的時(shí)間范圍內(nèi),不去詢問,統(tǒng)統(tǒng)允許跨域
corsConfigurations:
'[/**]':
allowedOrigins:#允許哪些網(wǎng)站的跨域請(qǐng)求
-"http://localhost:8090"
allowedMethods:#允許的跨域ajax的請(qǐng)求方式
-"GET"
-"POST"
-"DELETE"
-"PUT"
-"OPTIONS"
allowedHeaders:"*"#允許在請(qǐng)求中攜帶的頭信息
allowCredentials:true#允許在請(qǐng)求中攜帶cookie
maxAge:360000#本次跨域檢測(cè)的有效期(單位毫秒)
#有效期內(nèi),跨域請(qǐng)求不會(huì)一直發(fā)option請(qǐng)求去增大服務(wù)器壓力

方式二:使用編碼方式定義配置類:

importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.http.HttpHeaders;
importorg.springframework.http.HttpMethod;
importorg.springframework.http.HttpStatus;
importorg.springframework.http.server.reactive.ServerHttpRequest;
importorg.springframework.http.server.reactive.ServerHttpResponse;
importorg.springframework.web.cors.reactive.CorsUtils;
importorg.springframework.web.server.ServerWebExchange;
importorg.springframework.web.server.WebFilter;
importorg.springframework.web.server.WebFilterChain;
importreactor.core.publisher.Mono;

@Configuration
publicclassCorsConfig{
privatestaticfinalStringMAX_AGE="18000L";

@Bean
publicWebFiltercorsFilter(){
return(ServerWebExchangectx,WebFilterChainchain)->{
ServerHttpRequestrequest=ctx.getRequest();
//使用SpringMvc自帶的跨域檢測(cè)工具類判斷當(dāng)前請(qǐng)求是否跨域
if(!CorsUtils.isCorsRequest(request)){
returnchain.filter(ctx);
}
HttpHeadersrequestHeaders=request.getHeaders();//獲取請(qǐng)求頭
ServerHttpResponseresponse=ctx.getResponse();//獲取響應(yīng)對(duì)象
HttpMethodrequestMethod=requestHeaders.getAccessControlRequestMethod();//獲取請(qǐng)求方式對(duì)象
HttpHeadersheaders=response.getHeaders();//獲取響應(yīng)頭
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN,requestHeaders.getOrigin());//把請(qǐng)求頭中的請(qǐng)求源(協(xié)議+ip+端口)添加到響應(yīng)頭中(相當(dāng)于yml中的allowedOrigins)
headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,requestHeaders.getAccessControlRequestHeaders());
if(requestMethod!=null){
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,requestMethod.name());//允許被響應(yīng)的方法(GET/POST等,相當(dāng)于yml中的allowedMethods)
}
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS,"true");//允許在請(qǐng)求中攜帶cookie(相當(dāng)于yml中的allowCredentials)
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,"*");//允許在請(qǐng)求中攜帶的頭信息(相當(dāng)于yml中的allowedHeaders)
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE,MAX_AGE);//本次跨域檢測(cè)的有效期(單位毫秒,相當(dāng)于yml中的maxAge)
if(request.getMethod()==HttpMethod.OPTIONS){//直接給option請(qǐng)求反回結(jié)果
response.setStatusCode(HttpStatus.OK);
returnMono.empty();
}
returnchain.filter(ctx);//不是option請(qǐng)求則放行
};
}

}

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 網(wǎng)關(guān)
    +關(guān)注

    關(guān)注

    9

    文章

    4469

    瀏覽量

    51109
  • Gateway
    +關(guān)注

    關(guān)注

    1

    文章

    16

    瀏覽量

    7898
  • 腳本語言
    +關(guān)注

    關(guān)注

    0

    文章

    48

    瀏覽量

    8225
  • nginx
    +關(guān)注

    關(guān)注

    0

    文章

    149

    瀏覽量

    12176

原文標(biāo)題:網(wǎng)關(guān) GateWay 的使用詳解、路由、過濾器、跨域配置

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Proteus涉及的基本概念

    Proteus涉及的基本概念
    發(fā)表于 08-01 20:58

    電子元件基本概念和原理

    電子元件基本概念和原理
    發(fā)表于 08-05 21:25

    Fpga Cpld的基本概念

    Fpga Cpld的基本概念
    發(fā)表于 08-20 17:14

    C語言基本概念

    C語言基本概念
    發(fā)表于 08-01 02:00

    數(shù)據(jù)結(jié)構(gòu)的基本概念是什么

    數(shù)據(jù)結(jié)構(gòu)之基本概念
    發(fā)表于 05-27 08:29

    阻抗控制相關(guān)的基本概念

    阻抗控制部分包括兩部分內(nèi)容:基本概念及阻抗匹配。本篇主要介紹阻抗控制相關(guān)的一些基本概念
    發(fā)表于 02-25 08:11

    智能天線的基本概念

    1智能天線的基本概念 智能天線綜合了自適應(yīng)天線和陣列天線的優(yōu)點(diǎn),以自適應(yīng)信號(hào)處理算法為基礎(chǔ),并引入了人工智能的處理方法。智能天線不再是一個(gè)簡(jiǎn)單的單元,它已成為一個(gè)具有智能的系統(tǒng)。其具體定義為:智能
    發(fā)表于 08-05 08:30

    CODESYS的基本概念有哪些

    CODESYS是什么?CODESYS的基本概念有哪些?CODESYS有哪些功能?
    發(fā)表于 09-18 06:52

    微服務(wù)網(wǎng)關(guān)gateway的相關(guān)資料推薦

    目錄微服務(wù)網(wǎng)關(guān) gateway 概述[路由器網(wǎng)關(guān) Zuul 概述]嵌入式 Zuul 反向代理微服務(wù)網(wǎng)關(guān) gateway 概述1、想象一下一個(gè)
    發(fā)表于 12-23 08:19

    質(zhì)量檢驗(yàn)的基本概念及統(tǒng)計(jì)技術(shù)的詳解

    本文介紹了質(zhì)量檢驗(yàn)的基本概念,詳述了統(tǒng)計(jì)抽樣檢驗(yàn)以及質(zhì)量統(tǒng)計(jì)與質(zhì)量統(tǒng)計(jì)分析等相關(guān)技術(shù)的詳解
    發(fā)表于 11-20 14:06 ?35次下載
    質(zhì)量檢驗(yàn)的<b class='flag-5'>基本概念</b>及統(tǒng)計(jì)技術(shù)的<b class='flag-5'>詳解</b>

    通信原理的基本概念講解

    通信原理的基本概念講解。
    發(fā)表于 05-27 14:48 ?17次下載

    Spring Cloud Gateway服務(wù)網(wǎng)關(guān)的部署與使用詳細(xì)教程

    Gateway 網(wǎng)關(guān)的搭建: 3、Spring Cloud Gateway 配置項(xiàng)的說明: 4、Gateway 集成 nacos 注冊(cè)中心實(shí)現(xiàn)服務(wù)發(fā)現(xiàn): 5、
    的頭像 發(fā)表于 10-11 17:46 ?1750次閱讀

    如何利用Gateway搭建網(wǎng)關(guān)服務(wù)?

    網(wǎng)關(guān)作為微服務(wù)中非常重要的一部分,是必須要掌握的;本文記錄一下我是如何使用Gateway搭建網(wǎng)關(guān)服務(wù)及實(shí)現(xiàn)動(dòng)態(tài)路由的,幫助大家學(xué)習(xí)如何快速搭建一個(gè)網(wǎng)關(guān)服務(wù),了解路由相關(guān)配置,鑒權(quán)的流程
    的頭像 發(fā)表于 01-21 16:06 ?1216次閱讀
    如何利用<b class='flag-5'>Gateway</b>搭建<b class='flag-5'>網(wǎng)關(guān)</b>服務(wù)?

    基本概念.zip

    基本概念
    發(fā)表于 12-30 09:21 ?2次下載

    Spring Cloud Gateway網(wǎng)關(guān)框架

    Spring Cloud Gateway網(wǎng)關(guān)框架 本軟件微服務(wù)架構(gòu)中采用Spring Cloud Gateway網(wǎng)關(guān)控制框架,Spring Cloud
    的頭像 發(fā)表于 08-22 09:58 ?494次閱讀
    Spring Cloud <b class='flag-5'>Gateway</b><b class='flag-5'>網(wǎng)關(guān)</b>框架