Spring Cloud Gateway 官網地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3
Spring Cloud Gateway 檔案地址 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/
Spring Cloud Gateway GitHub原始碼地址 https://github.com/spring-cloud/spring-cloud-gateway
Spring Cloud Gateway使用了WebFlux技術,而WebFlux技術底層又基於高效能的Reactor模式通訊框架Netty。Spring Cloud Gateway基於Spring 5、Spring Boot 2和project Reactor技術上構建非同步非阻塞的高吞吐量API閘道器,提供一種簡單且有效的方式來路由到API,併為它們提供橫切關注點如安全性、監控/指標和彈性等。Spring Cloud Gateway特性如下:
Spring Cloud Gateway特性如下:
閘道器作為系統的唯一流量入口,封裝內部系統的架構,所有請求都先經過閘道器,由閘道器將請求路由到合適的微服務,優勢如下:
流量閘道器(如典型Nginx閘道器)是指提供全域性性的、與後端業務應用無關的策略,例如 HTTPS證書解除安裝、Web防火牆、全域性流量監控等。而微服務閘道器(如Spring Cloud Gateway)是指與業務緊耦合的、提供單個業務域級別的策略,如服務治理、身份認證等。也就是說,流量閘道器負責南北向流量排程及安全防護,微服務閘道器負責東西向流量排程及服務治理。
從發展趨勢上看,Spring Cloud Gateway作為Spring Cloud生態體系中的閘道器,目標替代Netflix的Zuul且勢在必行。
進一步研究 Spring Cloud Gateway 的設定及其使用之前,我們先了解幾個 Spring Cloud Gateway 的核心術語
專案或模組中加入spring-cloud-starter-gateway
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
如果引入了啟動器,但又不希望啟用閘道器,則可以通過設定spring.cloud.gateway.enabled=false來禁用。全部詳細設定可以查閱官網,Spring Cloud Gateway詳細設定說明 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/appendix.html
官網提供兩種設定謂詞和過濾器的方法,分別是shortcuts and fully expanded arguments,譯為快捷方式和完全擴充套件的引數方式,後續例子我們都使用快捷方式,這種方式簡潔舒暢,官方的例子也大都是使用快捷方式。
路由設定Route 主要由路由id、目標uri、斷言集合和過濾器集合組成
利用前面庫存微服務提供的deduct介面,埠為4080,啟動庫存微服務,存取http://localhost:4080/deduct,顯示成功
建立閘道器微服務模組,pom檔案依賴如下,由於後面我們有Gateway整合Nacos和Sentinel的範例,所以這裡把其他依賴也先加進來
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>simple-ecommerce</artifactId>
<groupId>cn.itxs</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ecom-gateway</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>ecom-gateway</name>
<description>a simple electronic commerce platform demo tutorial for gateway service</description>
<properties>
<spring-cloud-loadbalancer.version>3.1.3</spring-cloud-loadbalancer.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>${spring-cloud-loadbalancer.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
</project>
bootstrap.yml組態檔加入建議路由設定如下
server:
port: 4090
spring:
application:
name: ecom-gateway
cloud:
gateway:
routes:
- id: storage_route
uri: http://localhost:4080
predicates:
- Path=/storage-service/**
filters:
- StripPrefix=1
啟動閘道器微服務
存取閘道器提供api介面http://localhost:4090/storage-service/deduct,匹配storage-service為真後通過過濾器去掉一層也即是storage-service路徑去掉,然後轉發至uri地址,最終轉發url為http://localhost:4080/deduct ,成功返回結果
本地組態檔bootstrap.yml改為如下,commons-dev.yaml包含服務註冊的組
spring:
application:
name: ecom-gateway
profiles:
active: dev
cloud:
nacos:
# 註冊中心資訊放在設定中心上,每個程式一般只設定設定中心的資訊
server-addr: 192.168.50.95:8848
config:
server-addr: ${spring.cloud.nacos.server-addr}
file-extension: yaml
namespace: a2b1a5b7-d0bc-48e8-ab65-04695e61db01
group: gateway-group
extension-configs:
- dataId: commons-dev.yaml
group: commons-group
refresh: true
username: itsx
password: itxs123
enabled: true # 預設為true,設定false 來完全關閉 Spring Cloud Nacos Config
refresh-enabled: true # 預設為true,當變更設定時,應用程式中能夠獲取到最新的值,設定false來關閉動態重新整理,我們使用註冊中心場景大部分就是動態感知,因此基本使用預設的
將路由設定也一併放在Nacos中設定ecom-gateway-dev.yaml,內容如下,uri這裡使用的是庫存微服務名稱,lb是做負載均衡處理
server:
port: 4090
spring:
cloud:
gateway:
routes:
- id: storage_route
uri: lb://ecom-storage-service
predicates:
- Path=/storage-service/**
filters:
- StripPrefix=1
Nacos中commons-dev.yaml的關於Nacos註冊中心使用設定如下,庫存微服務也是使用這個,服務註冊和發現都在ecom-group組
spring:
cloud:
nacos:
discovery:
server-addr: ${spring.cloud.nacos.server-addr}
group: ecom-group
namespace: a2b1a5b7-d0bc-48e8-ab65-04695e61db01
username: itsx
password: itxs123
啟動庫存微服務和閘道器微服務,都註冊到同一個組裡面
再次存取http://localhost:4090/storage-service/deduct ,正常返回結果,到此我們已經成功整合Nacos
Route Predicate Factories為路由斷言工廠,官網提供12種路由工廠,如果都沒有滿足你的需求,還可以自定義路由斷言工廠
我們先設定一個未來時間的after斷言- After=2022-07-09T23:42:47.789-08:00[Asia/Shanghai]
可以直接存取本機IP,返回一個錯誤的頁面
將after斷言改為- Before=2022-07-09T23:42:47.789-08:00[Asia/Shanghai]後則可以正常存取。
當官方提供的所有斷言工廠無法滿足業務需求時,還可以自定義斷言工廠。新增自定義斷言工廠類自定斷言工廠主要注意一下幾點:
新建一個庫存數量的路由斷言工廠QuantityRoutePredicateFactory.java,如庫存在100和200之間可以存取
package cn.itxs.ecom.gateway.factory;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
// 自定義路由斷言工廠
@Component
public class QuantityRoutePredicateFactory extends AbstractRoutePredicateFactory<QuantityRoutePredicateFactory.Config>{
public QuantityRoutePredicateFactory() {
super(QuantityRoutePredicateFactory.Config.class);
}
// 將組態檔中的值按返回集合的順序,賦值給設定類
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(new String[]{"minQuantity", "maxQuantity"});
}
@Override
public Predicate<ServerWebExchange> apply(Consumer<Config> consumer) {
return super.apply(consumer);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
// 建立閘道器斷言物件
// 檢查
return serverWebExchange -> {
// TODO 獲取請求引數age,判斷是否滿足如設定的[100, 200)
MultiValueMap<String, String> queryParams = serverWebExchange.getRequest().getQueryParams();
String quantity = queryParams.getFirst("quantity");
if (StringUtils.hasText(quantity) && quantity.matches("[0-9]+")) {
int iQuantity = Integer.parseInt(quantity);
if (iQuantity >= config.getMinQuantity() && iQuantity < config.getMaxQuantity()) {
return true;
}
}
return false;
};
}
// 設定類,屬性用於接收組態檔中的值
@Validated
public static class Config {
private int minQuantity;
private int maxQuantity;
public int getMinQuantity() {
return minQuantity;
}
public void setMinQuantity(int minQuantity) {
this.minQuantity = minQuantity;
}
public int getMaxQuantity() {
return maxQuantity;
}
public void setMaxQuantity(int maxQuantity) {
this.maxQuantity = maxQuantity;
}
}
}
Nacos閘道器的設定中增加自定義路由斷言工廠設定Quantity
server:
port: 4090
spring:
cloud:
gateway:
routes:
- id: storage_route
uri: lb://ecom-storage-service
predicates:
- Path=/storage-service/**
- Quantity=100,200
filters:
- StripPrefix=1
啟動閘道器微服務,存取http://localhost:4090/storage-service/deduct?quantity=99 ,沒有匹配路由策略
而存取http://localhost:4090/storage-service/deduct?quantity=100 ,能夠正確返回庫存微服務介面結果
**本人部落格網站 **IT小神 www.itxiaoshen.com