gateway基本配置教程
1、gateway簡介
路由轉發(fā) + 執(zhí)行過濾器鏈。
網(wǎng)關,旨在為微服務架構提供一種簡單有效的統(tǒng)一的API路由管理方式。同時,基于Filter鏈的方式提供了網(wǎng)關的基本功能,比如:鑒權、流量控制、熔斷、路徑重寫、黑白名單、日志監(jiān)控等。
基本功能如下:
- 統(tǒng)一入口:暴露出網(wǎng)關地址,作為請求唯一入口,隔離內(nèi)部微服務,保障了后臺服務的安全性
- 鑒權校驗:識別每個請求的權限,拒絕不符合要求的請求
- 動態(tài)路由:動態(tài)的將請求路由到不同的后端集群中
2、gateway核心概念
- 路由(Route):由一個ID,一個目標URI(最終路由到的url地址),一組斷言(匹配條件判斷)和一組過濾器定義。如果斷言為真,則路由匹配。
- 斷言(Predicate):通過斷言匹配http請求中的任何內(nèi)容(請求頭、請求參數(shù)等),如果匹配成功,則匹配斷言所在路由。
- 過濾器(Filter):在請求前后執(zhí)行業(yè)務邏輯,比如鑒權、日志監(jiān)控、流量控制、修改請求頭、修改響應等。
3、路由
spring: cloud: gateway: routes: - id: manager # 路由唯一標識 uri: lb://manager_server # 路由指向目的地URL或服務名,客戶端請求最終被轉發(fā)到的微服務 predicates: - Path=/manager/** # 斷言:以manager開頭的請求都負載到manager_server服務 filters: - RewritePath=/manager/(?<segment>.*), /$\{segment} # 過濾器:過濾掉url里的manager,例如http://ip:port/manager/test -> http://ip:port/test order: 5 # 用于多個Route之間的排序,數(shù)值越小越靠前,匹配優(yōu)先級越高
4、斷言
spring: cloud: gateway: routes: - id: manager uri: https://manager_server predicates: - After=2017-01-20T17:42:47.789-07:00[America/Denver] # 時間點后匹配 - Before=2017-01-20T17:42:47.789-07:00[America/Denver] # 時間點前匹配 - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver] # 時間區(qū)間匹配 - Cookie=chocolate, ch.p # 指定cookie正則匹配 - Header=X-Request-Id, \d+ # 指定Header正則匹配 - Host=**.somehost.org,**.anotherhost.org # 請求Host匹配 - Method=GET,POST # 請求Method匹配指定請求方式 - Path=/red/{segment},/blue/{segment} # 請求路徑正則匹配 - Query=green # 請求包含某參數(shù) - Query=red, gree. # 請求包含某參數(shù)并且參數(shù)值匹配正則表達式(匹配red;green,greet,gree...) - RemoteAddr=192.168.1.1/24 # 遠程地址匹配 # 設置分組和權重,按照路由權重選擇同一個分組中的路由 - id: preManager1 uri: https://preManager1 predicates: - Weight=group1, 2 - id: preManager2 uri: https://preManager2 predicates: - Weight=group1, 8
5、過濾器
5.1、過濾器介紹
按生命周期分類
- 前置(pre)過濾器: 在請求被路由之前調(diào)用:在chain.filter(exchange)前編寫過濾器邏輯
- 后置(post)過濾器: 在路由到微服務之后調(diào)用:通過chain.filter(exchange).then(Mono.fromRunnable(() -> {過濾器邏輯})實現(xiàn)
按類型分類
- 局部(GatewayFilter)過濾器:作用在某一個路由上,使用時需要關聯(lián)指定的路由
- 全局(GlobalFilter)過濾器:作用在所有路由上,不需要在配置文件中配置
5.2、內(nèi)置局部過濾器與使用
spring: cloud: gateway: routes: - id: gateway_filter uri: https://example.org predicates: - Path=/red/{segment} filters: # 1、為原始請求添加Header。headerName:X-Request-red,headerValue:blue。 - AddRequestHeader=X-Request-red, blue - AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green # 2、為原始請求添加參數(shù)。參數(shù)名,參數(shù)值 - AddRequestParameter=red, blue # 3、為原始響應添加Header - AddResponseHeader=X-Response-Red, Blue # 4、剔除響應頭中重復的值 - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin # 5、為原始請求路徑添加前綴 - PrefixPath=/mypath # 6、配置該過濾器后,會原始請求的host頭信息,并原封不動的轉發(fā)出去,而不是被gateway的http客戶端重置。 - PreserveHostHeader # 7、將原始請求重定向到指定的URL,參數(shù)為http狀態(tài)碼及重定向的url - RedirectTo=302, https://acme.org # 8、移除響應Body中的指定key - RemoveJsonAttributesResponseBody=id,color # 9、移除原始請求中的指定Header - RemoveRequestHeader=X-Request-Foo # 10、移除原始請求中的指定參數(shù) - RemoveRequestParameter=red # 11、移除響應中的指定Header - RemoveResponseHeader=X-Response-Foo
spring: cloud: gateway: routes: - id: gateway_filter uri: https://example.org predicates: - Path=/red/{segment} filters: # 12、請求限流,限流算法為令牌桶,以下示例為根據(jù)用戶id做限流 # @Configuration # public class RateLimiterConfig { # @Bean # public KeyResolver userKeyResolver() { # return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getQueryParams().getFirst("userId"))); # } # } - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 10 # 允許用戶每秒處理的請求數(shù) redis-rate-limiter.burstCapacity: 20 # 令牌桶的容量,即允許在 1 秒內(nèi)完成的最大請求數(shù)。設置為 0 則表示拒絕所有請求。 key-resolver: "#{@userKeyResolver}" # 一個引用名為 userKeyResolver 的 bean 的 SpEL 表達式 # 13、重寫原始的請求路徑 - RewritePath=/red/?(?<segment>.*), /$\{segment} # 14、重寫響應中的某個Header - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=*** # 15、在轉發(fā)請求之前,強制執(zhí)行websession::save操作,保存會話狀態(tài) - SaveSession # 16、修改原始的請求路徑 - SetPath=/{segment} # 17、修改原始請求中的指定Header值 - SetRequestHeader=X-Request-Red, Blue # 18、修改原始響應中的指定Header值 - SetResponseHeader=X-Response-Red, Blue # 19、修改原始響應的響應碼 - SetStatus=401 # 20、剝離原始請求路徑 - StripPrefix=2 # 21、請求重試 - name: Retry args: retries: 3 # 重試次數(shù) statuses: BAD_GATEWAY # 應被重試的 HTTP Status Codes methods: GET,POST # 應被重試的 HTTP Methods backoff: # 為重試配置指數(shù)級的 backoff。重試時間間隔的計算公式為 firstBackoff * (factor ^ n),n 是重試的次數(shù);如果設置了 maxBackoff,最大的 backoff 限制為 maxBackoff. 如果 basedOnPreviousValue 設置為 true, backoff 計算公式為 prevBackoff * factor. firstBackoff: 10ms maxBackoff: 50ms factor: 2 basedOnPreviousValue: false # 22、設置允許接收最大請求包的大小。如果請求包大小超過設置的值,則返413Payload Too Large - name: RequestSize args: maxSize: 5000000
5.3、內(nèi)置全局過濾器
- GatewayMetricsFilter(0):統(tǒng)計一些網(wǎng)關的性能指標
- RouteToRequestUrlFilter(10000):把瀏覽器的URL請求的Path路徑添加到路由的URI之中。
- NettyRoutingFilter(2147483647):通過HttpClient客戶端轉發(fā)真實的URL,并存儲返回的結果。
- NettyWriteResponseFilter(-1):在所有的其它的過濾器執(zhí)行完成之后運行,將響應的數(shù)據(jù)發(fā)送給網(wǎng)關的客戶端。
- ForwardRoutingFilter(2147483647):轉發(fā)路由過濾器,若URI是forward模式,過濾器會將請求轉發(fā)到DispatcherHandler來處理請求。
- ForwardPathFilter(0):解析路徑,并將路徑轉發(fā)。
- LoadBalancerClientFilter(10100):負載均衡,解析服務名,獲取真實服務地址。
- RemoveCachedBodyFilter(-2147483648):清除網(wǎng)關上下文中的緩存的請求Body。
- WebsocketRoutingFilter(2147483646):如果請求中的ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 屬性對應的URL前綴為 ws 或 wss,會使用Spring Web Socket 模塊轉發(fā)WebSocket請求。WebSockets可以使用路由進行負載均衡。
- AdaptCachedBodyGlobalFilter(-2147482648):從請求中獲取body緩存到網(wǎng)關上下文。
5.4、自定義全局過濾器
創(chuàng)建自定義全局過濾器類 ,實現(xiàn)GlobalFilter和Ordered兩個接口。
- GlobalFilter:全局過濾攔截器
- Ordered:攔截器的順序,數(shù)字越低,優(yōu)先級越高
5.4.1、黑名單校驗
/** * 定義全局過濾器,會對所有路由生效 */ @Slf4j @Component // 讓容器掃描到,等同于注冊了 public class BlackListFilter implements GlobalFilter, Ordered { // 模擬黑名單(實際可以去數(shù)據(jù)庫或者redis中查詢) private static List<String> blackList = new ArrayList<>(); static { blackList.add("0:0:0:0:0:0:0:1"); // 模擬本機地址 } /** * 過濾器核心方法 * @param exchange 封裝了request和response對象的上下文 * @param chain 網(wǎng)關過濾器鏈(包含全局過濾器和單路由過濾器) * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 思路:獲取客戶端ip,判斷是否在黑名單中,在的話就拒絕訪問,不在的話就放行 ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); // 從request對象中獲取客戶端ip String clientIp = request.getRemoteAddress().getHostString(); // 拿著clientIp去黑名單中查詢,存在的話就決絕訪問 if(blackList.contains(clientIp)) { // 拒絕訪問,返回 response.setStatusCode(HttpStatus.UNAUTHORIZED); // 狀態(tài)碼 log.debug("=====>IP:" + clientIp + " 在?名單中,將被拒絕訪問!"); String data = "Request be denied!"; DataBuffer wrap = response.bufferFactory().wrap(data.getBytes()); return response.writeWith(Mono.just(wrap)); } // 合法請求,放行,執(zhí)行后續(xù)的過濾器 return chain.filter(exchange); } /** * @return 過濾器的順序(優(yōu)先級),數(shù)值越小,優(yōu)先級越高 */ @Override public int getOrder() { return 0; } }
5.4.2、模擬登錄校驗
在過濾器中檢查請求中是否攜帶token請求頭。如果token請求頭存在則放行;如果token為空或者不存在則返回認證失敗狀態(tài)碼。
@Component public class MyGlobalFilter implements GlobalFilter,Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { boolean token = exchange.getRequest().getHeaders().containsKey("token"); System.out.println("----全局過濾器token----"+token); if (!token){ exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); ServerHttpResponse response = exchange.getResponse(); return response.setComplete(); } return chain.filter(exchange); } @Override public int getOrder() { return 1; } }
6、一個簡單的gateway配置實例
spring: cloud: gateway: discovery: locator: # 表明Gateway開啟服務注冊和發(fā)現(xiàn)的功能,并且Spring Cloud Gateway自動根據(jù)服務發(fā)現(xiàn)為每一個服務創(chuàng)建了一個router,這個router將以服務名開頭的請求路徑轉發(fā)到對應的服務 enabled: true # 將請求路徑上的服務名配置為小寫(因為服務注冊的時候,向注冊中心注冊時將服務名轉成大寫的了) lower-case-service-id: true routes: # 系統(tǒng)管理 - id: sys-mgt uri: lb://sysmgt predicates: - Path=/sys-mgt/** #以sys-mgt開頭的請求都負載到sysmgt服務 - Method=GET #只匹配GET請求 filters: - RewritePath=/sys-mgt/(?<segment>.*), /$\{segment} #過濾掉url里的sys-mgt,例如http://ip:port/sys-mgt/test -> http://ip:port/test - PrefixPath=/mgt #為請求添加/mgt前綴,再結合RewritePath過濾器,http://ip:port/sys-mgt/test -> http://ip:port/mgt/test
到此這篇關于gateway基本配置的文章就介紹到這了,更多相關gateway基本配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springboot添加多數(shù)據(jù)源的方法實例教程
這篇文章主要給大家介紹了關于springboot添加多數(shù)據(jù)源方法的相關資料,在實際開發(fā)中經(jīng)??赡苡龅皆谝粋€應用中可能要訪問多個數(shù)據(jù)庫多的情況,需要的朋友可以參考下2023-09-09java連接MySQL數(shù)據(jù)庫實現(xiàn)代碼
這篇文章主要為大家詳細介紹了java連接MySQL數(shù)據(jù)庫實現(xiàn)代碼,感興趣的小伙伴們可以參考一下2016-06-06理解Java注解及Spring的@Autowired是如何實現(xiàn)的
今天通過本文帶領大家學習注解的基礎知識,學習Spring的@Autowired是怎么實現(xiàn)的,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-07-07基于Java實現(xiàn)中文分詞系統(tǒng)的示例代碼
這篇文章主要為大家詳細介紹了如何利用Java語言實現(xiàn)一個簡易的中文分詞系統(tǒng),文中的示例代碼講解詳細,感興趣的小伙伴可以嘗試一下2022-07-07SpringMVC打印請求參數(shù)和響應數(shù)據(jù)最優(yōu)方案
項目中經(jīng)常需要打印http請求的參數(shù)和響應數(shù)據(jù),本文給大家講解如何在SpringMVC打印請求參數(shù)和響應數(shù)據(jù)最優(yōu)方案,感興趣的朋友跟隨小編一起看看吧2023-07-07