网关介绍
1.1 为什么需要网关
在微服务架构中,我们通常通过注册中心(如 Nacos、Eureka)解决服务发现问题,利用负载均衡器处理流量分发。然而,如果所有微服务的接口都直接对外暴露,会带来显著的安全隐患和维护成本。
原本单体应用中的权限校验逻辑被拆分到各个微服务中,导致重复开发。一旦安全策略调整,就需要修改多个服务,这大大增加了运维负担。为了解决这个问题,引入 API 网关是业界的标准做法。
类比理解
就像公司设立前台:外部人员办事需先在前台核实身份,通过后由各部门办理。若没有前台,每个部门都要单独核验身份,效率低且流程繁琐。网关就是这个'前台',统一处理鉴权与调度。
1.2 什么是 API 网关
API 网关是后端服务的唯一入口,其设计模式类似于门面模式(Facade)。它负责所有外部客户端请求的调度、过滤和转发。

核心功能包括:
- 权限控制:作为入口拦截非法请求,执行统一的鉴权。
- 动态路由:根据规则将请求转发至对应的微服务,不处理具体业务。
- 负载均衡:当目标服务有多个实例时,自动进行流量分发。
- 限流保护:控制进入系统的流量,防止下游服务因压力过大而崩溃。
1.3 常见网关方案
业界成熟的网关方案较多,如 Nginx、Kong、Zuul 等。这里重点对比两种主流方案:
Zuul Netflix 开源的组件,曾是 Spring Cloud 推荐的网关。但在 2018 年后,Netflix 宣布部分组件进入维护状态,不再更新新特性,Zuul 1.X 也随之停止演进。
Spring Cloud Gateway 基于 Spring Boot 和 WebFlux 技术栈全新构建,旨在替代 Zuul。官方测试显示,其 RPS(每秒请求数)性能约为 Zuul 的 1.6 倍。它提供了更简洁的路由配置和强大的横切关注点处理能力(如安全性、监控、弹性)。
Spring Cloud Gateway 实战
2.1 快速上手
2.1.1 创建项目
新建一个标准的 Spring Boot 项目,命名为 gateway。
2.1.2 引入依赖
我们需要网关核心依赖、服务发现依赖以及负载均衡依赖。
<!-- 网关核心 -->
<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>
<!-- 负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2.1.3 编写启动类
保持标准 Spring Boot 启动结构即可。
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
2.1.4 配置路由
在 application.yml 中定义路由规则。注意 YAML 的缩进格式。
server:
port: 10030
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 110.41.51.65:10020
gateway:
routes:
- id: product-service
uri: lb://product-service
predicates:
- Path=/product/**
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
配置说明:
id:路由的唯一标识。uri:目标服务地址。使用lb://前缀表示从注册中心获取服务列表并负载均衡。predicates:路由断言,只有匹配该条件的请求才会被转发。
访问示例:http://127.0.0.1:10030/order/1 会被转发到 order-service。
2.2 Route Predicate Factories
2.2.1 Predicate 基础
Predicate 是 Java 8 提供的函数式接口,接收参数返回布尔值,用于条件判断。在网关中,它决定了请求是否匹配某条路由。
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
实际使用中,我们可以用 Lambda 表达式简化写法:
Predicate<String> predicate = s -> s.isEmpty();
2.2.2 路由断言工厂
Route Predicate Factory 将配置文件中的字符串规则转换为实际的判断逻辑。例如 Path=/product/** 是由 PathRoutePredicateFactory 实现的。
Spring Cloud Gateway 内置了丰富的断言工厂,支持 HTTP 请求的不同属性匹配,且可以通过 and 组合多个条件。
2.2.3 代码演示
在配置中添加时间断言,限制特定时间段内的访问:
spring:
cloud:
gateway:
routes:
- id: product-service
uri: lb://product-service
predicates:
- Path=/product/**
- After=2026-01-01T00:00:00.000+08:00[Asia/Shanghai]
这样配置后,只有在指定时间之后的请求才能通过网关。
2.3 Gateway Filter Factories
Predicate 决定请求去哪,Filter 则决定请求在到达目的地前后做什么处理。Filter 分为 Pre(前置)和 Post(后置)类型。
- Pre 过滤器:在转发到后端服务前执行,常用于鉴权、限流。
- Post 过滤器:在响应返回给客户端前执行,常用于日志记录、响应头修改。

根据作用范围,Filter 分为两类:
- GatewayFilter:作用于单个或一组路由。
- GlobalFilter:作用于所有路由,优先级更高。
2.3.1 GatewayFilter 使用
在路由配置中直接添加 filters 节点即可。
routes:
- id: product-service
uri: lb://product-service
predicates:
- Path=/product/**
filters:
- AddRequestParameter=userName, bite
此配置会在转发请求时自动添加 userName=bite 参数。后端服务接收时可直接获取该参数。
默认过滤器
若希望对所有路由生效,可使用 default-filters 配置全局默认过滤器列表。
2.3.2 GlobalFilter 使用
GlobalFilter 实现简单,只需实现 GlobalFilter 接口。Spring Cloud Gateway 内置了一些全局过滤器,如指标监控、负载均衡客户端等。
开启 Actuator 监控可验证内置过滤器效果:
management:
endpoints:
web:
exposure:
include: "*"
访问 /actuator 即可查看网关运行时的各项指标。
2.4 过滤器执行顺序
当项目中同时存在 GatewayFilter 和 GlobalFilter 时,它们会被合并到一个过滤器链中排序执行。
- Order 值:数值越小,优先级越高。可通过实现
Ordered接口或添加@Order注解指定。 - 默认顺序:当 Order 值相同时,执行顺序通常为
DefaultFilter > GatewayFilter > GlobalFilter。

2.5 自定义过滤器
2.5.1 自定义 GatewayFilter
继承 AbstractGatewayFilterFactory 即可轻松扩展。需要定义配置类来接收 YML 中的参数。
@Slf4j
@Service
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomConfig> implements Ordered {
public CustomGatewayFilterFactory() {
super(CustomConfig.class);
}
@Override
public GatewayFilter apply(CustomConfig config) {
return ((exchange, chain) -> {
log.info("[Pre] Filter Request, name: {}", config.getName());
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("[Post] Response Filter");
}));
});
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
配合配置类:
@Data
public class CustomConfig {
private String name;
}
YAML 配置示例:
filters:
- name: Custom
args:
name: custom filter
2.5.2 自定义 GlobalFilter
实现 GlobalFilter 接口,无需额外配置,Spring 会自动扫描注册。
@Slf4j
@Service
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("[Pre] CustomGlobalFilter enter...");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("[Post] CustomGlobalFilter return...");
}));
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
总结
Spring Cloud Gateway 作为微服务架构的统一入口,解决了传统微服务直接暴露带来的安全与维护难题。通过路由断言灵活匹配请求,结合过滤器机制实现鉴权、限流等横切逻辑,开发者可以高效构建高性能网关。掌握其配置方式与自定义扩展能力,对于构建稳健的微服务体系至关重要。


