Spring Cloud Gateway 是 Spring Cloud 生态的微服务网关,基于 WebFlux 响应式编程模型,替代了老旧的 Zuul 网关。它的核心价值是:统一入口、路由转发、业务增强(认证授权、限流熔断、日志监控等),是微服务架构中不可或缺的中间件。
本文从「入门配置→核心功能→进阶实战→性能优化」逐步递进,结合实际项目场景,帮你快速掌握 Gateway 的使用。
一、入门:环境搭建与基础路由(10 分钟上手)
1. 核心依赖(Spring Cloud Alibaba 环境)
在微服务网关模块(如 gateway-server)的 pom.xml 中添加依赖(无需额外引入 Spring MVC,Gateway 基于 WebFlux):
<!-- 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>
<!-- Nacos 配置中心(动态路由用) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2. 基础配置(application.yml)
网关的核心是「路由规则」,入门阶段先配置静态路由和服务发现路由:
spring:
application:
name: gateway-server # 网关服务名(Nacos 注册用)
cloud:
# Nacos 服务发现配置
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 你的 Nacos 地址
# Gateway 核心配置
gateway:
# 路由规则(可配置多个 route)
routes:
# 1. 静态路由:直接指定目标地址(适合非微服务接口,如第三方 API)
- id: static-route # 路由唯一ID(自定义,不重复)
uri: http://www.baidu.com # 目标地址(静态地址)
predicates: # 路由断言(满足条件才转发)
- Path=/baidu/** # 当请求路径以 /baidu 开头时触发
filters: # 路由过滤器(对请求/响应做处理)
- RewritePath=/baidu/(?<segment>.*), /$\{segment} # 路径重写:/baidu/xxx → /xxx
# 2. 动态路由:从 Nacos 拉取服务(微服务场景核心)
- id: order-service-route # 路由ID(建议与服务名一致)
uri: lb://order-server # 目标服务名(lb=负载均衡,从 Nacos 获取实例)
predicates:
- Path=/order/** # 请求路径以 /order 开头 → 转发到 order-server
filters:
- StripPrefix=1 # 路径剥离:/order/xxx → /xxx(去掉第一层路径)
# 启用服务发现(让网关能从 Nacos 感知服务上下线)
discovery:
locator:
enabled: true # 开启服务发现路由(默认关闭)
lower-case-service-id: true # 服务名转为小写(如 ORDER-SERVER → order-server)
server:
port: 8080 # 网关端口(公网入口,如 80 端口)
3. 启动网关
创建启动类(无需加 @EnableWebMvc,Gateway 自动配置 WebFlux):
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);
}
}
4. 测试验证
- 启动 Nacos、order-server、gateway-server;
- 访问静态路由:
http://localhost:8080/baidu→ 跳转到百度; - 访问微服务路由:
http://localhost:8080/order/xxx→ 转发到 order-server 的/xxx接口(需确保 order-server 有对应接口)。
二、核心概念:3 个核心组件(必懂)
Gateway 的所有功能都围绕「路由(Route)、断言(Predicate)、过滤器(Filter)」展开,理解这 3 个组件就能掌握 Gateway 的核心逻辑:
| 组件 | 作用 |
|---|---|
| Route(路由) | 网关的基本单元,包含「目标地址、断言、过滤器」三部分,是转发规则的最小单位。 |
| Predicate(断言) | 路由的「触发条件」,判断请求是否满足规则(如路径、方法、请求头、时间等),满足则转发。 |
| Filter(过滤器) | 路由的「增强逻辑」,对请求(前置处理)或响应(后置处理)做加工(如路径重写、认证、限流)。 |
1. 常用 Predicate(路由断言)
断言支持多种条件组合,满足条件才触发路由,常用场景:
routes:
- id: demo-route
uri: lb://order-server
predicates:
# 1. 路径断言(最常用):/order/** 或 /order/123
- Path=/order/**
# 2. 方法断言:只允许 GET 请求
- Method=GET
# 3. 请求头断言:必须包含 X-Token 请求头
- Header=X-Token, \d+ # 第二个参数是正则(可选)
# 4. 参数断言:请求必须包含 id 参数(值为数字)
- Query=id, \d+
# 5. 时间断言:在 2025-01-01 到 2025-12-31 之间有效
- Between=2025-01-01T00:00:00+08:00, 2025-12-31T23:59:59+08:00
# 6. IP 断言:只允许 192.168.1.0/24 网段访问
- RemoteAddr=192.168.1.0/24
2. 常用 Filter(路由过滤器)
Gateway 提供两种过滤器:GatewayFilter(路由级,只对当前路由生效) 和 GlobalFilter(全局级,对所有路由生效)。
(1)内置 GatewayFilter(直接配置使用)
routes:
- id: order-service-route
uri: lb://order-server
predicates:
- Path=/order/**
filters:
# 1. 路径剥离:去掉第1层路径(/order/xxx → /xxx)
- StripPrefix=1
# 2. 路径重写:/order/api/xxx → /api/xxx
- RewritePath=/order/(?<segment>.*), /$\{segment}
# 3. 添加请求头:给转发的请求添加 X-Request-Source=gateway
- AddRequestHeader=X-Request-Source, gateway
# 4. 添加响应头:给客户端响应添加 X-Response-Time=2025
- AddResponseHeader=X-Response-Time, 2025
# 5. 限流:每秒最多100个请求(基于 Redis 实现,需引入 spring-boot-starter-data-redis-reactive)
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100 # 令牌桶填充速率(每秒)
redis-rate-limiter.burstCapacity: 200 # 令牌桶最大容量(峰值)
key-resolver: "#{@ipKeyResolver}" # 限流键解析器(IP 限流)
(2)自定义 GlobalFilter(全局生效,如认证授权)
全局过滤器适合做「统一认证、日志采集、链路追踪」等全局逻辑,示例:统一 Token 校验(未带 Token 直接拦截):
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.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Configuration
public class GlobalAuthFilterConfig {
/**
* 自定义全局认证过滤器(Order 越小,执行优先级越高)
*/
@Bean
@Order(-100) // 优先级高于默认过滤器(默认 0)
public GlobalFilter authFilter() {
return (exchange, chain) -> {
// 1. 获取请求头中的 Token
String token = exchange.getRequest().getHeaders().getFirst("X-Token");
// 2. 校验 Token(实际场景:对接 Redis/鉴权服务校验)
if (token == null || token.isEmpty()) {
// 3. Token 无效:返回 401 未授权
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 4. Token 有效:继续转发请求到下游服务
return chain.filter(exchange);
};
}
/**
* 自定义限流键解析器(IP 限流)
*/
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(
// 获取客户端 IP 地址作为限流键
exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
);
}
}
三、进阶:核心功能实战(微服务必备)
1. 动态路由(基于 Nacos 配置中心)
静态路由需要重启网关才能更新,动态路由通过 Nacos 配置中心实现「配置推送即生效」,步骤如下:
(1)Nacos 中创建网关配置
在 Nacos 控制台新建配置:
- Data ID:
gateway-server.yaml(与网关服务名一致) - Group:
DEFAULT_GROUP - 配置内容(路由规则动态更新):
spring:
cloud:
gateway:
routes:
- id: order-service-route
uri: lb://order-server
predicates:
- Path=/order/**
filters:
- StripPrefix=1
# 新增/修改路由直接在这里操作,无需重启网关
- id: stock-service-route
uri: lb://stock-server
predicates:
- Path=/stock/**
filters:
- StripPrefix=1
(2)网关启用 Nacos 动态配置
在网关的 bootstrap.yml 中配置 Nacos 配置中心(优先级高于 application.yml):
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 # Nacos 地址
file-extension: yaml # 配置文件格式
group: DEFAULT_GROUP # 配置分组
application:
name: gateway-server # 对应 Nacos 的 Data ID 前缀
(3)测试动态路由
- 修改 Nacos 中
gateway-server.yaml的路由规则(如新增一个路由); - 无需重启网关,直接访问新路由(如
/stock/xxx),即可生效。
2. 整合 Sentinel 限流熔断(流量防护)
Gateway 与 Sentinel 无缝集成,实现「网关层限流」(避免下游服务被压垮),步骤如下:
(1)添加依赖
<!-- Sentinel 网关适配依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- Sentinel 核心依赖(已引入可忽略) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
(2)配置 Sentinel 控制台
在 application.yml 中添加:
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
port: 8719 # 客户端与控制台通信端口
# 启用网关限流规则(默认关闭)
filter:
enabled: true
(3)在 Sentinel 控制台配置网关限流
- 启动 Sentinel 控制台(
java -jar sentinel-dashboard-1.8.6.jar); - 启动网关和下游服务,访问网关接口(触发 Sentinel 初始化);
- Sentinel 控制台 → 网关路由限流 → 新增规则:
- 资源名:路由 ID(如
order-service-route); - 限流阈值:10(每秒最多 10 个请求);
- 统计周期:1 秒;
- 压测测试:快速访问
/order/xxx,超过阈值会返回Blocked by Sentinel: FlowException。
3. 灰度发布(基于请求头 / 参数路由)
灰度发布是微服务的核心需求(让部分用户体验新功能),Gateway 可通过「自定义路由断言」实现:
示例:按请求头 X-Gray-Tag=beta 路由到新版本服务
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
// 自定义路由断言工厂(命名规则:XXXRoutePredicateFactory)
@Component
public class GrayRoutePredicateFactory extends AbstractRoutePredicateFactory<GrayRoutePredicateFactory.Config> {
// 配置类:存储断言参数(如灰度标签)
public static class Config {
private String tag; // 灰度标签(如 beta)
public String getTag() { return tag; }
public void setTag(String tag) { this.tag = tag; }
}
public GrayRoutePredicateFactory() {
super(Config.class);
}
// 构建断言逻辑:请求头包含 X-Gray-Tag=配置的 tag 则生效
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
String grayTag = exchange.getRequest().getHeaders().getFirst("X-Gray-Tag");
return config.getTag().equals(grayTag);
};
}
// 配置参数名称(用于 yaml 配置)
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("tag");
}
}
配置灰度路由
spring:
cloud:
gateway:
routes:
# 灰度路由:X-Gray-Tag=beta → 转发到 order-server-beta(新版本服务)
- id: order-service-gray
uri: lb://order-server-beta
predicates:
- Path=/order/**
- Gray=beta # 自定义断言(对应上面的 GrayRoutePredicateFactory)
filters:
- StripPrefix=1
# 普通路由:其他请求 → 转发到 order-server(旧版本服务)
- id: order-service-normal
uri: lb://order-server
predicates:
- Path=/order/**
filters:
- StripPrefix=1
测试灰度发布
- 给请求添加头
X-Gray-Tag=beta→ 访问新版本服务; - 无该请求头 → 访问旧版本服务。
4. 分布式链路追踪(整合 SkyWalking)
网关作为请求入口,需要接入链路追踪,确保「请求→网关→服务 1→服务 2」的链路可追溯:
(1)添加依赖
<!-- SkyWalking 网关适配依赖 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-spring-cloud-gateway-3.x-plugin</artifactId>
<version>8.16.0</version> <!-- 与 SkyWalking 服务端版本一致 -->
</dependency>
<!-- SkyWalking 核心依赖(已引入可忽略) -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.16.0</version>
</dependency>
(2)配置 SkyWalking 代理
启动网关时,添加 JVM 参数(指定 SkyWalking 服务端地址):
-javaagent:D:\skywalking-agent\skywalking-agent.jar
-Dskywalking.agent.service_name=gateway-server
-Dskywalking.collector.backend_service=127.0.0.1:11800
(3)查看链路追踪
启动 SkyWalking 服务端,访问网关接口后,在 SkyWalking 控制台 → 链路追踪,可看到完整的请求链路(网关→下游服务)。
四、高阶:性能优化与生产实践
1. 性能优化技巧
Gateway 基于 WebFlux(响应式),性能优于传统 MVC,但需注意以下优化点:
(1)关闭 Netty 日志(减少 IO 开销)
在 logback.xml 中添加:
<logger name="reactor.netty" level="WARN" />
<logger name="io.netty" level="WARN" />
(2)调整 Netty 线程池(适配 CPU 核心数)
spring:
cloud:
gateway:
httpclient:
reactor:
# 工作线程数(默认 CPU 核心数 * 2)
workerGroupThreads: 16
# 事件循环线程数(默认 CPU 核心数)
eventLoopGroupThreads: 4
(3)启用连接池复用
spring:
cloud:
gateway:
httpclient:
pool:
max-idle-time: 60000 # 连接最大空闲时间(60秒)
max-life-time: 120000 # 连接最大生命周期(120秒)
max-connections: 1000 # 最大连接数(根据并发量调整)
(4)禁用不必要的过滤器
避免全局过滤器做过多耗时操作(如复杂计算、数据库查询),必要时用异步处理。
2. 生产环境必备配置
(1)高可用部署(多实例 + Nginx 负载均衡)
网关是入口,必须集群部署,避免单点故障:
用户 → Nginx(边缘网关) → 多个 Gateway 实例 → 微服务
Nginx 配置示例(转发到网关集群):
upstream gateway_cluster {
server 192.168.1.100:8080;
server 192.168.1.101:8080;
}
server {
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://gateway_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
(2)超时配置(避免请求阻塞)
spring:
cloud:
gateway:
httpclient:
connect-timeout: 5000 # 连接超时(5秒)
response-timeout: 10000 # 响应超时(10秒)
routes:
- id: order-service-route
uri: lb://order-server
predicates:
- Path=/order/**
filters:
- StripPrefix=1
- name: RequestTimeFilter
args:
responseTimeOut: 10000 # 路由级超时(覆盖全局)
(3)跨域配置(解决前端跨域问题)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*"); // 允许所有源(生产环境指定具体域名,如 https://xxx.com)
config.addAllowedMethod("*"); // 允许所有请求方法(GET/POST/PUT/DELETE)
config.addAllowedHeader("*"); // 允许所有请求头
config.setAllowCredentials(true); // 允许携带 Cookie
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); // 对所有路径生效
return new CorsWebFilter(source);
}
}
3. 常见问题排查
(1)路由不生效
- 检查路由 ID 是否重复;
- 断言条件是否满足(如路径是否匹配、请求头是否存在);
- 服务发现是否启用(
discovery.locator.enabled=true); - 下游服务是否已注册到 Nacos(网关日志中查看
Loaded service instances for service xxx)。
(2)请求超时
- 检查网关与下游服务的网络连通性;
- 调整
connect-timeout和response-timeout配置; - 排查下游服务是否响应缓慢(如数据库查询耗时过长)。
(3)Sentinel 控制台看不到网关路由
- 确保已引入
spring-cloud-alibaba-sentinel-gateway依赖; - 访问网关接口触发 Sentinel 初始化;
- 检查 Sentinel 控制台地址配置是否正确。
五、总结
Gateway 是微服务架构的「流量入口网关」,核心优势是:
- 原生集成 Spring 生态(Nacos、Sentinel、SkyWalking),开发成本低;
- 基于 WebFlux 响应式,性能优异;
- 支持动态路由、灰度发布、限流熔断等微服务核心需求。
学习路径建议:
- 入门:掌握基础路由、服务发现、内置过滤器;
- 进阶:实现动态路由、Sentinel 限流、灰度发布;
- 生产:优化性能、高可用部署、问题排查。
实际项目中,Gateway 通常与 Nginx 配合使用(Nginx 负责边缘网关,Gateway 负责微服务网关),各司其职,打造稳定、高效的微服务入口。
168万+

被折叠的 条评论
为什么被折叠?



