引言
在微服务架构中,服务数量众多,调用关系复杂。如果没有一个统一的入口来进行流量调度、权限控制和安全管理,系统的可维护性和安全性都会大大降低。Spring Cloud Gateway 作为新一代网关组件,基于 Spring 5、Spring Boot 2.0 和 Project Reactor 的响应式编程模型,为我们提供了一种高性能、统一的 API 路由与管理方式。
本文将从 为什么需要网关 、快速入门 、断言与过滤器机制 、同源策略与跨域问题 等方面进行系统性梳理,帮助读者快速掌握 Gateway 的核心思想与实践技巧。
一、为什么需要网关
在微服务系统中,网关扮演着"守门人"的角色,所有外部请求都会先进入网关,然后再根据规则路由到对应的服务。它的核心价值主要体现在以下几个方面:
-
统一入口
- 外部访问全部先经过 Gateway,便于集中管理和监控。
-
请求路由与负载均衡
- 根据配置的规则转发请求,并在多实例时进行负载均衡。
-
权限控制
- 拦截请求,校验用户是否有访问权限,防止非法访问。
-
限流保护
- 在流量过大时按下游服务的承受能力进行流控,避免雪崩效应。
Spring Cloud Gateway 相比传统的 Zuul,采用响应式编程(WebFlux),性能更高,延迟更低,尤其适合高并发场景。
二、快速入门 Gateway
2.1 创建工程与依赖引入
在 pom.xml 中添加以下依赖:
XML
<!-- 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>
2.2 配置路由规则
在 application.yml 中定义路由规则:
server:
port: 7000
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: product_route
uri: http://localhost:8081/
predicates:
- Path=/product-serv/**
filters:
- StripPrefix=1
此时,访问 http://localhost:7000/product-serv/product/19 会被代理到 http://localhost:8081/product/19。
2.3 高级版本:结合 Nacos 服务发现
通过 lb:// 方式实现负载均衡:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
discovery:
locator:
enabled: true
routes:
- id: product_route
uri: lb://service-product
predicates:
- Path=/product-serv/**
这样,网关会自动从 Nacos 获取服务实例并按策略进行负载均衡。
三、断言工厂(Predicate Factory)
断言(Predicate)决定了请求是否满足路由条件。Spring Cloud Gateway 提供了十几种常见的断言类型:
-
Path:请求路径匹配
- Path=/user/**
-
Method:请求方法限制
- Method=GET,POST
-
Header:请求头条件
- Header=X-Request-Id, \d+
-
After/Before/Between:时间范围限制
-
Cookie 、Host 、Query 、RemoteAddr 等
这些断言通过工厂类(如 PathRoutePredicateFactory)转换为路由条件,实现灵活的流量分发。
四、过滤器工厂(Filter Factory)
4.1 路由过滤器
对特定路由生效,例如:
filters:
- AddRequestHeader=msg, hello
4.2 默认过滤器(DefaultFilter)
对所有路由生效:
default-filters:
- AddRequestHeader=msg, wake up!
4.3 全局过滤器(GlobalFilter)
需要自定义逻辑,例如权限校验、限流等。
示例:拦截请求,校验 authorization=admin,否则拒绝访问。
java
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String auth = exchange.getRequest().getQueryParams().getFirst("authorization");
if ("admin".equals(auth)) {
return chain.filter(exchange);
}
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
}
4.4 执行顺序
-
优先级规则:order 值越小,执行越靠前。
-
同 order 时,执行顺序为:DefaultFilter > 路由过滤器 > GlobalFilter。
五、浏览器同源策略与跨域问题
浏览器的 同源策略 要求协议、域名和端口一致,否则会被视为跨域请求。
例如:
跨域会导致 AJAX 请求被拦截。解决方案是开启 CORS(跨源资源共享)。
Gateway 配置 CORS
spring:
cloud:
gateway:
globalcors:
add-to-simple-url-handler-mapping: true
corsConfigurations:
'[/**]':
allowedOrigins: "http://localhost:8090"
allowedMethods: [ "GET", "POST", "DELETE", "PUT", "OPTIONS" ]
allowedHeaders: "*"
allowCredentials: true
maxAge: 360000
这样就可以允许前端跨域请求,避免浏览器拦截。
六、总结
Spring Cloud Gateway 为微服务提供了一个 统一的请求入口 ,通过 断言与过滤器机制 实现灵活的路由控制、权限校验和流量治理。同时,内置的 CORS 配置 也帮助我们轻松解决前后端分离下的跨域问题。
整体而言,Gateway 是微服务架构中不可或缺的组件。掌握它的配置与原理,将大大提升系统的稳定性与可维护性。