跳到主要内容
Spring Cloud Gateway 网关核心原理与使用指南 | 极客日志
Java java
Spring Cloud Gateway 网关核心原理与使用指南 介绍微服务架构中 API 网关的作用及常见实现方案,重点讲解 Spring Cloud Gateway 的核心功能。内容包括网关的定义、路由断言(Predicate)、过滤器工厂(Filter Factory)的使用,以及自定义 GatewayFilter 和 GlobalFilter 的实现方法。通过配置示例展示如何设置路由规则、负载均衡、限流及权限校验,帮助开发者快速掌握网关在微服务中的调度与过滤机制。
时间旅人 发布于 2026/2/7 更新于 2026/5/30 28 浏览一、网关
在使用微服务时,所有接口直接暴露会导致管理困难。如果像单机架构一样使用过滤器,每个服务都需要单独编写,非常麻烦。针对这个问题,常用的解决方案是使用 API 网关。
1.1 API 网关是什么
API 网关(简称网关)也是一个服务,通常是后端服务的唯一入口。它的定义类似设计模式中的门面模式(Facade Pattern)。它就像整个微服务架构的大门,所有的外部客户端访问都需要经过它来进行调度和过滤。
核心功能:
权限控制:作为微服务的入口,对用户进行权限校验,如果校验失败则进行拦截
动态路由:一切请求先经过网关,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务
负载均衡:当路由的目标服务有多个时,还需要做负载均衡
限流:请求流量过高时,按照网关中配置微服务能够接受的流量进行放行,避免服务压力过大
1.2 常见网关实现
业界常用的网关方式有很多,技术方案也较成熟,其中不乏很多开源产品,比如 Nginx,Kong,Zuul,Spring Cloud Gateway 等。下面介绍两种常见的网关方案。
Zuul
Zuul 是 Netflix 公司开源的一个 API 网关组件,是 Spring Cloud Netflix 子项目的核心组件之一,它可以和 Eureka、Ribbon、Hystrix 等组件配合使用。
在 Spring Cloud Finchley 正式版之前,Spring Cloud 推荐的网关是 Netflix 提供的 Zuul(此处指 Zuul 1.X)。
然而 Netflix 在 2018 年宣布一部分组件进入维护状态,不再进行新特性的开发。这部分组件中就包含 Zuul。
Spring Cloud Gateway
Spring Cloud Gateway 是 Spring Cloud 的一个全新的 API 网关项目,基于 Spring + SpringBoot 等技术开发,目的是为了替换掉 Zuul。旨在为微服务架构提供一种简单而有效的途径来转发请求,并为他们提供横切关注点,比如:安全性,监控/指标和弹性。
在性能方面,根据官方提供的测试报告,Spring Cloud Gateway 的 RPS(每秒请求数) 是 Zuul 的 1.6 倍。
https://github.com/spencergibb/spring-cloud-gateway-bench
二、使用 GateWay
基于前面的 Feign 代码开发。
引入依赖
创建网关项目
<dependencies >
<dependency >
<groupId > org.springframework.cloud</groupId >
spring-cloud-starter-gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-loadbalancer
<artifactId >
</artifactId >
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
</dependency >
</dependencies >
package com.cloud.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayApplication {
public static void main (String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
server:
port: 10030
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: nacos 的 ip 地址 + 端口号
gateway:
routes:
- id: product-service
uri: lb://product-service
predicates:
- Path=/product/**
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
id:自定义路由 ID,保持唯一
uri:目标服务地址,支持普通 URI 及 lb://应用注册服务名称。lb 表示负载均衡,使用 lb:// 方式表示从注册中心获取服务地址。
predicates:路由条件,根据匹配结果决定是否执行该请求路由,上述代码中,我们把符合 Path 规则的一切请求,都代理到 uri 参数指定的地址。
三、Route Predicate Factories
3.1 Predicate Predicate 是 Java 8 提供的一个函数式编程接口,它接收一个参数并返回一个布尔值,用于条件过滤,请求参数的校验。
@FunctionalInterface
public interface Predicate <T> {
boolean test (T t) ;
}
写一个判断字符串为空的 Predicate 函数:
package predicate;
import java.util.function.Predicate;
public class StringPredicate implements Predicate <String> {
@Override
public boolean test (String s) {
return s == null || s.isEmpty();
}
}
package predicate;
import org.junit.Test;
import java.util.function.Predicate;
public class StringPredicateTest {
@Test
public void test () {
StringPredicate stringPredicate = new StringPredicate ();
System.out.println(stringPredicate.test("" ));
System.out.println(stringPredicate.test("123" ));
System.out.println(stringPredicate.test(null ));
}
@Test
public void test2 () {
Predicate<String> stringPredicate = new Predicate <String>() {
@Override
public boolean test (String s) {
return s == null || s.isEmpty();
}
};
System.out.println(stringPredicate.test("" ));
System.out.println(stringPredicate.test("123" ));
System.out.println(stringPredicate.test(null ));
}
@Test
public void test3 () {
Predicate<String> stringPredicate = s -> s == null || s.isEmpty();
System.out.println(stringPredicate.test("" ));
System.out.println(stringPredicate.test("123" ));
System.out.println(stringPredicate.test(null ));
}
}
isEqual(Object targetRef) : 比较两个对象是否相等,参数可以为 Null
and(Predicate other):短路与操作,返回一个组成 Predicate
or(Predicate other):短路或操作,返回一个组成 Predicate
test(T t):传入一个 Predicate 参数,用来做判断
negate():返回表示此 Predicate 逻辑否定的 Predicate
方法 说明 boolean test(T t) 判断条件,可以理解为 条件 A 根据逻辑返回布尔值 Predicate and(Predicate<? super T> other) 条件 A && 条件 B 当前 Predicate 的 test 方法 && other 的 test 方法,相当于进行两次判断 default Predicate negate() ! 条件 A default Predicate or(Predicate<? super T> other) 条件 A
3.2 Route Predicate Factories Route Predicate Factories (路由断言工厂,也称为路由谓词工厂),在 Spring Cloud Gateway 中,Predicate 提供了路由规则的匹配机制。
我们在配置文件中写的断言规则只是字符串,这些字符串会被 Route Predicate Factory 读取并处理,转变为路由判断的条件。
这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory 来实现的。
Spring Cloud Gateway 默认提供了很多 Route Predicate Factory,这些 Predicate 会分别匹配 HTTP 请求的不同属性,并且多个 Predicate 可以通过 and 逻辑进行组合。
名称 说明 示例 After 这个工厂需要一个日期时间 (Java 的 ZonedDateTime 对象),匹配指定日期之后的请求 predicates: - After=2017-01-20T17:42:47.789-07:00[America/Denver]Before 匹配指定日期之前的请求 predicates: - Before=2017-01-20T17:42:47.789-07:00[America/Denver]Between 匹配两个指定时间之间的请求 datetime2 的参数必须在 datetime1 之后 predicates: - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]Cookie 请求中包含指定 Cookie,且该 Cookie 值符合指定的正则表达式 predicates: - Cookie=chocolate, ch.pHeader 请求中包含指定 Header,且该 Header 值符合指定的正则表达式 predicates: - Header=X-Request-Id, \d+Host 请求必须是访问某个 host(根据请求中的 Host 字段进行匹配) predicates: -Host=**.somehost.org,**.anotherhost.orgMethod 匹配指定的请求方式 predicates: - Method=GET,POSTPath 匹配指定规则的路径 predicates: - Path=/red/{segment},/blue/{segment}Remote Addr 请求者的 IP 必须为指定范围 predicates: - RemoteAddr=192.168.1.1/24
3.3 Gateway Filter Factories(网关过滤器工厂) Predicate 决定了请求由哪一个路由处理,如果在请求处理前后需要加一些逻辑,这就是 Filter(过滤器) 的作用范围了。
Filter 分为两种类型:Pre 类型和 Post 类型。
Pre 类型过滤器:路由处理之前执行 (请求转发到后端服务之前执行),在 Pre 类型过滤器中可以做鉴权,限流等。
Post 类型过滤器:请求执行完成后,将结果返回给客户端之前执行。
Spring Cloud Gateway 中内置了很多 Filter,用于拦截和链式处理 web 请求。比如权限校验,访问超时等设定。
Spring Cloud Gateway 从作用范围上,把 Filter 可分为 GatewayFilter 和 GlobalFilter。
GatewayFilter:应用到单个路由或者一个分组的路由上。
GlobalFilter:应用到所有的路由上,也就是对所有的请求生效。
3.3.1 GatewayFilter GatewayFilter 同 Predicate 类似,都是在配置文件 application.yml 中配置,每个过滤器的逻辑都是固定的。比如 AddRequestParameterGatewayFilterFactory 只需要在配置文件中写 AddRequestParameter,就可以为所有的请求添加一个参数。
名称 说明 示例 AddRequestHeader 为当前请求添加 Header 参数:Header 的名称及值 -AddRequestHeader=X-Request-red,blueAddRequestParameter 为当前请求添加请求参数 参数:参数的名称及值 -AddRequestParameter=red,blueAddResponseHeader 为响应结果添加 Header 参数:Header 的名称及值 -AddResponseHeader=X-Response-Red,BlueRemoveRequestHeader 从当前请求删除某个 Header 参数:Header 的名称 -RemoveRequestHeader=X-Request-FooRemoveResponseHeader 从响应结果删除某个 Header 参数:Header 的名称 -RemoveResponseHeader=X-Response-FooRequestRateLimiter 为当前网关的所有请求执行限流过滤,若被限流默认返回 HTTP 429 Too Many Requests。 默认提供 RedisRateLimiter 的限流实现,采用令牌桶算法: - redis-rate-limiter.replenishRate:令牌填充速度,即每秒钟允许多少个请求(不丢弃任何请求) - redis-rate-limiter.burstCapacity:令牌桶容量,即每秒用户最大能够执行的请求数量(不丢弃任何请求),设为 0 将阻止所有请求 - redis-rate-limiter.requestedTokens:每次请求占用几个令牌,默认为 1 filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 10redis-rate-limiter.burstCapacity: 20redis-rate-limiter.requestedTokens: 1Retry 针对不同响应进行重试。当后端服务不可用时,网关根据配置参数发起重试请求。 - retries:重试次数,默认为 3 - statuses:HTTP 请求返回的状态码,针对指定状态码进行重试,对应 org.springframework.http.HttpStatus filters:- name: Retryargs:retries: 3statuses: BAD_REQUESTRequestSize 设置允许接收的最大请求包大小,若请求包大小超过设定值,则返回 413 Payload Too Large。 请求包大小单位为字节,默认值为 5 MB。 filters:- name: RequestSizeargs:maxSize: 5000000默认过滤器 添加一个 filter 并将其应用于所有路由,该属性需要一个 filter 列表,对所有路由都生效。 spring: cloud: gateway: default-filters:
3.3.2 GlobalFilter GlobalFilter 是 Spring Cloud Gateway 中的全局过滤器,它和 GatewayFilter 的作用是相同的。GlobalFilter 会应用到所有的路由请求上,全局过滤器通常用于实现与安全性,性能监控和日志记录等相关的全局功能。
Spring Cloud Gateway 内置的全局过滤器也有很多,比如:
Gateway Metrics Filter:网关指标,提供监控指标
Forward Routing Filter:用于本地 forword,请求不转发到下游服务器
LoadBalancer Client Filter:针对下游服务,实现负载均衡。
3.4 过滤器执行顺序 一个项目中,既有 GatewayFilter,又有 GlobalFilter 时,执行的先后顺序是:
请求路由后,网关会把当前项目中的 GatewayFilter 和 GlobalFilter 合并到一个过滤器链 (集合) 中,并进行排序,依次执行过滤器。
每一个过滤器都必须指定一个 int 类型的 order 值,默认值为 0,表示该过滤的优先级。order 值越小,优先级越高,执行顺序越靠前。Filter 通过实现 Order 接口或者添加@Order 注解来指定 order 值。Spring Cloud Gateway 提供的 Filter 由 Spring 指定。用户也可以自定义 Filter,由用户指定。当过滤器的 order 值一样时,会按照 defaultFilter > GatewayFilter > GlobalFilter 的顺序执行。
3.5 自定义过滤器 Spring Cloud Gateway 提供了过滤器的扩展功能,开发者可以根据实际业务来定义过滤器,同样自定义过滤器也支持 GatewayFilter 和 GlobalFilter 两种。
3.5.1 自定义 GatewayFilter 自定义 GatewayFilter,需要去实现对应的接口 GatewayFilterFactory,Spring Boot 默认帮我们实现的抽象类是 AbstractGatewayFilterFactory,我们可以直接使用。
我们在前面配置文件中使用过滤器的时候会传参数,我们需要自定义类来接收参数。
package com.cloud.gateway;
import lombok.Data;
@Data
public class CustomConfig {
private String name;
}
类名统一以 GatewayFilterFactory 结尾,因为默认情况下,过滤器的 name 会采用该定义类的前缀。这里的 name=Custom(yml 配置中使用)
apply 方法中,同时包含 Pre 和 Post 过滤,then 方法中是请求执行结束之后处理的
CustomConfig 是一个配置类,该类只有一个属性 name,和 yml 的配置对应
该类需要交给 Spring 管理,所以需要加 @Component 注解
getOrder 表示该过滤器的优先级,值越大,优先级越低。
package com.cloud.gateway;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory <CustomConfig> implements Ordered {
public CustomGatewayFilterFactory () {
super (CustomConfig.class);
}
@Override
public GatewayFilter apply (CustomConfig config) {
return new GatewayFilter () {
@Override
public Mono<Void> filter (ServerWebExchange exchange, GatewayFilterChain 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;
}
}
server:
port: 10030
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: product-service
uri: lb://product-service
predicates:
- Path=/product/**
filters:
- name: Custom
args:
name: custom filter
3.5.2 自定义 GlobalFilter GlobalFilter 的实现比较简单,它不需要额外的配置,只需要实现 GlobalFilter 接口,自动会过滤所有的 Filter。
package com.cloud.gateway;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Slf4j
@Component
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;
}
}
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online