一、网关核心定位:微服务统一流量入口
在微服务架构中,后端会拆分出订单、支付、用户等多个独立服务,前端无法维护海量服务 IP 与端口,Spring Cloud Gateway 应运而生,作为整个业务集群的唯一访问入口。
官方推荐基于 WebFlux 响应式 Server,而非传统 SpringMVC,依托非阻塞异步模型,网关拥有更高并发承载能力,核心职责如下:
- 统一入口:前端仅对接网关地址,屏蔽后端集群部署细节;
- 路由转发:根据匹配规则将请求分发至对应微服务;
- 负载均衡:搭配 Spring Cloud LoadBalancer 实现服务集群负载;
- 通用能力收敛:统一处理跨域、请求校验、响应封装、身份令牌等通用逻辑;
- 流量管控:可扩展实现限流、鉴权、黑白名单、监控告警。
负载均衡依赖说明
新版 Spring Cloud 已移除内置 Ribbon,负载均衡能力独立为spring-cloud-loadbalancer,必须手动引入 Maven 依赖才能使用lb://负载均衡协议:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
重要开发规范
使用 OpenFeign 远程调用时, @FeignClient修饰的接口不能添加类级别@RequestMapping,路径注解仅允许写在接口方法上,否则会出现路径拼接错乱、404 等异常。
微服务调用链路区分
- 默认场景:服务之间通过注册中心直连调用,不经过网关,性能更高;
- 强制走网关 :修改
@FeignClient的 value 为网关服务名,同步调整接口请求路径,适用于需要网关统一鉴权的场景。
二、路由:网关转发的基础规则
路由是网关最基础的组件,由唯一 ID、目标服务地址、匹配断言、过滤器四部分组成,配置存放于application-route.yml。
yml
spring:
cloud:
gateway:
routes:
- id: order-route # 路由唯一标识,不可重复
uri: lb://service-order # lb代表负载均衡,指向注册中心订单服务
predicates: # 路由匹配断言
- Path=/order/**
order: 0
路由匹配优先级规则:配置未手动指定order数值时,自上而下依次匹配,请求命中第一条符合断言的路由即转发。 配置order字段优先级按照从小到大以此降低,0优先级最高。
三、路由断言:精准匹配请求的判断器
断言(Predicate)本质是一套请求匹配规则,只有请求满足当前路由全部断言条件,才会转发至对应服务,底层统一由RoutePredicateFactory工厂生成。
1. 官方内置常用断言
表格
| 断言类型 | 匹配逻辑 |
|---|---|
| After / Before / Between | 根据请求时间匹配,限定访问时段 |
| Cookie | 校验请求携带 Cookie,支持正则匹配值 |
| Header | 校验指定请求头,支持正则 |
| Host | 匹配访问域名 |
| Method | 限定 HTTP 请求方式(GET/POST 等) |
| Path | 匹配请求路径,最常用断言 |
| Query | 校验 URL 携带的查询参数 |
| RemoteAddr | 限制客户端访问 IP 段 |
| Weight | 基于权重实现灰度负载均衡 |
2. 自定义断言工厂实战
内置断言无法满足业务时,可自定义断言工厂,命名规范为XXXRoutePredicateFactory,继承AbstractRoutePredicateFactory。文中VipRoutePredicateFactory实现自定义参数匹配断言:校验请求携带指定参数且值完全匹配,仅 VIP 用户可访问对应路由。核心实现要点:
- 内部静态 Config 类承载配置参数,配合
@NotEmpty做参数校验; shortcutFieldOrder定义 yml 短配置参数顺序;apply方法编写匹配逻辑,从请求中读取参数完成比对。
java
package cn.ecut.gateway.predicate;
import jakarta.validation.constraints.NotEmpty;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
@Component
public class VipRoutePredicateFactory extends AbstractRoutePredicateFactory<VipRoutePredicateFactory.Config> {
public VipRoutePredicateFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("param","value");
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
//localhost/search?q=haha&user=liu
ServerHttpRequest request = exchange.getRequest();
String first= request.getQueryParams().getFirst(config.param);
return StringUtils.hasText(first)&& first.equals(config.value);
}
};
}
/**
* 可以配置的参数
*/
@Validated
public static class Config {
@NotEmpty
private String param;
@NotEmpty
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
}
四、过滤器:请求与响应的统一处理器
过滤器负责对转发前后的请求、响应做加工处理,分为全局默认过滤器 (所有请求执行)和路由自定义过滤器(仅当前路由生效)。自定义过滤器需继承对应过滤器工厂父类,类名与 yml 配置名称保持一致。
1. 父类区分
AbstractGatewayFilterFactory:通用自定义过滤器,支持多参数自定义配置;AbstractNameValueGatewayFilterFactory:键值对专用过滤器,简化name=value格式配置。
2. 实战:一次性令牌过滤器 OnceTokenGatewayFilterFactory
基于AbstractNameValueGatewayFilterFactory开发,依托 WebFlux 响应式异步 API,在请求处理完成后,给响应头自动注入一次性令牌:
- 后置逻辑放在
chain.filter(exchange).then()中,保证响应生成后修改 Header; - 支持两种令牌模式:uuid 随机串、固定 jwt 标识;
- yml 配置格式:
OnceToken=自定义头名称,令牌类型。
完整核心代码:
java
package cn.ecut.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.UUID;
/**
* 响应式api都是异步的
*/
@Component
public class OnceTokenGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//每次打开,添加一个一次性令牌,支持uuid,jwt等各种格式
return chain.filter(exchange).then(
Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
String value = config.getValue();
if("uuid".equalsIgnoreCase(config.getValue())){ //不分大小写
value= UUID.randomUUID().toString();
}
if("jwt".equalsIgnoreCase(config.getValue())){
value="jwt";
}
headers.add(config.getName(), value);
})
);
}
};
}
}
五、网关全局跨域 CORS 配置
单体项目可在 Controller 添加@CrossOrigin解决跨域,微服务架构推荐统一在网关配置全局跨域,避免每个服务重复开发。基础配置示例:
yml
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]': # 全局所有路径生效
allowedOrigins: "*" # 允许所有前端域名(生产环境建议指定域名)
allowedMethods: "*" # 放行全部请求方式
生产优化提示:
allowedOrigins: *存在安全风险,应填写前端固定域名;开启allowCredentials携带 Cookie 时,禁止使用通配符域名。
六、整体总结与落地思路
Spring Cloud Gateway 是微服务架构的流量枢纽,整套体系由路由、断言、过滤器三大核心组件构成:
- 路由:定义转发目标,实现流量分发;
- 断言:精细化控制哪些请求可以走当前路由;
- 过滤器:统一拦截改造请求、响应,实现跨域、令牌下发、日志、鉴权等通用逻辑。
依托响应式非阻塞架构,网关具备高性能优势,同时提供标准化扩展接口,支持自定义断言、过滤器灵活拓展业务能力。开发过程中需要遵循负载均衡依赖、Feign 注解、响应式后置处理等规范,规避常见 404、响应头失效、参数匹配异常等问题。
在实际项目中,可基于本文自定义组件拓展能力:结合令牌过滤器实现网关统一鉴权、自定义 IP 断言实现访问黑白名单、全局过滤器统一打印请求日志,将所有与业务无关的流量处理逻辑收敛至网关,大幅简化后端微服务开发成本。