Spring Cloud Gateway 是 Spring Cloud 生态系统中的一个 API 网关组件,用于构建微服务架构中的路由、过滤和负载均衡等功能。它基于 Spring WebFlux 构建,支持非阻塞 I/O,适合高并发场景。以下是 Spring Cloud Gateway 的详细使用指南:
1. Spring Cloud Gateway 的核心概念
1.1 路由(Route)
路由是网关的基本构建块,用于将请求转发到指定的目标服务。每个路由包含:
-
ID:路由的唯一标识。
-
URI:目标服务的地址。
-
Predicates:匹配请求的条件。
-
Filters:对请求或响应进行处理的过滤器。
1.2 断言(Predicate)
断言用于匹配请求的条件,如路径、请求头、请求方法等。
1.3 过滤器(Filter)
过滤器用于在请求被路由之前或之后对请求或响应进行处理,如添加请求头、修改请求体等。
2. 快速开始
2.1 添加依赖
在 pom.xml
中添加 Spring Cloud Gateway 依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2.2 配置文件
在 application.yml
中配置路由:
spring:cloud:gateway:routes:- id: user-serviceuri: http://localhost:8081predicates:- Path=/user/**filters:- AddRequestHeader=X-Request-User, Gateway
2.3 启动应用
启动 Spring Boot 应用,网关会自动加载配置并生效。
3. 路由配置
3.1 基于配置文件的路由
在 application.yml
中配置路由:
spring:cloud:gateway:routes:- id: order-serviceuri: http://localhost:8082predicates:- Path=/order/**filters:- AddRequestHeader=X-Request-Order, Gateway
3.2 基于 Java 代码的路由
通过 RouteLocator
配置路由:
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {return builder.routes().route("order-service", r -> r.path("/order/**").filters(f -> f.addRequestHeader("X-Request-Order", "Gateway")).uri("http://localhost:8082")).build();
}
4. 断言(Predicate)
4.1 常用断言
-
Path:匹配请求路径。
-
Method:匹配请求方法。
-
Header:匹配请求头。
-
Query:匹配查询参数。
-
Cookie:匹配 Cookie。
4.2 示例
spring:cloud:gateway:routes:- id: user-serviceuri: http://localhost:8081predicates:- Path=/user/**- Method=GET- Header=X-Request-Id, \d+- Query=name, john- Cookie=sessionId, abc123
5. 过滤器(Filter)
5.1 常用过滤器
-
AddRequestHeader:添加请求头。
-
AddResponseHeader:添加响应头。
-
RewritePath:重写请求路径。
-
Retry:重试请求。
-
CircuitBreaker:熔断器。
5.2 示例
spring:cloud:gateway:routes:- id: user-serviceuri: http://localhost:8081predicates:- Path=/user/**filters:- AddRequestHeader=X-Request-User, Gateway- RewritePath=/user/(?<segment>.*), /$\{segment}- Retry=3- CircuitBreaker=myCircuitBreaker
6. 全局过滤器
6.1 自定义全局过滤器
实现 GlobalFilter
接口,定义全局过滤器:
@Component
public class CustomGlobalFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {exchange.getRequest().mutate().header("X-Global-Filter", "Applied");return chain.filter(exchange);}
}
6.2 内置全局过滤器
Spring Cloud Gateway 提供了一些内置的全局过滤器,如:
-
LoadBalancerClientFilter:负载均衡。
-
ForwardRoutingFilter:转发请求。
7. 负载均衡
7.1 使用 Spring Cloud LoadBalancer
在 application.yml
中配置负载均衡:
spring:cloud:gateway:routes:- id: user-serviceuri: lb://user-servicepredicates:- Path=/user/**
7.2 使用 Ribbon(已弃用)
在 application.yml
中配置 Ribbon:
user-service:ribbon:listOfServers: http://localhost:8081,http://localhost:8082
8. 熔断器
8.1 使用 Spring Cloud CircuitBreaker
在 application.yml
中配置熔断器:
spring:cloud:gateway:routes:- id: user-serviceuri: lb://user-servicepredicates:- Path=/user/**filters:- CircuitBreaker=myCircuitBreaker
8.2 自定义熔断器配置
在 application.yml
中配置熔断器参数:
resilience4j:circuitbreaker:instances:myCircuitBreaker:failureRateThreshold: 50minimumNumberOfCalls: 10waitDurationInOpenState: 10s
9. 限流
9.1 使用 Redis 限流
在 application.yml
中配置 Redis 限流:
spring:cloud:gateway:routes:- id: user-serviceuri: lb://user-servicepredicates:- Path=/user/**filters:- RequestRateLimiter=myRateLimiter
9.2 自定义限流配置
在 application.yml
中配置限流参数:
spring:redis:host: localhostport: 6379cloud:gateway:filter:request-rate-limiter:redis-enabled: truedefault-filter:replenish-rate: 10burst-capacity: 20
10. 监控与日志
10.1 使用 Actuator
在 pom.xml
中添加 Actuator 依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在 application.yml
中配置 Actuator:
management:endpoints:web:exposure:include: "*"
访问 /actuator/gateway/routes
查看路由信息。
总结
Spring Cloud Gateway 是一个强大的 API 网关,支持路由、过滤、负载均衡、熔断、限流等功能。通过合理配置,可以构建高性能、高可用的微服务网关。
Spring Cloud Gateway在微服务架构中扮演着至关重要的角色,主要作用包括路由转发、负载均衡、安全认证与授权、熔断与降级、请求限流、监控与日志以及过滤器功能1。
路由转发和负载均衡
Spring Cloud Gateway可以根据请求的特定条件(如URL路径、请求参数、请求头等)将请求转发到后端的多个服务。它支持动态路由配置,能够根据目标地址的不同选择最佳路径,并且可以进行协议转换,例如将HTTP请求转换成WebSocket请求12。通过集成服务注册中心(如Eureka、Consul、Zookeeper等),Gateway能够动态地从服务注册中心获取服务信息,并根据负载均衡策略将请求分发到不同的微服务实例,从而优化资源使用并提高系统的整体性能1。
安全认证与授权
Spring Cloud Gateway可以集成Spring Security等安全框架,为微服务提供安全认证和授权的功能。通过实施网络安全策略,对进出的数据包进行检查和过滤,验证和授权来自源网络的数据包,阻止未经授权的访问,从而保护微服务免受未经授权的访问和潜在的安全威胁12。
熔断与降级
Gateway支持熔断器模式,可以在微服务出现故障或超时时进行熔断,避免故障扩散到整个系统。同时也支持降级策略,当某个微服务出现故障时,可以通过返回默认值或其他备选方案来提供优雅降级,确保系统的稳定性和可用性1。
请求限流
通过配置限流规则,Spring Cloud Gateway能够限制对某个微服务的并发请求量或请求数量,防止恶意请求或异常情况下的流量冲击导致服务过载1。
监控与日志
Spring Cloud Gateway还提供监控与日志功能,帮助开发人员实时监控系统的运行状态和记录关键操作日志,便于故障排查和性能优化1。
过滤器功能
Gateway提供了丰富的过滤器功能,可以在请求路由前或路由后进行一些处理,如添加头部信息、修改请求体等。过滤器可以在全局范围或特定路由范围内配置,多个过滤器可以组成过滤器链,支持自定义过滤器以满足特定的业务需求23。
一、gateway网关的作用
1.身份认证,权限校验
2.路由转发,负载均衡
3.对用户请求做限流
二、创建gateway项目并且实现网关路由转发功能
1.新建model
2.引入依赖
<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>
3.编写yml配置文件
端口、注册naocs、gateway配置
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8845
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
4.图解
三、路由断言工厂(PredicateFactory)
1.路由断言工厂的作用
解析yml中写的Predicate字符串,转化为判断条件
2.11种路由断言工厂
a.11种断言的使用方法:
请转到这里查看=======>11种路由断言工厂-CSDN博客
3.思考题
四、路由的过滤器配置
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理。
1.过滤器种类
官方提供了三十多种过滤器,我们可以在需要时查看,部分过滤器如下:
2.流量染色
通过过滤器可以实现多种功能,例如流量染色,判断请求是否来源于gateway,如果不是gateway转发,将抛出异常。
实现:
application.yml:
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8845
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
filters:
- AddRequestHeader=passGateway, true
UserController.java
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id,
@RequestHeader(value = "PassGateway", required = false) boolean passGateway) {
if (!passGateway) {
throw new RuntimeException("passGateway is false");
}
System.out.println(passGateway);
return userService.queryById(id);
}
}
如果不经过gateway则抛出异常:
java.lang.RuntimeException: passGateway is false
at cn.itcast.user.web.UserController.queryById(UserController.java:45) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~
3.default-filters
给所有的路由请求请求加上过滤器:
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8845
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
# filters:
# - AddRequestHeader=passGateway, true
default-filters:
- AddRequestHeader=passGateway, true
五、全局过滤器(GlobalFilter)
1.实现全局过滤器
通过实现GlobalFilter接口,并且实现其中的filter方法即可定义全局过滤器
filter方法参数讲解:
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return null;
}
2.ServerWebExchange
接口包含以下重要方法:
getRequest():获取当前的HTTP请求对象。
getResponse():获取当前的HTTP响应对象。
getAttributes():获取与当前请求关联的属性map,可以用于在请求处理过程中共享数据。
getFormData():获取表单数据,返回一个Mono<MultiValueMap<String, String>>对象,可以使用flatMap操作符来处理表单数据。
mutate():创建一个新的ServerWebExchange实例,可以对请求和响应进行修改。
getSession():获取当前的会话对象,返回一个Mono<WebSession>对象,可以用于管理用户会话状态。
3.GatewayFilterChain
GatewayFilterChain是 Spring Cloud Gateway 中的一个接口,用于定义一系列的过滤器链。在请求进入网关后,会经过一系列的过滤器对请求进行处理和转换,然后再转发到后端服务。
GatewayFilterChain接口定义了一个 filter方法,调用该filter方法表示放行。
chain.filter(exchange);
六、过滤器链执行顺序
1.三种过滤器的处理
gateway中有三种过滤器:Default过滤器、路由过滤器、全局过滤器
Default过滤器和路由过滤器回通过AddRequestHeaderGatrewayFilterFactory这个工厂类转化为GatewayFilter类型的拦截器
【注】AddRequestHeaderGatrewayFilterFactory不是所有的Default过滤器和路由过滤器都是这个工厂类处理,而是对应filter配置文件中写的过滤器对应的工厂类。
全局过滤器会通过GatewayFilterAdapter类转换成GatewayFilter类型的类
2.执行顺序
七、网关的cors跨域配置
跨域问题:浏览器禁止请求的发起者与服务端发生跨域的Ajax请求
解决方案:
globalcors:
add-to-simple-url-handler-mapping: true
corsConfigurations:
'[/**]':
allowedOrigins: # 允许跨域访问的地址
- "http://localhost:8080"
- "www.baidu.com"
allowedMethods: # 允许跨域访问的请求方式
- "GET"
- "POST"
- "PUT"
- "DELETE"
allowedHeaders: # 允许请求头中携带的字段
- "*"
allowCredentials: true #是否允许携带cookies
exposedHeaders: # 允许跨域访问的响应头
- "*"
maxAge: 3600
踩坑日志:网关配置跨域之后,如果每个服务重新配置跨域,例如使用@CrossOrign注解,会导致出错