一、网关介绍
1.1 背景与问题
在微服务架构中,我们通常通过 Eureka 或 Nacos 解决服务注册与发现,利用 Spring Cloud LoadBalancer 处理负载均衡,借助 OpenFeign 完成远程调用。然而,如果所有微服务的接口都直接对外暴露,会带来显著的安全隐患。
服务端实现的微服务接口往往带有权限校验机制。由于微服务拆分,原本一个应用的多个模块变成了多个独立应用,导致我们需要在每个应用中重复实现相同的校验逻辑。一旦这套逻辑需要调整,就必须修改多个应用,极大地增加了开发负担。
针对这一问题,引入 API 网关是业界的标准解决方案。这就好比公司设立前台,外部人员办理业务前先由前台核实身份,通过后各部门再直接办理。这样既保证了安全,又提升了效率。
1.2 什么是 API 网关
API 网关(简称网关)是后端服务的唯一入口,其设计模式类似于门面模式(Facade)。它作为整个微服务架构的总控,所有外部客户端访问都需要经过它进行调度和过滤。

网关的核心功能包括:
- 权限控制:作为入口对用户进行鉴权,失败则拦截。
- 动态路由:根据规则将请求转发到具体的微服务。
- 负载均衡:当目标服务有多个实例时,自动分发流量。
- 限流:防止请求流量过高导致服务压力过大。
1.3 常见网关实现
业界成熟的网关方案很多,如 Nginx、Kong、Zuul 和 Spring Cloud Gateway。
Zuul Zuul 是 Netflix 开源的组件,曾是 Spring Cloud Netflix 的核心部分。但在 2018 年,Netflix 宣布部分组件进入维护状态,不再开发新功能,Zuul 也在其中。
Spring Cloud Gateway 这是 Spring Cloud 全新推出的 API 网关项目,基于 Spring + SpringBoot 开发,旨在替换 Zuul。它为微服务架构提供了简单有效的请求转发途径,并支持安全性、监控指标和弹性等横切关注点。官方测试显示,其 RPS(每秒请求数)是 Zuul 的 1.6 倍。
二、Spring Cloud Gateway 实战
2.1 快速上手
2.1.1 创建网关项目
新建一个标准的 Spring Boot 项目即可。
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 添加 Gateway 的路由配置
在 application.yml 中添加如下配置:
server:
port: 10030 # 网关端口
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
discovery:
server-addr: 110.41.51.65:10020
gateway:
routes:
- id: product-service # 路由 ID,自定义,唯一即可
uri: lb://product-service # 目标服务地址
predicates:
- Path=/product/**
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
配置字段说明:
- id: 子定义路由 ID,保持唯一。
- uri: 目标服务地址,支持普通 URI 及
lb://应用注册服务名称。lb表示负载均衡,使用此方式表示从注册中心获取服务地址。 - predicates: 路由条件,根据匹配结果决定是否执行该请求路由。上述代码中,符合 Path 规则的一切请求都会被代理到 uri 参数指定的地址。
通过网关服务访问 order-service 的 URL 示例:http://127.0.0.1:10030/order/1
2.2 Route Predicate Factories
2.2.1 Predicate
Predicate 是 Java 8 提供的一个函数式编程接口,接收一个参数并返回布尔值,用于条件过滤和请求参数校验。
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
2.2.2 Route Predicate Factories
Route Predicate Factories(路由断言工厂)在 Spring Cloud Gateway 中提供了路由规则的匹配机制。我们在配置文件中写的断言规则只是字符串,这些字符串会被工厂读取并处理,转变为路由判断的条件。
例如前面配置的 Path=/product/**,就是通过 Path 属性来匹配 URL 前缀是 /product 的请求。这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory 来实现的。Spring Cloud Gateway 默认提供了很多 Route Predicate Factory,它们分别匹配 HTTP 请求的不同属性,并且多个 Predicate 可以通过 and 逻辑进行组合。
具体可以参考相关文档:Spring Cloud Gateway Request Predicates
2.2.3 代码演示
在 application.yml 中添加时间限制规则:
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 类型(请求执行完成后,返回给客户端之前执行)。

Spring Cloud Gateway 内置了很多 Filter,用于拦截和链式处理 Web 请求。从作用范围上,Filter 可分为 GatewayFilter 和 GlobalFilter。
- GatewayFilter: 应用到单个路由或一个分组的路由上。
- GlobalFilter: 应用到所有的路由上,对所有的请求生效。
2.3.1 GatewayFilter
GatewayFilter 同 Predicate 类似,都是在配置文件 application.yml 中配置,每个过滤器的逻辑都是固定的。比如 AddRequestParameterGatewayFilterFactory 只需要在配置文件中写 AddRequestParameter,就可以为请求添加一个参数。
spring:
cloud:
gateway:
routes:
- id: product-service
uri: lb://product-service
predicates:
- Path=/product/**
filters:
- AddRequestParameter=userName,bite
该 filter 只添加在了 product-service 路由下,因此只对 /product/** 的请求生效。
在 product-service 服务中接收请求的参数并打印:
@RequestMapping("/product")
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping("/{productId}")
public ProductInfo getProductById(@PathVariable("productId") Integer productId, String userName) {
System.out.println("收到请求,Id:" + productId);
System.out.println("userName:" + userName);
return productService.selectProductById(productId);
}
}
Default Filters
若需要对全部路由生效,可以使用 spring.cloud.gateway.default-filters 属性,它需要一个 filter 的列表。
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red,Default-Blue
- PrefixPath=/httpbin
2.3.2 GlobalFilter
GlobalFilter 是 Spring Cloud Gateway 中的全局过滤器,会应用到所有的路由请求上,通常用于实现安全性、性能监控和日志记录等相关的全局功能。
Spring Cloud Gateway 内置的全局过滤器也有很多,比如 Gateway Metrics Filter(提供监控指标)、LoadBalancer Client Filter(实现负载均衡)等。
快速上手
- 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 添加配置
spring:
cloud:
gateway:
metrics:
enabled: true
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
shutdown:
enabled: true
访问 http://127.0.0.1:10030/actuator,即可显示所有监控的信息链接。
2.4 过滤器执行顺序
当一个项目中既有 GatewayFilter,又有 GlobalFilter 时,执行的先后顺序是怎样的呢?
请求路由后,网关会把当前项目中的 GatewayFilter 和 GlobalFilter 合并到一个过滤器链(集合)中,并进行排序,依次执行。
每一个过滤器都必须指定一个 int 类型的 order 值,默认值为 0,表示该过滤的优先级。order 值越小,优先级越高,执行顺序越靠前。
- Filter 通过实现 Order 接口或者添加
@Order注解来指定 order 值。 - Spring Cloud Gateway 提供的 Filter 由 Spring 指定。用户也可以自定义 Filter,由用户指定。
- 当过滤器的 order 值一样时,会按照
defaultFilter > GatewayFilter > GlobalFilter的顺序执行。
2.5 自定义过滤器
Spring Cloud Gateway 提供了过滤器的扩展功能,开发者可以根据实际业务来自定义过滤器,同样自定义过滤器也支持 GatewayFilter 和 GlobalFilter 两种。
2.5.1 自定义 GatewayFilter
自定义 GatewayFilter,需要去实现对应的接口 GatewayFilterFactory,Spring Boot 默认帮我们实现的抽象类是 AbstractGatewayFilterFactory,我们可以直接使用。
2.5.1.1 定义 GatewayFilter
@Slf4j
@Service
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.CustomConfig> implements Ordered {
public CustomGatewayFilterFactory() {
super(CustomConfig.class);
}
@Override
public GatewayFilter apply(CustomConfig config) {
/**
* Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
* ServerWebExchange: HTTP 请求 - 响应交互的契约
* GatewayFilterChain: 过滤器链
* Mono: Reactor 核心类,数据流发布者
*/
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; // 配置优先级,order 越大,优先级越低
}
@Data
public static class CustomConfig {
private String name;
}
}
针对这个 Filter 的配置,使用 CustomConfig 定义。
2.5.1.2 配置过滤器
spring:
cloud:
gateway:
routes:
- id: product-service
uri: lb://product-service
predicates:
- Path=/product/**
filters:
- name: Custom
args:
name: custom filter
2.5.2 自定义 GlobalFilter
GlobalFilter 的实现比较简单,它不需要额外的配置,只需要实现 GlobalFilter 接口,会自动过滤所有的 Filter。
2.5.2.1 定义 GlobalFilter
@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; // 配置优先级,order 越大,优先级越低
}
}
总结
本文详细介绍了 Spring Cloud Gateway 作为微服务统一入口的核心概念与实战操作。从基础的路由配置到高级的自定义过滤器,涵盖了 Predicate 断言与 Filter 过滤器的完整生命周期管理。掌握这些内容,有助于构建更加安全、高效且易于维护的微服务网关架构。


