
前言
在微服务架构中,网关是整个系统的 "入口门面",负责请求路由、流量控制、权限校验、日志监控等核心功能。Spring Cloud Gateway 作为 Spring 官方推出的第二代网关(替代 Zuul),基于 Netty 非阻塞 IO 模型,具有性能高、功能强、易扩展等优势,完美适配微服务高并发场景。
本文将从 "原理→实战→进阶→生产落地" 全方位拆解 Spring Cloud Gateway,不仅覆盖路由配置、过滤器开发、限流鉴权等核心场景,还提供可直接复制的配置模板和避坑指南。内容兼顾新手入门与老手优化,既有基础操作的 step-by-step 教程,也有底层原理和生产级优化技巧,助力你快速掌握网关实战能力。
1. 为什么选择 Spring Cloud Gateway?核心优势与架构原理
1.1 核心优势(对比 Zuul)
- 性能优异:基于 Netty 响应式编程,非阻塞 IO 模型,吞吐量是 Zuul 1.x 的 3 倍以上
- 功能强大:原生支持路由、过滤、限流、熔断、重试等核心功能,无需额外集成
- 易扩展:基于 Spring 生态,支持自定义过滤器、路由断言,适配各种业务场景
- 无缝整合:与 Spring Cloud Alibaba、Nacos、Sentinel 等组件完美兼容
- 支持 WebSocket:原生支持 WebSocket 协议,适合实时通信场景(如消息推送)
1.2 核心架构原理
Spring Cloud Gateway 的核心是 "路由(Route)+ 断言(Predicate)+ 过滤器(Filter)" 的三元组模型:

- 路由(Route):网关的基本单元,包含 ID、目标 URI、断言集合、过滤器集合
- 断言(Predicate):路由匹配规则,如路径、方法、参数、Header 等,满足条件则转发
- 过滤器(Filter):请求 / 响应的拦截器,分全局过滤器(对所有路由生效)和局部过滤器(对指定路由生效)
1.3 核心流程拆解
- 客户端发送请求到 Gateway
- 网关根据断言(Predicate)匹配对应的路由
- 请求经过 "前置过滤器链" 处理(如鉴权、日志、限流)
- 网关将请求转发到目标微服务
- 微服务返回响应,经过 "后置过滤器链" 处理(如响应改写、数据加密)
- 网关将最终响应返回给客户端
2. 快速上手:3 步搭建基础网关(附完整配置)
2.1 环境准备
- 技术栈:SpringBoot 2.7.x + SpringCloud 2021.0.4 + SpringCloud Gateway 3.1.4
- 注册中心:Nacos 2.2.3(服务发现)
- 微服务:已部署
user-service、order-service(作为路由目标服务)
2.2 步骤 1:引入核心依赖
XML
<!-- Spring Cloud Gateway核心依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Nacos服务发现依赖(网关需从注册中心获取服务列表) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringBoot Actuator(监控用,可选) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
注意:Gateway 基于响应式编程,不能引入 spring-boot-starter-web 依赖(会导致 Netty 冲突)
2.3 步骤 2:配置 application.yml
bash
spring:
application:
name: gateway-service # 网关服务名
cloud:
# Nacos配置
nacos:
discovery:
server-addr: 127.0.0.1:8848 # Nacos地址
# Gateway配置
gateway:
# 路由配置(静态路由)
routes:
# 路由1:转发到用户服务
- id: user-service-route # 路由唯一ID(自定义)
uri: lb://user-service # 目标服务名(lb=loadbalance,负载均衡)
predicates:
- Path=/api/user/** # 路径断言:匹配/api/user/开头的请求
filters:
- StripPrefix=1 # 过滤规则:去除路径前缀1级(/api/user/get → /user/get)
# 路由2:转发到订单服务
- id: order-service-route
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
# 端口配置(网关端口)
server:
port: 8080
# 监控配置(暴露路由信息)
management:
endpoints:
web:
exposure:
include: gateway,health,info # 暴露gateway端点
endpoint:
gateway:
enabled: true # 启用网关监控端点
2.4 步骤 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 GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
2.5 测试验证
- 启动 Nacos、
user-service、order-service、gateway-service - 访问网关地址:
http://localhost:8080/api/user/get/1→ 转发到user-service的/user/get/1接口 - 访问
http://localhost:8080/api/order/create→ 转发到order-service的/order/create接口 - 访问监控端点:
http://localhost:8080/actuator/gateway/routes→ 查看所有路由配置
3. 路由配置实战:静态路由 + 动态路由(Nacos 适配)
路由是 Gateway 的核心,分为静态路由(配置文件)和动态路由(配置中心),动态路由支持配置热更新,无需重启网关。
3.1 静态路由:多种匹配规则(Predicate)
除了路径匹配,Gateway 支持多种断言规则,可组合使用:
bash
spring:
cloud:
gateway:
routes:
- id: multi-predicate-route
uri: lb://user-service
predicates:
# 1. 路径匹配:/api/user/** 或 /api/member/**
- Path=/api/user/**,/api/member/**
# 2. 请求方法匹配:GET/POST
- Method=GET,POST
# 3. 参数匹配:必须包含userId参数(值可为任意)
- Query=userId
# 4. Header匹配:必须包含Authorization头
- Header=Authorization
# 5. 时间匹配:2024-01-01 00:00:00后生效
- After=2024-01-01T00:00:00+08:00[Asia/Shanghai]
filters:
- StripPrefix=1
3.2 动态路由:基于 Nacos 实现热更新
静态路由修改后需重启网关,生产环境推荐使用动态路由,通过 Nacos 配置中心实现配置实时刷新。
3.2.1 引入 Nacos 配置依赖
XML
<!-- Nacos配置中心依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
3.2.2 配置 bootstrap.yml(优先级高于 application.yml)
bash
spring:
application:
name: gateway-service
cloud:
nacos:
# 配置中心
config:
server-addr: 127.0.0.1:8848
file-extension: yaml # 配置文件格式
group: DEFAULT_GROUP # 配置分组
# 服务发现
discovery:
server-addr: 127.0.0.1:8848
3.2.3 在 Nacos 中创建配置
- 登录 Nacos 控制台 → 配置管理 → 配置列表 → 新建
- 配置信息:
- 数据 ID:
gateway-service.yaml(服务名 + 文件格式) - 分组:
DEFAULT_GROUP - 配置内容(路由配置):
- 数据 ID:
bash
spring:
cloud:
gateway:
routes:
- id: dynamic-user-route
uri: lb://user-service
predicates:
- Path=/dynamic/user/**
filters:
- StripPrefix=1
- id: dynamic-order-route
uri: lb://order-service
predicates:
- Path=/dynamic/order/**
filters:
- StripPrefix=1
3.2.4 编写动态路由配置类
java
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;
@Configuration
public class DynamicRouteConfig {
// 路由定义写入器(用于动态更新路由)
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
// Nacos配置属性
@Autowired
private NacosConfigProperties nacosConfigProperties;
// 配置ID(与Nacos中一致)
private static final String DATA_ID = "gateway-service.yaml";
// 配置分组
private static final String GROUP = "DEFAULT_GROUP";
// 项目启动时加载路由,且监听配置变化
@PostConstruct
public void dynamicRouteByNacos() throws NacosException {
// 1. 初始化Nacos配置服务
Properties properties = new Properties();
properties.put("serverAddr", nacosConfigProperties.getServerAddr());
ConfigService configService = NacosFactory.createConfigService(properties);
// 2. 首次加载配置
String configInfo = configService.getConfig(DATA_ID, GROUP, 5000);
updateRoute(configInfo);
// 3. 监听配置变化(热更新)
configService.addListener(DATA_ID, GROUP, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
// 配置变化时更新路由
updateRoute(configInfo);
}
});
}
// 解析配置并更新路由
private void updateRoute(String configInfo) {
// 解析Nacos配置中的routes节点
GatewayConfig gatewayConfig = JSON.parseObject(configInfo, GatewayConfig.class);
List<RouteDefinition> routeDefinitions = gatewayConfig.getSpring().getCloud().getGateway().getRoutes();
// 先删除所有旧路由
routeDefinitions.forEach(route -> {
routeDefinitionWriter.delete(Mono.just(route.getId())).subscribe();
});
// 再添加新路由
routeDefinitions.forEach(route -> {
routeDefinitionWriter.save(Mono.just(route)).subscribe();
});
}
// 自定义配置类(对应Nacos中的配置结构)
static class GatewayConfig {
private Spring spring;
// getter/setter
public Spring getSpring() { return spring; }
public void setSpring(Spring spring) { this.spring = spring; }
static class Spring {
private Cloud cloud;
// getter/setter
public Cloud getCloud() { return cloud; }
public void setCloud(Cloud cloud) { this.cloud = cloud; }
}
static class Cloud {
private Gateway gateway;
// getter/setter
public Gateway getGateway() { return gateway; }
public void setGateway(Gateway gateway) { this.gateway = gateway; }
}
static class Gateway {
private List<RouteDefinition> routes;
// getter/setter
public List<RouteDefinition> getRoutes() { return routes; }
public void setRoutes(List<RouteDefinition> routes) { this.routes = routes; }
}
}
}
3.2.5 测试动态路由
- 修改 Nacos 中的路由配置(如添加新路由、修改路径匹配规则)
- 无需重启网关,访问新路由地址 → 直接生效
- 访问
http://localhost:8080/actuator/gateway/routes→ 查看更新后的路由
4. 过滤器开发:全局过滤器 + 局部过滤器(含实战案例)
Gateway 的过滤器分为全局过滤器 (对所有路由生效)和局部过滤器(仅对指定路由生效),核心作用是对请求 / 响应进行拦截增强。
4.1 过滤器执行顺序

- 前置过滤器(Pre):请求转发前执行(如鉴权、日志、参数改写)
- 后置过滤器(Post):响应返回前执行(如响应加密、数据格式化)
4.2 全局过滤器实战:3 个高频场景
4.2.1 场景 1:全局日志打印(记录请求响应)
java
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
@Configuration
public class GlobalLogFilterConfig {
// Order值越小,执行优先级越高
@Bean
@Order(-100)
public GlobalFilter logFilter() {
return (exchange, chain) -> {
// 1. 前置处理:记录请求信息
String path = exchange.getRequest().getPath().value();
String method = exchange.getRequest().getMethod().name();
String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
System.out.printf("[%s] 收到请求:IP=%s, 方法=%s, 路径=%s%n",
LocalDateTime.now(), ip, method, path);
// 2. 继续执行后续过滤器
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
// 3. 后置处理:记录响应信息
int statusCode = exchange.getResponse().getStatusCode().value();
System.out.printf("[%s] 响应结果:状态码=%s, 路径=%s%n",
LocalDateTime.now(), statusCode, path);
}));
};
}
}
4.2.2 场景 2:全局跨域处理(解决前后端跨域)
java
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import reactor.core.publisher.Mono;
@Configuration
public class GlobalCorsFilterConfig {
@Bean
@Order(-101)
public GlobalFilter corsFilter() {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
// 允许所有源跨域
response.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
// 允许的请求头
response.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
// 允许的请求方法
response.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,PUT,DELETE,OPTIONS");
// 预检请求缓存时间
response.getHeaders().add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3600");
// 处理OPTIONS预检请求
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
return chain.filter(exchange);
};
}
}
4.2.3 场景 3:全局鉴权过滤器(JWT Token 验证)
java
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Mono;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class GlobalAuthFilterConfig {
// 放行的白名单(无需鉴权的路径)
private static final List<String> WHITE_LIST = new ArrayList<>();
static {
WHITE_LIST.add("/api/user/login");
WHITE_LIST.add("/api/user/register");
WHITE_LIST.add("/actuator/**");
}
// JWT密钥(生产环境需配置在Nacos,避免硬编码)
private static final String JWT_SECRET = "your-secret-key-32bytes-long-123456";
private final SecretKey secretKey = Keys.hmacShaKeyFor(JWT_SECRET.getBytes(StandardCharsets.UTF_8));
@Bean
@Order(-99) // 优先级高于日志过滤器
public GlobalFilter authFilter() {
return (exchange, chain) -> {
String path = exchange.getRequest().getPath().value();
// 1. 白名单路径直接放行
if (WHITE_LIST.stream().anyMatch(path::startsWith)) {
return chain.filter(exchange);
}
// 2. 从Header获取Token
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (!StringUtils.hasText(token) || !token.startsWith("Bearer ")) {
// Token不存在,返回401
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 3. 验证Token有效性
token = token.substring(7); // 去除Bearer前缀
try {
Claims claims = Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token)
.getBody();
// 4. Token有效,将用户信息存入请求头(传递给微服务)
String userId = claims.get("userId", String.class);
ServerHttpRequest request = exchange.getRequest().mutate()
.header("X-User-Id", userId)
.build();
return chain.filter(exchange.mutate().request(request).build());
} catch (Exception e) {
// Token无效/过期,返回401
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
};
}
}
4.3 局部过滤器实战:请求改写与响应处理
局部过滤器仅对指定路由生效,需实现GatewayFilter接口:
java
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
// 局部过滤器:给请求添加固定参数
@Component
public class AddParamGatewayFilterFactory extends AbstractGatewayFilterFactory<AddParamGatewayFilterFactory.Config> {
// 配置类(接收过滤器参数)
public static class Config {
private String paramName; // 参数名
private String paramValue; // 参数值
// getter/setter
public String getParamName() { return paramName; }
public void setParamName(String paramName) { this.paramName = paramName; }
public String getParamValue() { return paramValue; }
public void setParamValue(String paramValue) { this.paramValue = paramValue; }
}
public AddParamGatewayFilterFactory() {
super(Config.class);
}
// 配置参数的默认顺序(用于yml配置)
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("paramName", "paramValue");
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
// 给请求添加固定参数
ServerHttpRequest request = exchange.getRequest().mutate()
.queryParam(config.getParamName(), config.getParamValue())
.build();
return chain.filter(exchange.mutate().request(request).build());
};
}
}
局部过滤器使用(在路由中配置)
bash
spring:
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
# 局部过滤器:添加paramName=version,paramValue=v1.0
- AddParam=version,v1.0
5. 限流鉴权核心实现:基于 Redis 的限流 + JWT 鉴权
5.1 限流实现:基于 Redis 的令牌桶算法
Gateway 自带限流过滤器RequestRateLimiter,结合 Redis 可实现分布式限流(支持 IP、用户 ID、接口等维度)。
5.1.1 引入 Redis 依赖
XML
<!-- Redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
5.1.2 配置 Redis 与限流规则
bash
spring:
redis:
host: 127.0.0.1
port: 6379
password: # 无密码留空
database: 0
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
# 限流配置:基于IP,10秒内允许5次请求
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 0.5 # 令牌桶填充速率(每秒0.5个)
redis-rate-limiter.burstCapacity: 5 # 令牌桶最大容量(5个)
key-resolver: "#{@ipKeyResolver}" # 限流Key解析器(IP维度)
5.1.3 自定义限流 Key 解析器
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 RateLimitKeyResolverConfig {
// 1. 基于IP的限流Key解析器
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> {
// 获取客户端IP
String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
return Mono.just(ip);
};
}
// 2. 基于用户ID的限流Key解析器(需配合鉴权过滤器)
@Bean
public KeyResolver userIdKeyResolver() {
return exchange -> {
// 从请求头获取用户ID(鉴权过滤器传递)
String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
// 未登录用户用IP替代
return Mono.just(userId != null ? userId : ipKeyResolver().resolve(exchange).block());
};
}
// 3. 基于接口路径的限流Key解析器
@Bean
public KeyResolver pathKeyResolver() {
return exchange -> {
String path = exchange.getRequest().getPath().value();
return Mono.just(path);
};
}
}
5.1.4 限流效果测试
- 10 秒内多次访问
http://localhost:8080/api/user/get/1 - 超过 5 次后,网关返回 429 Too Many Requests
- Redis 中会生成限流相关 Key(如
request_rate_limiter.{IP}.timestamp)
5.2 鉴权完整流程:JWT + 权限校验
5.2.1 JWT 生成(用户登录接口)
在user-service中实现登录接口,生成 JWT Token:
java
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
@RestController
@RequestMapping("/user")
public class UserController {
private static final String JWT_SECRET = "your-secret-key-32bytes-long-123456";
private final SecretKey secretKey = Keys.hmacShaKeyFor(JWT_SECRET.getBytes(StandardCharsets.UTF_8));
private static final long EXPIRATION = 3600000; // Token有效期1小时
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
// 1. 校验用户名密码(实际场景从数据库查询)
if ("admin".equals(username) && "123456".equals(password)) {
// 2. 生成JWT Token
String token = Jwts.builder()
.setSubject(username) // 用户名
.claim("userId", "1001") // 自定义字段:用户ID
.claim("role", "ADMIN") // 自定义字段:角色
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) // 过期时间
.signWith(secretKey) // 签名
.compact();
return "Bearer " + token;
}
return "登录失败";
}
}
5.2.2 权限校验(基于角色)
在全局鉴权过滤器中扩展角色校验:
java
// 在GlobalAuthFilterConfig的authFilter中添加
String role = claims.get("role", String.class);
// 示例:只有ADMIN角色能访问/admin路径
if (path.startsWith("/api/admin") && !"ADMIN".equals(role)) {
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN); // 403
return exchange.getResponse().setComplete();
}
6. 生产环境优化:性能调优 + 熔断降级 + 监控告警
6.1 性能调优配置
bash
spring:
cloud:
gateway:
httpclient:
pool:
max-idle-time: 60000 # 连接池最大空闲时间(毫秒)
max-connections: 1000 # 每个路由的最大连接数
max-pending-connections: 500 # 最大等待连接数
connect-timeout: 3000 # 连接超时时间(毫秒)
response-timeout: 5000 # 响应超时时间(毫秒)
threads:
worker: 200 # 工作线程数(建议为CPU核心数*2)
server:
port: 8080
netty:
connection-timeout: 2000 # Netty连接超时时间
threads:
worker: 200 # Netty工作线程数
6.2 熔断降级(整合 Sentinel)
避免下游服务故障导致网关阻塞,通过 Sentinel 实现熔断降级:
XML
<!-- Sentinel依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
bash
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel控制台地址
scg:
fallback:
mode: response # 降级模式:返回固定响应
response-status: 503 # 降级状态码
response-body: '{"code":503,"message":"服务繁忙,请稍后再试"}' # 降级响应体
6.3 监控告警
- 暴露 Actuator 端点,结合 Prometheus+Grafana 监控路由命中率、响应时间、限流次数
- 配置 Sentinel 告警规则,服务异常时通过邮件 / 钉钉通知运维
7. 高频场景配置模板(直接复制使用)
模板 1:静态路由完整配置
bash
spring:
cloud:
gateway:
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/user/**
- Method=GET,POST
- Header=Authorization
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 10
key-resolver: "#{@ipKeyResolver}"
模板 2:跨域配置(全局)
bash
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
allow-credentials: true
max-age: 3600
模板 3:Redis 限流配置(基于用户 ID)
bash
spring:
cloud:
gateway:
routes:
- id: order-service-route
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 2
redis-rate-limiter.burstCapacity: 20
key-resolver: "#{@userIdKeyResolver}"
模板 4:熔断降级配置(Sentinel)
bash
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
scg:
fallback:
mode: redirect # 降级模式:重定向到错误页面
redirect: /error.html # 降级跳转页面
8. 实战避坑指南(10 个实测踩坑总结)
- 依赖冲突 :引入
spring-boot-starter-web导致 Netty 冲突,需删除该依赖 - 跨域配置失效:同时配置了全局 CorsFilter 和 globalcors,优先级冲突,选择一种即可
- 动态路由不生效:Nacos 配置的 dataId 与 bootstrap.yml 不一致,或路由 ID 重复
- 限流不生效 :未引入
spring-boot-starter-data-redis-reactive依赖,或 Redis 连接失败 - Token 传递丢失 :多线程环境下
RequestContextHolder获取不到请求,需手动传递 ThreadLocal - 路由匹配优先级:路由配置顺序即匹配优先级,精确路径路由应放在前面
- StripPrefix 失效 :路径匹配规则与 StripPrefix 级数不匹配(如
/api/user/**对应 StripPrefix=1) - 响应超时配置无效:需同时配置 Gateway 的 httpclient.response-timeout 和微服务的超时时间
- Sentinel 熔断不生效 :未引入
spring-cloud-alibaba-sentinel-gateway依赖 - 日志打印乱码 :Netty 默认编码为 ISO-8859-1,需配置 JVM 参数
-Dfile.encoding=UTF-8
9. 面试高频考点梳理
- Spring Cloud Gateway 的核心组件?(路由、断言、过滤器)
- Gateway 与 Zuul 的区别?(性能、模型、功能支持)
- Gateway 的过滤器执行顺序?(全局→局部,前置→后置,Order 值越小优先级越高)
- 如何实现动态路由?(基于 Nacos 配置中心 + RouteDefinitionWriter)
- Gateway 的限流算法是什么?(令牌桶算法,基于 Redis 实现分布式限流)
- 如何解决 Gateway 的跨域问题?(全局 CorsFilter 或 globalcors 配置)
- Gateway 如何实现鉴权?(全局过滤器 + JWT Token 验证)
- Gateway 的性能优化手段?(连接池配置、线程数调整、压缩、缓存)
10. 总结与展望
Spring Cloud Gateway 作为微服务架构的核心网关,凭借其高性能、强扩展性、丰富的功能,成为企业级微服务项目的首选。本文从基础搭建到生产落地,覆盖了路由、过滤、限流、鉴权等核心场景,提供的配置模板和避坑指南可直接应用于实际项目。
后续可进一步探索 Gateway 的高级特性,如:
- 灰度发布(基于权重路由)
- 分布式链路追踪(整合 SkyWalking/Zipkin)
- 网关层数据脱敏
- 自定义路由断言工厂
如果在实战中遇到具体问题,欢迎在评论区留言讨论,一起交流进步!
