Spring Cloud Gateway
概述
Spring Cloud Gateway 是 Spring Cloud 的一個全新項目,該項目是基於Netty、Reactor以及WEbFlux構建,它旨在為微服務架構提供一種簡單有效的統一的 API 路由管理方式。
Spring Cloud Gateway 作為 Spring Cloud 生態系統中的網關,目標是替代 Netflix Zuul,其不僅提供統一的路由方式,並且基於 Filter 鏈的方式提供了網關基本的功能,例如:安全、監控、埋點和限流等。
優點
- 性能強勁,是Zuul的1.6倍
- 功能強大,內置了很多實用的功能,例如轉發、監控、限流等
- 設計優雅,容易擴展
缺點
- 依賴Netty與WebFlux,不是傳統的Servlet編程模型,有一定的學習成本
- 不能在Servlet容器下工作,也不能構建成WAR包,即不能將其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包執行
- 不支持Spring Boot 1.x,需2.0及更高的版本
核心概念
Route(路由)
這是Spring Cloud Gateway的基本構建塊,可簡單理解成一條轉發規則。包含:ID、目標URL、一組斷言和一組過濾器
Predicate(斷言)
這是一個 Java 8 的 Predicate,即java.util.function.Predicate這個接口,Gateway使用Predicate實現路由的匹配條件。
Filter(過濾器)
這是 org.springframework.cloud.gateway.filter.GatewayFilter 的實例,我們可以使用它修改請求和響應
Gateway路由配置示例
spring:
cloud:
gateway:
routes:
- id: study01 # 唯一標識,通常使用服務id
uri: lb://study01 # 目標URL,lb代表從注冊中心獲取服務,lb是Load Balance的縮寫
predicates:
# Predicate集合
- Path=/findBy # 匹配轉發路徑
filters:
# Filter集合
- StripPrefix=4 # 從第幾級開始轉發
工作流程
客戶端向 Spring Cloud Gateway 發出請求。然后在 Gateway Handler Mapping 中找到與請求相匹配的路由,將其發送到 Gateway Web Handler。Handler 再通過指定的過濾器鏈來將請求發送到我們實際的服務執行業務邏輯,然后返回。
過濾器之間用虛線分開是因為過濾器可能會在發送代理請求之前(“pre”)或之后(“post”)執行業務邏輯。
特征
- 基於 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
- 動態路由
- Predicates 和 Filters 作用於特定路由
- 集成 Hystrix 斷路器
- 集成 Spring Cloud DiscoveryClient
- 易於編寫的 Predicates 和 Filters
- 限流
- 路徑重寫
整合Spring Cloud Gateway
新建一個標准的Spring Boot項目,命名為gateway。
添加依賴
整合Spring Cloud Alibaba,添加Gateway和Nacos的依賴,示例如下:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>小程序網關</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 整合spring-cloud-alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
修改配置
添加nacos和gateway的配置,代碼如下:
server:
port: 8040
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: 888ac051-ae5f-44f1-940a-30c7824a0e91
cluster-name: HZ
gateway:
discovery:
locator:
# 讓gateway通過服務發現組件找到其他的微服務
enabled: true
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
測試
依次啟動之前就寫好的項目【study01和study02】,然后啟動gateway項目,打開任意瀏覽器。
PS:上述三個項目的nacos配置要一致。
我在study01項目中有一個findBy請求:http://localhost:8881/findById
在啟動了gateway之后,可以這樣輸入瀏覽器地址:http://localhost:8040/study01/findById ,我們發現返回的結果是相同的
這就是Spring Cloud Gateway的作用之一 - 轉發。
轉發規律
- ${GATEWAY_URL}/{微服務名}/{請求路徑}