Gateway网关

什么是网关?

网关是一个位于微服务架构前端的组件,它充当了所有微服务的入口。网关负责路由请求、负载均衡、安全认证、流量控制、监控和日志记录等任务。网关还可以将多个微服务组合成一个统一的 API,从而简化客户端与微服务之间的通信。

有 Nginx 了为什么还要 SpringCloud Gateway 做网关,两者有啥区别?

Nginx 属于前置网关,擅长处理静态资源、SSL 加密和简单的流量管理,但不支持动态路由决策和复杂的业务逻辑。

Spring Cloud Gateway 是专门为微服务架构设计的,更加贴近业务逻辑,支持动态路由、复杂的过滤器、监控、权限、限流等。

在生产环境中,通常会把两者结合起来,Nginx 用来处理静态资源和高并发流量,Spring Cloud Gateway 用来实现动态路由、权限控制和业务逻辑处理。

Gateway的三大核心

Spring Cloud Gateway 网关的三大核心分别是路由(Route)、断言(Predicate)、过滤器(Filter)。Spring Cloud Gateway 底层使用了高性能的通信框架Netty。

  1. Filter(过滤器):

    和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对上游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。

  2. Route(路由):

    网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。

  3. Predicate(断言):

    这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入参数类型是一个 ServerWebExchange。

路由配置方式

1
2
3
4
5
6
7
8
9
10
11
12
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: url-proxy-1
uri: https://blog.csdn.net
predicates:
- Path=/csdn

Gateway 中uri有三种配置方式

  • websocket配置方式: ws://localhost:8000

  • http地址配置方式: http://localhost:8000

  • Nacos注册中心配置方式: lb://xx-path

断言

简而言之,Predicate 就是为了实现一组匹配规则,让请求找到对应的 Route 进行处理。

Spring Cloud Gateway 创建 Route 对象时,会使用 RoutePredicateFactory 创建 Predicate 对象,Predicate 对象可以赋值给 Route。

  • Spring Cloud Gateway 包含许多内置的 Route Predicate Factories。

  • 所有这些断言都匹配 HTTP 请求的不同属性。

  • 多个 Route Predicate Factories 可以通过逻辑与(and)结合起来一起使用。

常用断言:

  • 匹配权重:
1
2
Predicates:
- Weight=group1
  • 匹配时间
1
2
Predicates:
- After=2022-10-10T14:25:25.000+8:00[Asia/Shanghai]
  • 匹配查询参数
1
2
Predicates:
- Query=username, abc.
  • 匹配请求路径
1
2
Predicates:
- Path=/root/**
  • 匹配指定名称的请求头
1
2
Predicates:
- Header=X-Request-Id, \d+

如果内置的模板不能满足需求,也可以自定义断言规则,方法也比较简单,按照以下套路即可:

  • 继承 AbstractRoutePredicateFactory 抽象类

  • 实现 IRoutePredicateFactory 接口

  • 类可以任意命名,但是必须以 RoutePredicateFactory 后缀结尾

过滤器

网关中的过滤器,有点类似 SpringMVC 里面的拦截器 Interceptor,以及 Servlet 过滤器,其中「pre」和「post」分别会在请求被执行前调用和被执行后调用,用来修改请求和响应信息。

按类型分,过滤器分为全局默认过滤器、单一内置过滤器和自定义过滤器。

全局过滤器

全局过滤器作用于所有的路由,不需要单独配置,我们可以用它来实现很多统一处理的业务需求,比如权限认证,IP 访问限制等。PmHub 中的 AuthFilter.java 就是采用的全局过滤器,只需要实现 GlobalFilter, Ordered 这两个接口就可以了。

单一内置过滤器

单一内置过滤器也可以称为网关过滤器,这种过滤器主要作用于单一路由。

以下为常见单一内置过滤器:

  • 指定请求头内容
1
2
3
filters:
- AddRequestHeader=X-Request-pmhub,pmhubValue1 # 请求头kv,若一头含有多个参数则写一行设置
- AddRequestHeader=X-Request-pmhub2,pmhubValue2
  • 指定请求参数
1
2
3
4
filters:
- AddRequestParameter=customerId,9527001 # 新增请求参数Parameter: k, v
- RemoveRequestParameter=customerName # 删除url请求参数customerName,你传递过来也是null

  • 指定响应头
1
2
filters:
- AddResponseHeader=X-Response-pmhub, BlueResponse # 新增请求参数X-Response-pmhub并设置为BlueResponse
  • 添加响应头信息
1
2
filters:
- RewriteResponseBody=application/json, application/xml # 替换响应体,将所有的application/json替换为application/xml

自定义过滤器

如何统计接口的调用耗时情况?

可以利用 Gateway 的自定义过滤器来实现该功能。

我们创建一个全局 Filter,实现 GlobalFilter, Ordered 两个接口,并在 filter 方法中进行接口访问时间统计:
① 在接口调用开始时,记录当前时间戳,并将其存储在 ServerWebExchange 的属性中。

② 在接口调用结束时,通过 Mono.fromRunnable 的 then 方法,获取存储的开始时间,计算当前时间与开始时间的差值,即为接口调用的耗时。

Gateway 限流配置

限流,顾名思义,就是对流量进行限制。通过实施限流措施,我们可以有效地管理系统的每秒请求数(QPS),从而对系统进行保护。

常见的限流算法包括:计数器算法、漏桶算法(Leaky Bucket)、以及令牌桶算法(Token Bucket)。

在 Spring Cloud Gateway 中,官方提供了 RequestRateLimiterGatewayFilterFactory 过滤器工具,通过结合 Redis 和 Lua 脚本,可以实现基于令牌桶的限流方式。

Gateway 黑名单配置

顾名思义,黑名单就是一个禁止访问的 URL 列表。我们可以创建自定义过滤器 BlackListUrlFilter,并配置黑名单列表 blacklistUrl。当然,如果有其他需求,还可以实现自定义规则的过滤器来满足特定的过滤要求。

Gateway 白名单配置

顾名思义,就是允许访问的 URL 地址列表,且无需登录就能访问。例如登录、注册接口,就可以放在自名单里面。爱她,就把她放进来吧(^^)/


Gateway网关
http://bloomivy.github.io/2025/02/06/Gateway网关/
作者
Bloom
发布于
2025年2月6日
许可协议