1. 基本路由配置
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://USER-SERVICE # 使用负载均衡
predicates:
- Path=/user/**
filters:
- StripPrefix=1
说明:
-
id:路由的唯一 ID -
uri:目标服务地址,支持http://、lb://(负载均衡) -
predicates:断言规则,决定请求是否匹配该路由 -
filters:过滤规则,对请求或响应进行修改
2. 断言(Predicates)
Spring Cloud Gateway 提供了多种请求匹配规则(断言),可以用来判断某个请求是否符合当前路由。
常见断言
predicates:
- Path=/api/** # 匹配路径
- Method=GET,POST # 限制 HTTP 方法
- Host=**.example.*** # 匹配域名
- Header=X-Request-Id, \d+ # 请求头匹配
- Query=token # 请求参数必须包含 token
- Before=2025-12-31T23:59:59.999Z # 在某个时间之前生效
- After=2025-01-01T00:00:00.000Z # 在某个时间之后生效
- Between=2025-01-01T00:00:00.000Z, 2025-12-31T23:59:59.999Z # 时间范围
- RemoteAddr=192.168.1.1/24 # 限制 IP 地址
- Weight=group1, 5 # 按指定权重负载均衡,group1 组内权重为 5
- Cookie=SESSIONID, abc123 # 包含名为 SESSIONID 的 Cookie,且值必须匹配 abc123
- XForwardedRemoteAddr=192.168.1.0/24 # 从 X-Forwarded-For 请求头解析 IP,限制来源于
192.168.1.0/24 网段
这里要求访问路径要求满足Path和Query才会访问uri
3. 过滤器(Filters)
过滤器用于修改请求或响应,可以在网关层面进行鉴权、限流、日志记录等操作。
常见过滤器
filters:
- StripPrefix=1 # 去掉第一级路径
- AddRequestHeader=Token, abc123 # 给请求添加请求头
- AddResponseHeader=X-Response, OK # 给响应添加请求头
- RewritePath=/api/(?<segment>.*), /newpath/$\{segment} # 路径重写
- SetStatus=404 # 修改返回状态码
- Retry=5 # 失败重试 5 次
- RequestRateLimiter=redis-rate-limiter # 基于 Redis 令牌桶算法限流
4. 全局超时设置
可以配置连接超时、读取超时,防止服务长时间无响应:
spring:
cloud:
gateway:
httpclient:
connect-timeout: 5000 # 连接超时 5 秒
response-timeout: 10s # 读取超时 10 秒
5. CORS 跨域配置
如果前端需要跨域访问 API,需要在网关中开启 CORS:
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]': # 匹配所有路径
allowedOrigins: "https://example.***" # 允许的来源
allowedMethods: # 允许的请求方法
- GET
- POST
- PUT
- DELETE
allowedHeaders: "*" # 允许所有请求头
allowCredentials: true # 允许携带 Cookie
6. 限流(Request Rate Limiting)
Spring Cloud Gateway 支持基于 Redis 的令牌桶限流,限制单位时间内的请求数:
spring:
cloud:
gateway:
routes:
- id: limit_route
uri: http://localhost:8080
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒补充 10 个令牌
redis-rate-limiter.burstCapacity: 20 # 令牌桶最大容量
key-resolver: "#{@ipKeyResolver}" # 根据 IP 进行限流
💡 需要在
@Bean中定义ipKeyResolver
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostString());
}
7. 负载均衡(Load Balancer)
Spring Cloud Gateway 可与 Spring Cloud LoadBalancer 结合,动态选择可用的微服务:
spring:
cloud:
gateway:
routes:
- id: service-route
uri: lb://USER-SERVICE # 通过服务名进行负载均衡
predicates:
- Path=/user/**
⚠️ 需要引入 spring-cloud-starter-loadbalancer 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
8. 断路器(Circuit Breaker)
Spring Cloud Gateway 可以与 Resilience4j 结合,避免微服务雪崩:
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fallback
💡 需要配置 Resilience4j
resilience4j:
circuitbreaker:
instances:
myCircuitBreaker:
sliding-window-size: 10
failure-rate-threshold: 50
wait-duration-in-open-state: 5000ms
9. 日志 & 监控
可以启用 Spring Boot Actuator 进行监控:
management:
endpoints:
web:
exposure:
include: gateway
10.自定义断言工厂
创建一个“时间范围”断言工厂,控制请求只能在指定时间范围内访问
(1)创建自定义 Predicate 工厂类
在 Spring Cloud Gateway 中,自定义断言工厂必须继承 AbstractRoutePredicateFactory<T>,并且 类名必须以 RoutePredicateFactory 结尾。
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.***ponent;
import java.time.LocalTime;
import java.util.function.Predicate;
import org.springframework.web.server.ServerWebExchange;
@***ponent
public class TimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<TimeBetweenRoutePredicateFactory.Config> {
public TimeBetweenRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
// 获取当前时间
LocalTime now = LocalTime.now();
// 检查当前时间是否在配置的时间范围内
return now.isAfter(config.getStartTime()) && now.isBefore(config.getEndTime());
};
}
// 这个方法用于绑定 yml 配置中的参数
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("startTime", "endTime");
}
// 配置类
public static class Config {
private LocalTime startTime;
private LocalTime endTime;
public LocalTime getStartTime() {
return startTime;
}
public void setStartTime(LocalTime startTime) {
this.startTime = startTime;
}
public LocalTime getEndTime() {
return endTime;
}
public void setEndTime(LocalTime endTime) {
this.endTime = endTime;
}
}
}
📌 解释
-
继承
AbstractRoutePredicateFactory<Config>:- 这里的
Config是一个内部类,用于接收 YAML 配置中的参数(startTime和endTime)。
- 这里的
-
apply(Config config):- 逻辑:获取当前时间,判断是否在
startTime和endTime之间。
- 逻辑:获取当前时间,判断是否在
-
shortcutFieldOrder():- 指定
YAML配置中参数的顺序(必须与Config类的字段一致)。
- 指定
-
exchange是 Spring Cloud Gateway 处理请求时,由 WebFlux 框架自动创建并传递的,你只需要在 过滤器、断言工厂等组件 中直接使用它即可
(2)在 application.yml 中使用
spring:
cloud:
gateway:
routes:
- id: time_based_route
uri: http://localhost:8080
predicates:
- name: TimeBetween
args:
startTime: "08:00"
endTime: "18:00"
📌 解释
- 这个路由规则表示:只能在 08:00 - 18:00 之间访问,否则请求不会被转发。
假设你要拦截某些特定的 User-Agent(比如禁止 curl 访问):
(1)基于 User-Agent 判断
@***ponent
public class UserAgentRoutePredicateFactory extends AbstractRoutePredicateFactory<UserAgentRoutePredicateFactory.Config> {
public UserAgentRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
String userAgent = exchange.getRequest().getHeaders().getFirst("User-Agent");
return userAgent != null && !userAgent.toLowerCase().contains(config.getBlockedUserAgent().toLowerCase());
};
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("blockedUserAgent");
}
public static class Config {
private String blockedUserAgent;
public String getBlockedUserAgent() {
return blockedUserAgent;
}
public void setBlockedUserAgent(String blockedUserAgent) {
this.blockedUserAgent = blockedUserAgent;
}
}
}
(2)YAML 配置
spring:
cloud:
gateway:
routes:
- id: block_curl
uri: http://localhost:8080
predicates:
- name: UserAgent
args:
blockedUserAgent: "curl"
📌 效果
- 如果
User-Agent包含"curl",请求将被拦截。
11.过滤器详述
在 Spring Cloud Gateway 中,过滤器(Filter) 是网关处理请求的重要组成部分。它可以对请求和响应进行拦截、修改或增强,比如:
- 权限认证(JWT 解析、OAuth2 认证)
- 日志记录(记录请求时间、请求路径)
- 限流处理(Redis 令牌桶限流)
- 修改请求(添加/删除 Header、修改 Body)
- 修改响应(统一返回格式、添加 CORS 头)
📌 1. 过滤器的分类
Spring Cloud Gateway 过滤器分为 两大类:
| 类型 | 作用 | 执行顺序 |
|---|---|---|
| GatewayFilter(局部过滤器) |
针对单个路由生效,只能在 application.yml 的 routes 里配置 |
在请求匹配到某个路由后执行 |
| GlobalFilter(全局过滤器) | 对所有路由生效,用于全局日志、权限认证等 | 所有请求都会执行 |
📌 2. 局部过滤器(GatewayFilter)
(1)常见内置过滤器
Spring Cloud Gateway 提供了很多 内置的 GatewayFilter,可以直接在 application.yml 里配置:
spring:
cloud:
gateway:
routes:
- id: my_route
uri: http://localhost:8080
predicates:
- Path=/api/**
filters:
- AddRequestHeader=Authorization, Bearer 123456 # 添加请求头
- AddResponseHeader=X-Response-Time, 100ms # 添加响应头
- RewritePath=/old/(?<segment>.*), /new/$\{segment} # 修改请求路径
- RemoveRequestParameter=token # 移除请求参数
📌 内置过滤器说明
| 过滤器 | 作用 |
|---|---|
AddRequestHeader |
添加请求头(示例:Authorization: Bearer 123456) |
AddResponseHeader |
添加响应头(示例:X-Response-Time: 100ms) |
RewritePath |
修改请求路径(示例:/old/user → /new/user) |
RemoveRequestParameter |
删除指定的请求参数 |
(2)自定义局部过滤器
如果内置 GatewayFilter 不能满足需求,可以自定义过滤器,比如统计请求时间:
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.***ponent;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@***ponent
public class RequestTimeGatewayFilterFactory extends AbstractGatewayFilterFactory<RequestTimeGatewayFilterFactory.Config> {
public RequestTimeGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
long startTime = System.currentTimeMillis();
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
long endTime = System.currentTimeMillis();
System.out.println("请求耗时:" + (endTime - startTime) + "ms");
}));
};
}
public static class Config {
// 这里可以添加需要的配置参数
}
}
📌 如何在 application.yml 里使用?
spring:
cloud:
gateway:
routes:
- id: time_filter_route
uri: http://localhost:8080
predicates:
- Path=/api/**
filters:
- name: RequestTime
📌 效果
- 这个过滤器会计算每个请求的耗时并打印日志。
📌 3. 全局过滤器(GlobalFilter)
如果你想对所有请求进行拦截(比如日志记录、鉴权),需要使用 GlobalFilter。
(1)定义全局过滤器
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.stereotype.***ponent;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@***ponent
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("🔹 全局过滤器:请求路径 " + exchange.getRequest().getURI().getPath());
// 继续执行下一个过滤器
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
System.out.println("🔹 响应返回,状态码:" + exchange.getResponse().getStatusCode());
}));
}
@Override
public int getOrder() {
return -1; // 数字越小,优先级越高(-1 代表最早执行)
}
}
📌 解释
-
GlobalFilter:全局生效,无需在application.yml里配置,所有请求都会执行。 -
Ordered:用于控制执行顺序,数字越小优先级越高(-1 代表最早执行)。
(2)高级示例:JWT 认证
如果你需要拦截请求并校验 JWT 令牌:
@***ponent
public class JwtAuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().set***plete();
}
return chain.filter(exchange); // 继续请求
}
@Override
public int getOrder() {
return -10; // 优先级比默认 GlobalFilter 高
}
}
📌 效果
- 如果请求头里没有
Authorization或者格式不正确,返回401 Unauthorized。
📌 4. 过滤器执行顺序
🌟 过滤器执行流程
1️⃣ GlobalFilter(前置逻辑)
2️⃣ GatewayFilter(局部过滤器)
3️⃣ 真正访问目标服务(http://localhost:8080)
4️⃣ GatewayFilter(后置逻辑)
5️⃣ GlobalFilter(后置逻辑)
✅ 总结
| 过滤器类型 | 生效范围 | 适用场景 | 定义方式 |
|---|---|---|---|
| GatewayFilter(局部) | 只针对某个路由 | 日志记录、参数修改、Header 操作 |
application.yml 或 AbstractGatewayFilterFactory
|
| GlobalFilter(全局) | 所有请求都会经过 | JWT 鉴权、日志、全局限流 |
GlobalFilter 接口 |
📌5.Spring Cloud Gateway 实现全局跨域(CORS 配置)
1. 在 application.yml 中配置 CORS(推荐 ✅)
Spring Cloud Gateway 支持直接在 application.yml 配置跨域,简单方便:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]': # 允许所有路径
allowedOrigins: "*" # 允许所有来源(可指定前端域名,如 "http://example.***")
allowedMethods: "*" # 允许所有请求方法(GET, POST, PUT, DELETE等)
allowedHeaders: "*" # 允许所有请求头
allowCredentials: true # 允许携带 Cookie
✅ 优点:
- 配置简单,适用于大多数场景。
- 支持 Spring Boot 2.4+ 及 Spring Cloud Gateway 原生跨域处理。
2. 使用 CorsWebFilter 配置全局 CORS
如果 application.yml 配置不生效,可以使用 CorsWebFilter 代码配置:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsWebFilter;
import java.util.Arrays;
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("*")); // 允许所有来源
config.setAllowedMethods(Arrays.asList("*")); // 允许所有请求方法
config.setAllowedHeaders(Arrays.asList("*")); // 允许所有请求头
config.setAllowCredentials(true); // 允许携带 Cookie
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
✅ 优点:
- 代码方式更灵活,可以动态配置。
- 可以针对不同路径设置不同 CORS 规则。
3. 在 GlobalFilter 里手动设置 CORS 响应头
如果 CorsWebFilter 也无法满足需求,你可以在自定义全局过滤器里手动设置 CORS 头:
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.***ponent;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@***ponent
public class CorsGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add("A***ess-Control-Allow-Origin", "*"); // 允许所有域
headers.add("A***ess-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
headers.add("A***ess-Control-Allow-Headers", "*");
headers.add("A***ess-Control-Allow-Credentials", "true");
// 处理 OPTIONS 预检请求
if (exchange.getRequest().getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(org.springframework.http.HttpStatus.OK);
return response.set***plete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
✅ 适用于特殊场景:
- 想在某个全局过滤器里控制跨域
- 对
OPTIONS预检请求做特殊处理 - 动态调整跨域规则