SpringCloud Gateway路由組件詳解
簡介
Gateway是SpringCloud Alibaba中的路由組件(前身是Zuul),作為瀏覽器端請求的統(tǒng)一入口。當(dāng)項目采用微服務(wù)模式時,若包含了路由模塊,瀏覽器端的請求都不會直接請求含有業(yè)務(wù)邏輯的各個業(yè)務(wù)模塊,而是請求這個路由模塊,然后再由它來轉(zhuǎn)發(fā)到各個業(yè)務(wù)模塊去。
核心概念
Gateway中的三個核心概念:路由、斷言(Predicate)、過濾器。
路由:由唯一id、目的url、斷言和過濾組成
斷言:即路由規(guī)則,用來判斷哪些請求符合規(guī)則,符合的請求進(jìn)行轉(zhuǎn)發(fā)
過濾器:分為GatewayFilter和GlobalFilter,前者作用于單一路由,后者作用于所有路由。過濾器可以對請求或者返回進(jìn)行處理,如增加請求頭、刪除請求頭
配置文件如下:
spring:
cloud:
gateway:
# 網(wǎng)關(guān)路由配置
routes:
# 路由id,自定義,只要唯一即可
- id: user-service
# uri: http://127.0.0.1:8081 # 路由的目標(biāo)地址 http就是固定地址
# 路由的目標(biāo)地址 lb就是負(fù)載均衡,后面跟服務(wù)名稱,要和nacos的注冊中心結(jié)合
uri: lb://userservice
# 斷言
predicates:
# 這個是按照路徑匹配,只要以/user/開頭就符合要求
- Path=/user/**
# 過濾器
filters:
# 添加請求頭
- AddRequestHeader=sign, xn2001.com is eternal
上面寫到了根據(jù)路徑匹配的斷言,Gateway提供了十幾種內(nèi)置的斷言:
| 名稱 | 說明 | 示例 |
|---|---|---|
| After | 是某個時間點之后的請求 | - After=2022-08-26T18:34:10.475+08:00[Asia/Shanghai] |
| Before | 是某個時間點之前的請求 | - Before=2022-11-26T18:34:10.475+08:00[Asia/Shanghai] |
| Between | 是某兩個時間點之前的請求 | - Between=2022-10-26T18:35:15.093+08:00[Asia/Shanghai], 2022-11-26T18:35:15.093+08:00[Asia/Shanghai] |
| Cookie | 請求必須包含某些cookie | - Cookie=chocolate, ch.p |
| Header | 請求必須包含某些header | - Header=sign, internal |
| Host | 請求必須是訪問某個host(域名) | - Host=**.somehost.org, **.anotherhost.org |
| Method | 請求方式必須是指定方式 | - Method=GET,POST |
| Path | 請求路徑必須符合指定規(guī)則 | - Path=/blue/** |
| Query | 請求參數(shù)必須包含指定參數(shù) | - Query=name, Jack或- Query=name |
| RemoteAddr | 請求者的ip必須是指定范圍 | - RemoteAddr=192.168.1.1/24 |
| Weight | 權(quán)重處理 |
配置中的AddRequestHeader就是其中一種Gateway Filter,還有其余的內(nèi)置的:
| 名稱 | 說明 |
|---|---|
| AddRequestHeader | 給當(dāng)前請求添加一個請求頭 |
| RemoveRequestHeader | 移除請求中的一個請求頭 |
| AddResponseHeader | 給響應(yīng)結(jié)果中添加一個響應(yīng)頭 |
| RemoveResponseHeader | 從響應(yīng)結(jié)果中移除一個響應(yīng)頭 |
| RequestRateLimiter | 限制請求的流量 |
全局過濾器,后面的示例給出具體用法
具體示例
這里新建2個模塊,路由模塊和用戶模塊
用戶模塊,引入依賴spring-boot-starter-web、spring-cloud-starter-alibaba-nacos-discovery,bootstrap.yml配置端口號、nacos注冊中心的地址,并提供接口:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/user")
public class UserController {
@ResponseBody
@RequestMapping("/sayHello")
public String sayHello(@RequestHeader(value = "sign",
required = false) String sign) {
return "這是好吃的:" + sign;
}
}
路由模塊,引入依賴:
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config
</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery
</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
bootstrap.yml的配置:
server:
port: 8086
servlet:
context-path: /gatewayspring:
application:
name: gateway
profiles:
active: dev
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yml
discovery:
server-addr: 127.0.0.1:8848
2個模塊都啟動后,nacos的服務(wù)列表顯示:

nacos中新建名為gateway-dev.yml的配置,內(nèi)容為:
spring:
cloud:
gateway:
discovery:
locator:
# 通過服務(wù)名稱轉(zhuǎn)發(fā),默認(rèn)false
enabled: true
# 服務(wù)名稱不用大寫
lower-case-service-id: true
# routes:
# - id: user-service
# uri: lb://supplier
# predicates:
# - Path=/provider/**
# filters:
# - AddRequestHeader=sign, big JavaCoder
此時,請求路徑:http://localhost:8086/supplier/provider/user/sayHello
注:supplier是服務(wù)名稱,provider是模塊訪問路徑(server.servlet.context-path)
但這種配置不是很推薦
把spring.cloud.gateway.discovery及子配置注釋掉,把spring.cloud.gateway.routes及子配置取消注釋,重啟路由模塊,這時訪問路徑:
http://localhost:8086/provider/user/sayHello。
注:這是訪問的路徑,經(jīng)過gateway處理后,實際訪問的是lb://supplier/provider/user/sayHello(見RouteToRequestUrlFilter的filter方法);provider是模塊訪問路徑(server.servlet.context-path),如果用戶模塊沒有設(shè)置的話,filters下添加- StripPrefix=1,這時訪問路徑不變,實際的訪問路徑是lb://supplier/user/sayHello。
GlobalFilter
處理一切進(jìn)入網(wǎng)關(guān)的請求和響應(yīng),并且也是可以編寫代碼自定義邏輯;在執(zhí)行順序上,GatewayFilter先執(zhí)行,GlobalFilter后執(zhí)行。
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
List<String> sign = headers.get("sign");
if(sign.size() < 1) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.BAD_REQUEST);
//被攔截,請求不到對應(yīng)模塊了
return exchange.getResponse().setComplete();
}
headers = HttpHeaders.writableHttpHeaders(headers);
headers.set("sign1", "bigAAA");
//放行
return chain.filter(exchange);
}
}
到此這篇關(guān)于SpringCloud Gateway路由組件詳解的文章就介紹到這了,更多相關(guān)SpringCloud Gateway內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring boot實現(xiàn)在request里解密參數(shù)返回
這篇文章主要介紹了Spring Boot實現(xiàn)在request里解密參數(shù)返回操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
SpringSecurityOAuth2實現(xiàn)微信授權(quán)登錄
微信的登錄功能是用戶注冊和使用微信的必經(jīng)之路之一,而微信授權(quán)登錄更是方便了用戶的登錄操作,本文主要介紹了SpringSecurityOAuth2實現(xiàn)微信授權(quán)登錄,感興趣的可以了解一下2023-09-09
Java使用Hutool實現(xiàn)AES、DES加密解密的方法
本篇文章主要介紹了Java使用Hutool實現(xiàn)AES、DES加密解密的方法,具有一定的參考價值,有興趣的可以了解一下2017-08-08
Java中處理金額計算之使用Long還是BigDecimal詳解
在Java后端開發(fā)中處理與錢有關(guān)的業(yè)務(wù)時,確保金額計算的準(zhǔn)確性和避免錯誤非常重要,這篇文章主要給大家介紹了關(guān)于Java中處理金額計算之使用Long還是BigDecimal的相關(guān)資料,需要的朋友可以參考下2024-07-07
Java 實現(xiàn)一個漢諾塔實戰(zhàn)練習(xí)
漢諾塔是源于印度一個古老傳說的益智玩具。大梵天創(chuàng)造世界時做了三根石柱,在一根柱子上從下往上按大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。并且規(guī)定,在小圓盤上不能放大圓盤,三根柱子之間一次只能移動一個圓盤2021-10-10

