SpringCloud服務(wù)網(wǎng)關(guān)Gateway的使用教程詳解
Gateway
什么是Gateway
由于Netflix的zuul發(fā)生問題,spring公司自己研發(fā)了一套網(wǎng)關(guān)框架Gateway用于取代zuul的使用。什么是gateway呢?spring cloud Gateway是使用Webflux中的reactor-netty響應(yīng)式編程組件,底層使用的是netty通訊框架。
什么是api網(wǎng)關(guān)
API gateway 處于客戶端與各個微服務(wù)之間,它擔任了反向代理的角色,將不同的請求路由到相對應(yīng)的微服務(wù)中去。與此同時,它還有以下功能:安全,限流,緩存,日志,監(jiān)控,重試,熔斷等。網(wǎng)關(guān)就是所有項目的一個統(tǒng)一入口,也可以說是進入系統(tǒng)的唯一節(jié)點。
網(wǎng)關(guān)的三個核心概念
路由(Route)
路由是構(gòu)建網(wǎng)關(guān)的基本模塊,它由ID、目標URI、一系列的斷言和過濾器組成,如果斷言為真則匹配該路由。就是根據(jù)斷言和過濾器提供的某些規(guī)則,將請求發(fā)送到指定服務(wù)上
斷言(Predicate)
開發(fā)人員可以匹配HTTP請求中的所有內(nèi)容(例如請求頭或請求參數(shù)),如果請求與斷言相匹配則進行路由,就是定義匹配規(guī)則,只有滿足斷言的請求才會繼續(xù)進行路由
過濾(Filter)
指的是Spring框架中GatewayFilter的實例,使用過濾器,可以在請求被路由前或者之后對請求進行修改。當請求進行斷言之前,或者滿足斷言后會繼續(xù)進行路由,但是由于過濾的存在請求會再次被過濾條件進行指定的修改操作
gateway的工作流程
客戶端向Spring Cloud Gateway發(fā)出請求。然后在Gateway Handler Mapping 中找到與請求相匹配的路由,將其發(fā)送到GatewayWeb Handler。Handler再通過指定的過濾器鏈來將請求發(fā)送到我們實際的服務(wù)執(zhí)行業(yè)務(wù)邏輯,然后返回。
過濾器之間用虛線分開是因為過濾器可能會在發(fā)送代理請求之前(“pre”)或之后(“post”)執(zhí)行業(yè)務(wù)邏輯。Filter在“pre”類型的過濾器可以做參數(shù)校驗、權(quán)限校驗、流量監(jiān)控、日志輸出、協(xié)議轉(zhuǎn)換等,在“post”類型的過濾器中可以做響應(yīng)內(nèi)容、響應(yīng)頭的修改,日志的輸出,流量監(jiān)控等有著非常重要的作用。
如何使用Gateway
gateway路由轉(zhuǎn)發(fā)
使用配置文件
第一步: 創(chuàng)建一個子模塊用于配置gateway,導(dǎo)入相關(guān)依賴,其中最重要的就是gateway的啟動器。一定不能引入web場景啟動器依賴,否則gateway模塊將無法啟動
<!--gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
第二步: 配置文件
server:
port: 9527spring:
application:
name: cloud-gatewayeureka:
instance:
hostname: cloud-gateway-service
client: #服務(wù)提供者provider注冊進eureka服務(wù)列表內(nèi)
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://localhost:7001/eureka
第三步: 現(xiàn)在我們想在支付微服務(wù)8001之前使用gateway網(wǎng)關(guān),讓請求在訪問8001微服務(wù)之前先經(jīng)過gateway網(wǎng)關(guān)。于是我們需要先配置配置文件
spring:
cloud:
gateway:
routes:
- id: payment_routh #payment_route #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
#uri: http://localhost:8001 #匹配后提供服務(wù)的路由地址
uri: lb://cloud-payment-service #匹配后提供服務(wù)的路由地址
predicates:
- Path=/payment/get/** # 斷言,路徑相匹配的進行路由- id: payment_routh2 #payment_route #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
#uri: http://localhost:8001 #匹配后提供服務(wù)的路由地址
uri: lb://cloud-payment-service #匹配后提供服務(wù)的路由地址
predicates:
- Path=/payment/create/** # 斷言,路徑相匹配的進行路由
- After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
經(jīng)過如上操作,即可實現(xiàn)如果通過9527端口也可以訪問8001的接口,也就是說請求先是通過9527網(wǎng)關(guān),將符合yml配置文件中配置的請求進行路由轉(zhuǎn)發(fā)至8001端口
使用代碼配置
使用代碼配置的話就需要使用到自定義配置類了,將上面的第三步由配置文件配置修改為自定義配置類,前兩步要保持一致。其中route方法的第一個參數(shù)相當于id配置,r.path相當于predicates斷言,r.path.uri就是請求將要路由到的地址
@Configuration public class GateWayConfig { @Bean public RouteLocator customRouteLocatorBuilder(RouteLocatorBuilder routeLocatorBuilder) { RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes(); routes.route("path_route_atguigu", r -> r.path("/guonei") .uri("http://news.baidu.com/guonei")) .build(); return routes.build(); } }
路由實現(xiàn)負載均衡
之前都是通過ribbon來實現(xiàn)請求的負載均衡,其實gateway網(wǎng)關(guān)也可以通過注冊中心的微服務(wù)名來實現(xiàn)負載均衡,也就是動態(tài)路由的功能。這里我們先通過以下配置開啟從注冊中心動態(tài)創(chuàng)建路由的功能
spring:
cloud:
gateway:
discovery:
locator:
enabled: true #開啟從注冊中心動態(tài)創(chuàng)建路由的功能,利用微服務(wù)名進行路由
然后將原先寫死的路徑改為微服務(wù)名,通過這個實現(xiàn)對微服務(wù)的輪詢
spring:
cloud:
gateway:
routes:
- id: payment_routh #payment_route #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
#uri: http://localhost:8001 #匹配后提供服務(wù)的路由地址
uri: lb://cloud-payment-service #匹配后提供服務(wù)的路由地址
predicates:
- Path=/payment/get/** # 斷言,路徑相匹配的進行路由- id: payment_routh2 #payment_route #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
#uri: http://localhost:8001 #匹配后提供服務(wù)的路由地址
uri: lb://cloud-payment-service #匹配后提供服務(wù)的路由地址
predicates:
- Path=/payment/create/** # 斷言,路徑相匹配的進行路由
gateway九種斷言
gateway的斷言實際上就是配置文件中的predicates配置項,既然這個單詞是復(fù)數(shù),那就意味著它不僅僅可以配置一種斷言,實際上斷言的類型有九種,它們的意思以及使用方式我都寫在了下面
predicates:
- Path=/payment/create/** # 路徑斷言,路徑相匹配的進行路由
- Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] # 時間斷言,時間Before、After、Between指定時間的請求進行路由
- After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
- Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] , 2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
- Cookie=username,zzyy # cookie斷言,攜帶名為username且值為zzyy的請求進行路由(zzyy可以替換為正則)
- Header=X-Request-Id, \d+ # header斷言,請求頭攜帶X-Request-Id且值滿足正則"\d+"的請求進行路由
- Host=**.atguigu.com, **.atg.com # host斷言,請求格式符合的請求進行路由
- Method=GET # method斷言,請求方式為get的請求進行路由
- Query=username, \d+ # query斷言,有參數(shù)名為username且值滿足正則"\d+"的請求進行路由
gateway過濾修改
使用配置文件實現(xiàn)filter過濾修改很簡單,類似于斷言的使用,在配置文件直接配置即可
filters:
- AddRequestParameter=X-Request-Id,1024
但是一般不這么使用filter,我們都是自定義一個全局GlobalFilter,重點就是@Component注解,類實現(xiàn)GlobalFilter, Ordered接口重寫方法,設(shè)置過濾規(guī)則和優(yōu)先級
@Component @Slf4j public class MyLogGateWayFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { /** * 判斷請求中包含uname參數(shù)且它的值不為空,否則拒絕請求 */ String uname = exchange.getRequest().getQueryParams().getFirst("uname"); if (uname == null) { log.info("*******用戶名為null,非法用戶,o(╥﹏╥)o"); exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } /** * 加載過濾器順序,數(shù)字越小優(yōu)先級越高 * @return */ @Override public int getOrder() { return 0; } }
到此這篇關(guān)于SpringCloud服務(wù)網(wǎng)關(guān)Gateway的使用教程詳解的文章就介紹到這了,更多相關(guān)SpringCloud Gateway內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springcloud gateway網(wǎng)關(guān)服務(wù)啟動報錯的解決
- Springcloud GateWay網(wǎng)關(guān)配置過程圖解
- SpringCloud網(wǎng)關(guān)Gateway架構(gòu)解析
- 從0到1學SpringCloud之SpringCloud?gateway網(wǎng)關(guān)路由配置示例詳解
- SpringCloud Gateway網(wǎng)關(guān)功能介紹與使用
- SpringCloud gateway+zookeeper實現(xiàn)網(wǎng)關(guān)路由的詳細搭建
- SpringCloud超詳細講解微服務(wù)網(wǎng)關(guān)Gateway
- SpringCloudGateway網(wǎng)關(guān)處攔截并修改請求的操作方法
相關(guān)文章
mybatisPlus條件構(gòu)造器常用方法小結(jié)
這篇文章主要介紹了mybatisPlus條件構(gòu)造器常用方法,首先是.select和其他條件,本文結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下2022-10-10spring-security關(guān)閉登錄框的實現(xiàn)示例
這篇文章主要介紹了spring-security關(guān)閉登錄框的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-05-05Java五種方式實現(xiàn)多線程循環(huán)打印問題
本文主要介紹了Java五種方式實現(xiàn)多線程循環(huán)打印問題,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12SpringBoot任意版本集成Swagger各種版本的操作指南
在學習Swagger生成API文檔的時候經(jīng)常會遇到問題,而目前市面上大部分技術(shù)分享者的SpringBoot版本并沒和我們的同步,導(dǎo)致一些一模一樣的代碼,在我們的項目上卻無法使用,這是一個經(jīng)常性的問題,本文章就旨在和大家搞定SpringBoot任意版本集成Swagger各種版本2024-07-07