Spring Cloud Gateway服务网关
一、简介
1. 概述
Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,Spring Cloud Gateway 旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,目标是替代 Netflix ZUUL,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
2. Spring Cloud Gateway 功能特征
- 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
- 动态路由
- Predicates 和 Filters 作用于特定路由
- 集成 Hystrix 断路器
- 集成 Spring Cloud DiscoveryClient
- 易于编写的 Predicates 和 Filters
- 限流
- 路径重写
3. Spring Cloud Gateway 工程流程
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre
)或之后(post
)执行业务逻辑。
二、搭建Spring Cloud Gateway微服务
1. pom.xml
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.banmingi.nodeapp</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>gateway</artifactId>
<packaging>jar</packaging>
<inceptionYear>2019-Now</inceptionYear>
<dependencies>
<!--spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- spring cloud -->
<!-- nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>
<licenses>
<license>
<name>Apache 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>374564448</id>
<name>banmingi</name>
<email>l374564448@qq.com</email>
</developer>
</developers>
<build>
<plugins>
<!-- tk-mybatis 代码生成插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<configurationFile>
${basedir}/src/main/resources/generator/generatorConfig.xml
</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.1.5</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>
com.banmingi.nodeapp.gateway.GatewayApplication
</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
特别注意:
- Spring Cloud Gateway 不使用 Web 作为服务器,而是 使用 WebFlux 作为服务器,Gateway 项目已经依赖了
starter-webflux
,所以这里 千万不要依赖starter-web
- 由于过滤器等功能依然需要 Servlet 支持,故这里还需要依赖
javax.servlet:javax.servlet-api
2. 配置文件
server:
port: 9000
spring:
main:
allow-bean-definition-overriding: true
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
#让gateway从服务发现组件上面找到其他微服务并自动代理
enabled: true
# 暴露所有 actuator 端点
management:
endpoints:
jmx:
exposure:
include: '*'
# 健康检查展示详情
endpoint:
health:
show-details: always
3. 转发定律
4. 核心概念
-
**Route(路由):**Spring Cloud Gateway的元素基础,可简单理解成一条转发的规则。包含ID、目标URL、Predicate集合以及Filter集合。
-
**Predicate(谓词):**即java.util.Predicate,Spring Cloud Gateway使用Predicate实现路由的匹配条件。
-
**Filter(过滤器):**修改请求及响应。
路由匹配示例:
spring:
cloud:
gateway:
discovery:
locator:
#让gateway从服务发现组件上面找到其他微服务
enabled: true
routes:
- id: between_router
uri: lb://user-center
predicates:
- Path=/users/1
filters:
- AddRequestHeader=X-Request-Foo,Bar
三、Spring Cloud Gateway路由谓词工厂详解
1. 内置路由工厂
2. 自定义谓词路由工厂
Spring Cloud Gateway默认提供了一系列的路由谓词工厂,但如果这些内置的谓词工厂不能满足我们的需求,就需要编写自己的路由谓词工厂了。
**例如:**自定义路由工厂,使其在9:00~17:00这个期间才能访问。
配置:
spring:
cloud:
gateway:
discovery:
locator:
#让gateway从服务发现组件上面找到其他微服务
enabled: true
routes:
- id: between_router
uri: lb://user-center
predicates:
- TimeBetween=上午9:00,下午11:00
创建名为TimeBetweenRoutePredicateFactory的类,继承AbstractRoutePredicateFactory
注意这个类前缀为TimeBetween,与配置里面谓词的名字相一致,而且这个类一定要以RoutePredicateFactory结尾。
@Component
public class TimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<TimeBetweenConfig> {
public TimeBetweenRoutePredicateFactory() {
super(TimeBetweenConfig.class);
}
@Override
public Predicate<ServerWebExchange> apply(TimeBetweenConfig config) {
LocalTime start = config.getStart();
LocalTime end = config.getEnd();
return exchange -> {
LocalTime now = LocalTime.now();
//时间处于 start 和 end 之间
return now.isAfter(start) && now.isBefore(end);
};
}
/**
* 控制 配置类和配置文件的映射关系和顺序
* @return
*/
@Override
public List<String> shortcutFieldOrder() {
//映射
//上午9:00 下午5:00是Gateway的时间格式形式
//配置文件中的上午9:00对应配置实体类中的start,下午5:00对应end
return Arrays.asList("start","end");
}
}
@Data
public class TimeBetweenConfig {
private LocalTime start;
private LocalTime end;
}
四、Spring Cloud Gateway过滤器工厂详解
1. 内置过滤器
2. 自定义过滤器工厂
-
过滤器的声明周期
- **pre:**Gateway转发请求之前
- **post:**Gateway转发请求之后
-
自定义过滤器工厂的方式
-
继承AbstractGatewayFilterFactory
参考示例:
org.springframework.cloud.gateway.filter.factory.RequestSizeGatewayFilterFactory
配置形式:
-
继承AbstractNameValueGatewayFilterFactory
参考示例:
org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory
配置形式:
-
-
核心API
-
编写一个过滤器工厂
**例如:**进入这个过滤器工厂时就打印一下日志。
配置:
spring: cloud: gateway: discovery: locator: #让gateway从服务发现组件上面找到其他微服务 enabled: true routes: - id: between_router uri: lb://user-center predicates: - TimeBetween=上午9:00,下午11:00 filters: - PreLog=a,b
创建名为PreLogGatewayFilterFactory的类继承AbstractNameValueGatewayFilterFactory,
注意这个类前缀为PreLog,与配置里面filter的名字相一致,而且这个类一定要以GatewayFilterFactory结尾
@Slf4j @Component public class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory { @Override public GatewayFilter apply(NameValueConfig config) { return ((exchange,chain) -> { log.info("请求进来了 = {},{}",config.getName(),config.getValue()); ServerHttpRequest modifiedRequest = exchange.getRequest() .mutate() .build(); ServerWebExchange modifiedExchange = exchange.mutate().request(modifiedRequest).build(); return chain.filter(modifiedExchange); }); } }
3. 过滤器的执行顺序
-
**结论1:**Order越小越靠前执行
-
**结论2:**过滤器工厂的Order按配置顺序从1开始递增
-
**结论3:**如果配置了默认过滤器,则先执行相同Order的默认过滤器
-
**结论4:**如需自行控制Order,可返回OrderedGatewayFilter
五、Spring Cloud Gateway整合Sentinel
后面会讲到,再回来做总结
六、Spring Cloud Gateway监控
七、排错、调试技巧总结
八、Spring Cloud Gateway限流
本文地址:https://blog.csdn.net/banmingi/article/details/107147816
推荐阅读
-
基于Nacos实现Spring Cloud Gateway实现动态路由的方法
-
Spring Cloud Alibaba | Sentinel: 服务限流高级篇
-
Spring Cloud系列-Zuul网关集成JWT身份验证
-
Spring Cloud第七篇 | 声明式服务调用Feign
-
跟我学SpringCloud | 第十四篇:Spring Cloud Gateway高级应用
-
[Spring cloud 一步步实现广告系统] 11. 使用Feign实现微服务调用
-
微服务架构下使用Spring Cloud Zuul作为网关将多个微服务整合到一个Swagger服务上
-
Spring Cloud Alibaba | Nacos服务中心初探
-
spring cloud 入门系列八:使用spring cloud sleuth整合zipkin进行服务链路追踪
-
Spring Cloud下使用Feign Form实现微服务之间的文件上传