Spring Cloud Gateway作为Spring Cloud生态中的API网关解决方案,其核心架构设计充分考虑了现代微服务架构的需求特点。与传统的Zuul网关相比,它基于响应式编程模型构建,底层采用Netty作为网络通信框架,这使得它在高并发场景下能够更高效地处理请求。
网关的核心工作流程涉及三个关键组件协同:
这种组件划分使得网关具备了极高的灵活性和可扩展性。在实际项目中,我们通常会配置数十个路由规则,每个路由可能包含多个断言条件和过滤器链。
Gateway采用Project Reactor作为响应式编程框架,这种非阻塞IO模型相比传统Servlet容器(如Tomcat)的线程池模型,在资源利用率和吞吐量方面具有明显优势。实测数据显示,在同等硬件条件下,Gateway的QPS可以达到传统网关的2-3倍。
重要提示:响应式编程虽然性能优越,但会改变传统的编程思维模式。开发者在编写自定义过滤器时,需要特别注意避免在反应式链中进行阻塞操作。
路由配置是Gateway最核心的功能,其灵活的路由定义方式可以满足各种复杂的业务场景需求。
yaml复制spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=2
这个配置展示了典型的服务路由:
/api/users/开头的请求路由到user-serviceStripPrefix过滤器去掉路径中的前两级(/api/users)lb://前缀表示使用客户端负载均衡在实际生产环境中,我们往往需要更复杂的路由策略:
权重路由配置:
yaml复制routes:
- id: canary-release
uri: lb://new-service
predicates:
- Path=/service/**
- Weight=group1, 20
- id: production-release
uri: lb://old-service
predicates:
- Path=/service/**
- Weight=group1, 80
这种配置可以实现金丝雀发布,将20%的流量导向新版本服务。我们在电商大促前通常会采用这种方式进行灰度测试。
断言是决定请求是否匹配路由的条件判断,Gateway内置了丰富的断言工厂。
| 断言类型 | 配置示例 | 应用场景 |
|---|---|---|
| Path | - Path=/api/** | 路径匹配 |
| Method | - Method=GET,POST | 请求方法限制 |
| Header | - Header=X-Request-Id, \d+ | 请求头校验 |
| Query | - Query=name, zhangsan | 查询参数匹配 |
| Cookie | - Cookie=sessionId, .+ | Cookie校验 |
| RemoteAddr | - RemoteAddr=192.168.1.1/24 | IP白名单控制 |
当内置断言不能满足需求时,可以自定义断言实现:
java复制public class BusinessHourPredicateFactory extends
AbstractRoutePredicateFactory<BusinessHourPredicateFactory.Config> {
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
LocalTime now = LocalTime.now();
return now.isAfter(config.getStartTime())
&& now.isBefore(config.getEndTime());
};
}
}
这个自定义断言实现了营业时间检查,只允许在配置的时间段内访问特定路由。我们在金融系统中常用此类断言实现交易时段控制。
过滤器是Gateway最强大的功能模块,可以对请求和响应进行各种处理。
Gateway的过滤器分为两种类型:
过滤器执行顺序由order参数控制,数值越小优先级越高。合理的顺序设计对业务逻辑的正确性至关重要。
请求头修改过滤器:
yaml复制filters:
- AddRequestHeader=X-Request-Id, 12345
- RemoveRequestHeader=Cookie
请求体修改过滤器:
yaml复制filters:
- ModifyRequestBody=String.class, String.class, (exchange, body) -> {
return Mono.just(body.toUpperCase());
}
限流过滤器:
yaml复制filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
我们在秒杀系统中使用Redis实现的限流过滤器,有效防止系统过载。
下面是一个记录请求耗时的自定义过滤器:
java复制public class ElapsedFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
long startTime = System.currentTimeMillis();
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
long duration = System.currentTimeMillis() - startTime;
exchange.getResponse().getHeaders().add("X-Response-Time", duration+"ms");
}));
}
@Override
public int getOrder() {
return -1; // 高优先级
}
}
这个过滤器会为每个响应添加X-Response-Time头,方便我们监控接口性能。
properties复制reactor.netty.ioWorkerCount=16
yaml复制spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
我们推荐采用以下部署架构:
问题1:路由不生效
问题2:性能瓶颈
问题3:跨域问题
yaml复制spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods:
- GET
- POST
java复制@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http.authorizeExchange()
.pathMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
.anyExchange().authenticated()
.and().oauth2Login()
.and().build();
}
}
这种配置可以实现基于OAuth2的认证鉴权,我们在内部管理系统广泛使用。
Gateway天然支持服务发现,与Nacos/Eureka集成只需简单配置:
yaml复制spring:
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
集成Prometheus监控示例:
java复制@Bean
public MeterRegistryCustomizer<PrometheusMeterRegistry> metricsCommonTags() {
return registry -> registry.config().commonTags("application", "gateway");
}
结合Sleuth实现全链路追踪:
properties复制spring.sleuth.web.enabled=true
spring.sleuth.reactor.instrumentation-type=decorate-queues
在实际项目部署中,我们发现合理配置采样率对系统性能影响很大,通常生产环境设置为0.1(10%采样)即可满足监控需求。