Spring Cloud Gateway 详细示例 元一软件
·
Spring Cloud Gateway 是基于 Spring WebFlux 的响应式微服务网关,核心能力:路由转发、断言匹配、过滤器链、限流、鉴权、灰度等。以下从基础搭建、核心配置、高级功能提供完整可运行示例。
一、环境准备与项目搭建
1. 版本选择(推荐稳定组合)
- Spring Boot:3.2.x
- Spring Cloud:2023.0.x(Leyton)
- JDK:17+
- 注册中心:Nacos 2.x(用于服务发现)
2. 核心依赖(Maven pom.xml)
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
</parent>
<dependencies>
<!-- Gateway 核心依赖(自动集成 WebFlux,禁止引入 spring-boot-starter-web) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Nacos 服务发现(实现 lb:// 负载均衡路由) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2023.0.1.0</version>
</dependency>
<!-- 负载均衡依赖(服务名路由必须) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- Redis 限流依赖(可选) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2023.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3. 启动类(无额外注解,自动配置)
java
运行
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 启用 Nacos 服务发现
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
二、基础路由配置(application.yml)
1. 静态路由(直接转发到固定地址)
yaml
server:
port: 9999 # 网关端口
spring:
application:
name: gateway-demo
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # Nacos 地址
gateway:
routes:
- id: static-route # 路由唯一ID(不可重复)
uri: http://httpbin.org # 目标地址(静态)
predicates: # 断言(匹配条件)
- Path=/get/** # 路径匹配 /get/** 时转发
filters: # 过滤器(请求/响应处理)
- AddRequestHeader=X-Gateway, SpringCloudGateway # 添加请求头
- RewritePath=/get/(?<segment>.*), /$\{segment} # 路径重写:/get/hello → /hello
2. 服务发现路由(lb:// 负载均衡)
yaml
spring:
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service # lb:// + 服务名(Nacos 中注册的服务)
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1 # 去掉路径前缀:/api/user/1 → /1(转发到 user-service)
- AddResponseHeader=X-Response-From, Gateway # 添加响应头
# 自动服务发现路由(开启后,可直接通过 /服务名/** 访问)
discovery:
locator:
enabled: true # 开启自动路由
lower-case-service-id: true # 服务名小写
三、常用断言与过滤器示例
1. 常用断言(Predicates)
yaml
spring:
cloud:
gateway:
routes:
- id: predicate-demo
uri: lb://order-service
predicates:
- Path=/api/order/** # 路径匹配
- Method=GET,POST # 请求方法匹配
- Header=X-Request-Id, \d+ # 请求头匹配(正则)
- Query=token, .+ # 请求参数匹配
- After=2026-01-01T00:00:00+08:00 # 时间之后生效
- Before=2026-12-31T23:59:59+08:00 # 时间之前生效
- Between=2026-01-01T00:00:00+08:00,2026-12-31T23:59:59+08:00 # 时间区间
2. 常用过滤器(Filters)
yaml
spring:
cloud:
gateway:
routes:
- id: filter-demo
uri: lb://product-service
predicates:
- Path=/api/product/**
filters:
- StripPrefix=1 # 去掉1级前缀
- AddRequestHeader=X-User-Id, 1001 # 添加请求头
- AddRequestParameter=source, gateway # 添加请求参数
- AddResponseHeader=X-Result, Success # 添加响应头
- SetStatus=404 # 设置响应状态码
- RewritePath=/api/product/(?<id>.*), /product/$\{id} # 路径重写
四、高级功能实战
1. 全局过滤器(统一鉴权)
场景:所有请求必须携带 Token,否则返回 401。
java
运行
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 获取请求头 Token
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
// 2. 校验 Token(实际对接认证服务/Redis)
if (token == null || !token.startsWith("Bearer ")) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 3. Token 有效,继续转发
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE; // 最高优先级(最先执行)
}
}
2. Redis 限流(令牌桶算法)
配置(application.yml)
yaml
spring:
redis:
host: 127.0.0.1
port: 6379
cloud:
gateway:
routes:
- id: rate-limit-route
uri: lb://pay-service
predicates:
- Path=/api/pay/**
filters:
- StripPrefix=1
- name: RequestRateLimiter # 限流过滤器
args:
redis-rate-limiter.replenishRate: 10 # 每秒生成10个令牌
redis-rate-limiter.burstCapacity: 20 # 最大令牌数(突发流量)
key-resolver: "#{@ipKeyResolver}" # 限流维度(IP/用户ID)
限流维度配置(IP 限流)
java
运行
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
@Configuration
public class RateLimitConfig {
// IP 限流(按客户端 IP 限流)
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
);
}
// 用户ID 限流(可选,从请求头/参数获取)
@Bean
public KeyResolver userIdKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getHeaders().getFirst("X-User-Id")
);
}
}
3. 自定义路由断言(灰度发布)
场景:根据请求头 X-Gray-Tag=beta 转发到灰度服务。
java
运行
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
@Component
public class GrayRoutePredicateFactory extends AbstractRoutePredicateFactory<GrayRoutePredicateFactory.Config> {
public GrayRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
String grayTag = exchange.getRequest().getHeaders().getFirst("X-Gray-Tag");
return config.getTag().equals(grayTag);
};
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("tag"); // 配置参数名
}
// 配置类
public static class Config {
private String tag;
public String getTag() { return tag; }
public void setTag(String tag) { this.tag = tag; }
}
}
灰度路由配置
yaml
spring:
cloud:
gateway:
routes:
# 灰度路由:X-Gray-Tag=beta → 转发到 beta 服务
- id: order-gray-route
uri: lb://order-service-beta
predicates:
- Path=/api/order/**
- Gray=beta # 自定义断言
filters:
- StripPrefix=1
# 普通路由:其他请求 → 转发到正式服务
- id: order-normal-route
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
4. 全链路日志过滤器
java
运行
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class LoggingGlobalFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(LoggingGlobalFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 记录请求日志
log.info("Request: {} {} from {}",
exchange.getRequest().getMethod(),
exchange.getRequest().getPath(),
exchange.getRequest().getRemoteAddress());
// 记录响应日志
return chain.filter(exchange).doOnSuccess(v ->
log.info("Response: {} for {}",
exchange.getResponse().getStatusCode(),
exchange.getRequest().getPath())
);
}
@Override
public int getOrder() {
return -1; // 早于鉴权过滤器
}
}
五、测试与验证
1. 启动服务
- 启动 Nacos(端口 8848)
- 启动 user-service、order-service 等微服务(注册到 Nacos)
- 启动 Gateway 服务(端口 9999)
2. 测试请求
bash
运行
# 测试静态路由
curl http://localhost:9999/get/headers
# 测试服务发现路由
curl http://localhost:9999/api/user/1001
# 测试鉴权(无 Token → 401)
curl http://localhost:9999/api/order/1
# 测试鉴权(携带 Token → 成功)
curl -H "Authorization: Bearer test_token" http://localhost:9999/api/order/1
# 测试灰度路由
curl -H "X-Gray-Tag: beta" http://localhost:9999/api/order/1
六、生产环境建议
- 高可用:部署多个 Gateway 实例,前端用 Nginx 负载均衡
- 监控:集成 Prometheus + Grafana 监控网关指标
- 熔断:集成 Sentinel 实现服务熔断降级
- 安全:开启 HTTPS、请求参数校验、防 SQL 注入
- 日志:集成 ELK 统一日志管理
更多推荐

所有评论(0)