
Spring Cloud Gateway 的核心功能与配置详解
Spring Cloud Gateway 是 Spring Cloud 生态系统中的一个核心组件,专为现代微服务架构设计的 API 网关解决方案。它以 Spring Framework 和 Spring Boot 为基础,旨在为开发者提供一个高性能、易扩展、简单易用的网关工具,用于管理微服务流量,执行安全验证,提供动态路由和过滤功能。
写这篇博客的起因是在昨天的面试中,面试官问我项目中使用的Spring Cloud Gateway能否在tomcat服务器上使用,我却一时半会儿答不出来,感到很惭愧。
正确的答案是不能。因为Spring Cloud Gateway需要由Spring Boot和Spring Webflux提供的Netty运行时,它不适用于传统的Servlet容器,例如Tomcat、Jetty、Undertow等。传统的Servlet应用通常会以WAR包的形式部署到应用服务器,但 Spring Cloud Gateway 依赖的是 Netty,而不是 Servlet 容器,因此它无法以 WAR 包部署。
Netty 是一个由 Java 编写的异步事件驱动的网络应用框架,专为快速开发高性能、高可扩展性的网络应用而设计。它是一个开源项目,提供了对网络协议(如 TCP/IP、HTTP、WebSocket 等)的抽象封装,使得开发者可以专注于业务逻辑,而无需深入了解底层网络通信的复杂细节。
Netty之所以能够支持快速开发高性能、高扩展性的网络应用,其原因主要有如下几点:
因为Netty的高性能、异步非阻塞架构和强大的扩展性,能够很好地满足现代微服务网关Spring Cloud Gateway的高并发、低延迟和动态路由等需求。
客户端向Spring Cloud Gateway发出请求,如果Gateway Handler Mapping确定请求与路由匹配,则会将其发送到Gateway Web Handler。该处理程序通过特定于请求的过滤器链运行请求。过滤器可以在发送请求之前和之后运行逻辑。首先会执行所有的“前置(pre)”过滤器逻辑,然后发起代理请求。在代理请求完成后,再执行“后置(post)”过滤器逻辑。
Spring Cloud Gateway支持Route Predicate Factories和GatewayFilter Factories。这两种方式都支持快捷方式配置以及使用完全扩展的参数。
快捷方式配置由过滤器名称识别,其后跟上等号以及使用逗号分隔的参数值,示例如下。
使用两个参数定义Cookie路由谓词工厂:cookie 名称mycookie和匹配mycookievalue值:
而使用参数则更像是标准的yaml配置,通常会有一个name键和args键,args键用于配置谓词或者过滤器的键值对的映射:
按照核心功能及其应用场景,可以大致将Route Predicate Factories分为以上几类。
具体的功能如下:
After:匹配指定时间之后的请求。Before:匹配指定时间之前的请求。Between:匹配指定时间范围内的请求。Cookie:匹配指定名称和值的 Cookie。Header:匹配指定 Header 和正则表达式。Host:匹配 Host 名称(支持 Ant 风格模式)。Method:匹配 HTTP 请求方法(如 GET、POST)。Path:匹配请求路径(支持 URI 模板变量)。Query:匹配请求中的查询参数及其值。RemoteAddr:基于 CIDR 格式匹配远程地址。XForwardedRemoteAddr:基于 X-Forwarded-For Header 匹配远程地址。Weight:按照组的权重比例分配流量。使用的样例可以参考:Route Predicate Factories。
其对应的功能如下:
AddRequestHeader:添加请求头。AddRequestHeadersIfNotPresent:如果请求头不存在,则添加。SetRequestHeader:设置请求头(替换已有的)。RemoveRequestHeader:移除指定请求头。MapRequestHeader:从一个请求头映射到另一个请求头。SetRequestHostHeader:设置请求的 Host 头。AddRequestParameter:添加请求参数。RemoveRequestParameter:移除请求参数。RewriteRequestParameter:重写请求参数。PrefixPath:为路径添加前缀。SetPath:设置请求路径。StripPrefix:移除路径前缀。RewritePath:使用正则表达式重写路径。CacheRequestBody:缓存请求体。ModifyRequestBody:修改请求体内容。AddResponseHeader:添加响应头。SetResponseHeader:设置响应头(替换已有的)。RemoveResponseHeader:移除指定响应头。RewriteResponseHeader:使用正则表达式重写响应头。DedupeResponseHeader:去重响应头。ModifyResponseBody:修改响应体内容。RemoveJsonAttributesResponseBody:从 JSON 响应体中移除指定属性。RequestRateLimiter:基于 Redis 的请求限流。RequestHeaderSize:限制请求头大小。RequestSize:限制请求体大小。CircuitBreaker:使用熔断器保护路由。FallbackHeaders:在熔断回退中添加异常信息到请求头。Retry:失败后重试请求。SecureHeaders:添加安全相关的响应头。SaveSession:在转发请求之前保存会话状态。TokenRelay:转发 OAuth2 令牌到下游服务。RedirectTo:重定向到指定 URL。RewriteLocationResponseHeader:调整响应中 Location 头的值。具体的使用案例依然可以参考:GatewayFilter Factories。
用好以上过滤器,就能够获得一个功能及其强大的网关。
在微服务成为流行的当下,一个服务常常会有多个实例,这个时候就需要使用动态路由,此处以Nacos注册中心为例说明。
Nacos 作为服务注册和配置中心,存储路由配置信息。网关从 Nacos 中获取最新的路由配置。Spring Cloud Gateway通过监听Nacos配置变更事件,在路由配置更新实时刷新网关的路由信息,在应用启动的时候,网关从Nacos加载路由规则。
先引入以下依赖:
而后在application.yml中配置Nacos的连接信息:
在Nacos配置中心中创建一个配置文件,例如gateway-routes.yaml,并在其中定义路由规则。确保该配置的Data ID与应用名称和配置文件名称匹配。
而后在启动类上加上@EnableDiscoveryClient注解,启用Nacos配置和发现功能,最后还需要再在application.yml中加上网关发现功能:
Spring Cloud Gateway的负载均衡主要依赖于Spring Cloud LoadBalancer,引入以下依赖:
在相应的网关服务的application.yml中写入以下配置:
lb://example-service就是对example-service使用了负载均衡的意思,使用负载均衡之后,请求会被均衡负载到多个实例当中。默认的负载均衡策略为轮询,目前Spring Cloud Loadbalancer内置了两种负载均衡策略:
需要切换的时候,只需要在配置文件中更改:
此外,还有其他的负载均衡策略,但是需要自己去实现:
Spring Cloud Gateway 是现代微服务架构中强大的网关解决方案,凭借灵活的路由规则、多样化的负载均衡策略和高性能的 Netty 支持,能够满足多种复杂场景需求。通过合理配置和实践应用,可以充分发挥其能力,为系统的高效稳定运行提供坚实保障。