首页 > 其他分享 >API网关

API网关

时间:2023-12-09 22:34:52浏览次数:32  
标签:网关 请求 Spring API 路由 Gateway Cloud

1.API网关:

(1)什么是网关?

  微服务背景下,一个系统被拆分为多个服务,但是像安全认证,流量控制,日志,监控等功能是每个服务都需要的,没有网关的话,我们就需要在每个服务中单独实现,重复且零散。

  实际上,网关主要做了两件事情:请求转发 + 请求过滤

  由于引入网关之后,会多一步网络转发,因此性能会有一点影响(几乎可以忽略不计)。 另外,我们需要保障网关服务的高可用,避免单点风险

  网关服务外层通过 Nginx(其他负载均衡设备/软件也行) 进⾏负载转发以达到⾼可⽤。Nginx 在部署的时候,尽量也要考虑高可用,避免单点风险。

(2)网关能提供哪些功能?

绝大部分网关可以提供下面这些功能(有一些功能需要借助其他框架或者中间件):
  • 请求转发:将请求转发到目标微服务。
  • 负载均衡:根据各个微服务实例的负载情况或者具体的负载均衡策略配置对请求实现动态的负载均衡。
  • 安全认证:对用户请求进行身份验证并仅允许可信客户端访问 API,并且还能够使用类似 RBAC 等方式来授权。
  • 参数校验:支持参数映射与校验逻辑。
  • 日志记录:记录所有请求的行为日志供后续使用。
  • 监控告警:从业务指标、机器指标、JVM 指标等方面进行监控并提供配套的告警机制。
  • 流量控制:对请求的流量进行控制,也就是限制某一时刻内的请求数。
  • 熔断降级:实时监控请求的统计信息,达到配置的失败阈值后,自动熔断,返回默认值。
  • 响应缓存:当用户请求获取的是一些静态的或更新不频繁的数据时,一段时间内多次请求获取到的数据很可能是一样的。对于这种情况可以将响应缓存起来。这样用户请求可以直接在网关层得到响应数据,无需再去访问业务服务,减轻业务服务的负担。
  • 响应聚合:某些情况下用户请求要获取的响应内容可能会来自于多个业务服务。网关作为业务服务的调用方,可以把多个服务的响应整合起来,再一并返回给用户。
  • 灰度发布:将请求动态分流到不同的服务版本(最基本的一种灰度发布)。
  • 异常处理:对于业务服务返回的异常响应,可以在网关层在返回给用户之前做转换处理。这样可以把一些业务侧返回的异常细节隐藏,转换成用户友好的错误提示返回。
  • API 文档: 如果计划将 API 暴露给组织以外的开发人员,那么必须考虑使用 API 文档,例如 Swagger 或 OpenAPI。
  • 协议转换:通过协议转换整合后台基于 REST、AMQP、Dubbo 等不同风格和实现技术的微服务,面向 Web Mobile、开放平台等特定客户端提供统一服务。
  • 证书管理:将 SSL 证书部署到 API 网关,由一个统一的入口管理接口,降低了证书更换时的复杂度。

(3)有哪些常见的网关系统?

# Netflix Zuul

# Spring Cloud Gateway

  SpringCloud Gateway 属于 Spring Cloud 生态系统中的网关,其诞生的目标是为了替代老牌网关 Zuul。准确点来说,应该是 Zuul 1.x。

  为了提升网关的性能,SpringCloud Gateway 基于 Spring WebFlux 。Spring WebFlux 使用 Reactor 库来实现响应式编程模型,底层基于 Netty 实现同步非阻塞的 I/O。

  Spring Cloud Gateway 不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,限流。

  Spring Cloud Gateway 和 Zuul 2.x 的差别不大,也是通过过滤器来处理请求。不过,目前更加推荐使用 Spring Cloud Gateway 而非 Zuul,Spring Cloud 生态对其支持更加友好。

# OpenResty

  OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

  OpenResty 基于 Nginx,主要还是看中了其优秀的高并发能力。不过,由于 Nginx 采用 C 语言开发,二次开发门槛较高。如果想在 Nginx 上实现一些自定义的逻辑或功能,就需要编写 C 语言的模块,并重新编译 Nginx。

  为了解决这个问题,OpenResty 通过实现 ngx_luastream_lua 等 Nginx 模块,把 Lua/LuaJIT 完美地整合进了 Nginx,从而让我们能够在 Nginx 内部里嵌入 Lua 脚本,使得可以通过简单的 Lua 语言来扩展网关的功能,比如实现自定义的路由规则、过滤器、缓存策略等。

Lua 是一种非常快速的动态脚本语言,它的运行速度接近于 C 语言。
LuaJIT 是 Lua 的一个即时编译器,它可以显著提高 Lua 代码的执行效率。
LuaJIT 将一些常用的 Lua 函数和工具库预编译并缓存,这样下次调用就可以直接使用缓存的字节码,大大加快了执行速度。

# Kong

  Kong 是一款基于 OpenResty(Nginx + Lua)的高性能、云原生、可扩展、生态丰富的网关系统,主要由 3 个组件组成:

  • Kong Server:基于 Nginx 的服务器,用来接收 API 请求。
  • Apache Cassandra/PostgreSQL:用来存储操作数据。
  • Kong Dashboard:官方推荐 UI 管理工具,当然,也可以使用 RESTful 方式 管理 Admin api。

  由于默认使用 Apache Cassandra/PostgreSQL 存储数据,Kong 的整个架构比较臃肿,并且会带来高可用的问题。

  Kong 提供了插件机制来扩展其功能,插件在 API 请求响应循环的生命周期中被执行。比如在服务上启用 Zipkin 插件:

  Kong 本身就是一个 Lua 应用程序,并且是在 Openresty 的基础之上做了一层封装的应用。归根结底就是利用 Lua 嵌入 Nginx 的方式,赋予了 Nginx 可编程的能力,这样以插件的形式在 Nginx 这一层能够做到无限想象的事情。例如限流、安全访问策略、路由、负载均衡等等。编写一个 Kong 插件,就是按照 Kong 插件编写规范,写一个自己自定义的 Lua 脚本,然后加载到 Kong 中,最后引用即可。除了 Lua,Kong 还可以基于 Go 、JavaScript、Python 等语言开发插件,得益于对应的 PDK(插件开发工具包)。

# APISIX

  APISIX 是一款基于 OpenResty 和 etcd 的高性能、云原生、可扩展的网关系统。

etcd 是使用 Go 语言开发的一个开源的、高可用的分布式 key-value 存储系统,使用 Raft 协议做分布式共识。

  与传统 API 网关相比,APISIX 具有动态路由和插件热加载,特别适合微服务系统下的 API 管理。并且,APISIX 与 SkyWalking(分布式链路追踪系统)、Zipkin(分布式链路追踪系统)、Prometheus(监控系统) 等 DevOps 生态工具对接都十分方便

  作为 Nginx 和 Kong 的替代项目,APISIX 目前已经是 Apache 顶级开源项目,并且是最快毕业的国产开源项目。国内目前已经有很多知名企业(比如金山、有赞、爱奇艺、腾讯、贝壳)使用 APISIX 处理核心的业务流量。

  根据官网介绍:“APISIX 已经生产可用,功能、性能、架构全面优于 Kong”。

  APISIX 同样支持定制化的插件开发。开发者除了能够使用 Lua 语言开发插件,还能通过下面两种方式开发来避开 Lua 语言的学习成本:

  • 通过 Plugin Runner 来支持更多的主流编程语言(比如 Java、Python、Go 等等)。通过这样的方式,可以让后端工程师通过本地 RPC 通信,使用熟悉的编程语言开发 APISIX 的插件。这样做的好处是减少了开发成本,提高了开发效率,但是在性能上会有一些损失。
  • 使用 Wasm(WebAssembly) 开发插件。Wasm 被嵌入到了 APISIX 中,用户可以使用 Wasm 去编译成 Wasm 的字节码在 APISIX 中运行。
Wasm 是基于堆栈的虚拟机的二进制指令格式,一种低级汇编语言,非常接近已编译的机器代码,和本机性能。
Wasm 最初是为浏览器构建的,但是随着技术的成熟,在服务器端看到了越来越多的用例。

# Shenyu

  Shenyu 是一款基于 WebFlux 的可扩展、高性能、响应式网关,Apache 顶级开源项目。

  Shenyu 通过插件扩展功能,插件是 ShenYu 的灵魂,并且插件也是可扩展和热插拔的。不同的插件实现不同的功能。Shenyu 自带了诸如限流、熔断、转发、重写、重定向、和路由监控等插件。

(4)如何选择?

  最常用的是 Spring Cloud Gateway、Kong、APISIX 。

  对于业务以 Java 为主要开发语言的情况,Spring Cloud Gateway 通常是个不错的选择,其优点有:简单易用、成熟稳定、与 Spring Cloud 生态系统兼容、Spring 社区成熟等等。不过,Spring Cloud Gateway 也有一些局限性, 一般还需要结合其他网关一起使用比如 OpenResty。并且,其性能相比较于 Kong 和 APISIX,还是差一些。

  如果对性能要求比较高的话,Kong 和 APISIX 功能更丰富,性能更强大,技术架构更贴合云原生。Kong 是开源 API 网关的鼻祖,生态丰富,用户群体庞大。APISIX 属于后来者,更优秀一些,根据 APISIX 官网介绍:“APISIX 已经生产可用,功能、性能、架构全面优于 Kong”。

  • APISIX 基于 etcd 来做配置中心,不存在单点问题,云原生友好;而 Kong 基于 Apache Cassandra/PostgreSQL ,存在单点风险,需要额外的基础设施保障做高可用。
  • APISIX 支持热更新,并且实现了毫秒级别的热更新响应;而 Kong 不支持热更新。
  • APISIX 的性能要优于 Kong 。
  • APISIX 支持的插件更多,功能更丰富。
 

(1) 什么是 Spring Cloud Gateway?

  Spring Cloud Gateway 属于 Spring Cloud 生态系统中的网关,其诞生的目标是为了替代老牌网关 Zuul (Zuul 1.x)。

  为了提升网关的性能,Spring Cloud Gateway 基于 Spring WebFlux 。Spring WebFlux 使用 Reactor 库来实现响应式编程模型,底层基于 Netty 实现同步非阻塞的 I/O。

  Spring Cloud Gateway 不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,限流。

  Spring Cloud Gateway 和 Zuul 2.x 的差别不大,也是通过过滤器来处理请求。不过,目前更加推荐使用 Spring Cloud Gateway 而非 Zuul,Spring Cloud 生态对其支持更加友好。

(2)Spring Cloud Gateway 的工作流程?

  Spring Cloud Gateway 的工作流程如下图所示:

  具体流程:

  • 路由判断:客户端的请求到达网关后,先经过 Gateway Handler Mapping 处理,这里面会做断言(Predicate)判断,看下符合哪个路由规则,这个路由映射后端的某个服务。
  • 请求过滤:然后请求到达 Gateway Web Handler,这里面有很多过滤器,组成过滤器链(Filter Chain),这些过滤器可以对请求进行拦截和修改,比如添加请求头、参数校验等等,有点像净化污水。然后将请求转发到实际的后端服务。这些过滤器逻辑上可以称作 Pre-Filters,Pre 可以理解为“在...之前”。
  • 服务处理:后端服务会对请求进行处理。
  • 响应过滤:后端处理完结果后,返回给 Gateway 的过滤器再次做处理,逻辑上可以称作 Post-Filters,Post 可以理解为“在...之后”。
  • 响应返回:响应经过过滤处理后,返回给客户端。
  总结流程:客户端的请求先通过匹配规则找到合适的路由,就能映射到具体的服务。然后请求经过过滤器处理后转发给具体的服务,服务处理后,再次经过过滤器处理,最后返回给客户端。

(3) Spring Cloud Gateway 的断言是什么?

  断言(Predicate): 就是对一个表达式进行 if 判断,结果为真或假,如果为真则做这件事,否则做那件事。

  在 Gateway 中,如果客户端发送的请求满足了断言的条件,则映射到指定的路由器,就能转发到指定的服务上进行处理。

  断言配置的示例如下,配置了两个路由规则,有一个 predicates 断言配置,当请求 url 中包含 api/thirdparty,就匹配到了第一个路由 route_thirdparty

   常见路由断言规则:

(4)Spring Cloud Gateway 的路由和断言是什么关系?

  Route 路由和 Predicate 断言的对应关系如下::

  • 一对多:一个路由规则可以包含多个断言。如上图中路由 Route1 配置了三个断言 Predicate。
  • 同时满足:如果一个路由规则中有多个断言,则需要同时满足才能匹配。如上图中路由 Route2 配置了两个断言,客户端发送的请求必须同时满足这两个断言,才能匹配路由 Route2。
  • 第一个匹配成功:如果一个请求可以匹配多个路由,则映射第一个匹配成功的路由。如上图所示,客户端发送的请求满足 Route3 和 Route4 的断言,但是 Route3 的配置在配置文件中靠前,所以只会匹配 Route3。

(5)Spring Cloud Gateway 如何实现动态路由?

  在使用 Spring Cloud Gateway 的时候,官方提供的方案总是基于配置文件或代码配置的方式。

  Spring Cloud Gateway 作为微服务的入口,需要尽量避免重启,而现在配置更改需要重启服务不能满足实际生产过程中的动态刷新、实时变更的业务需求,所以我们需要在 Spring Cloud Gateway 运行时动态配置网关。

  实现动态路由的方式有很多种,其中一种推荐的方式是基于 Nacos 注册中心来做Spring Cloud Gateway 可以从注册中心获取服务的元数据(例如服务名称、路径等),然后根据这些信息自动生成路由规则。这样,当你添加、移除或更新服务实例时,网关会自动感知并相应地调整路由规则,无需手动维护路由配置。

  其实这些复杂的步骤并不需要我们手动实现,通过 Nacos Server 和 Spring Cloud Alibaba Nacos Config 即可实现配置的动态变更。

(6)Spring Cloud Gateway 的过滤器有哪些?

过滤器 Filter 按照请求和响应可以分为两种:

  • Pre 类型:在请求被转发到微服务之前,对请求进行拦截和修改,例如参数校验、权限校验、流量监控、日志输出以及协议转换等操作。
  • Post 类型:微服务处理完请求后,返回响应给网关,网关可以再次进行处理,例如修改响应内容或响应头、日志输出、流量监控等。

另外一种分类是按照过滤器 Filter 作用的范围进行划分:

  • GatewayFilter局部过滤器,应用在单个路由或一组路由上的过滤器。标红色表示比较常用的过滤器。
  • GlobalFilter全局过滤器,应用在所有路由上的过滤器。

 局部过滤器具体使用:

filters: #过滤器
  - RewritePath=/api/(?<segment>.*),/$\{segment} # 将跳转路径中包含的 “api” 替换成空

 全局过滤器最常见的用法是进行负载均衡。配置如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: route_member # 第三方微服务路由规则
          uri: lb://passjava-member # 负载均衡,将请求转发到注册中心注册的 passjava-member 服务
          predicates: # 断言
            - Path=/api/member/** # 如果前端请求路径包含 api/member,则应用这条路由规则
          filters: #过滤器
            - RewritePath=/api/(?<segment>.*),/$\{segment} # 将跳转路径中包含的api替换成空

  这里有个关键字 lb,用到了全局过滤器 LoadBalancerClientFilter,当匹配到这个路由后,会将请求转发到 passjava-member 服务,且支持负载均衡转发,也就是先将 passjava-member 解析成实际的微服务的 host 和 port,然后再转发给实际的微服务。

(7)Spring Cloud Gateway 支持限流吗?

  Spring Cloud Gateway 自带了限流过滤器,对应的接口是 RateLimiterRateLimiter 接口只有一个实现类 RedisRateLimiter (基于 Redis + Lua 实现的限流),提供的限流功能比较简易且不易使用。

  从 Sentinel 1.6.0 版本开始,Sentinel 引入了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:route 维度和自定义 API 维度。也就是说,Spring Cloud Gateway 可以结合 Sentinel 实现更强大的网关流量控制.

(8)Spring Cloud Gateway 如何自定义全局异常处理?

  在 SpringBoot 项目中,我们捕获全局异常只需要在项目中配置 @RestControllerAdvice@ExceptionHandler就可以了。不过,这种方式在 Spring Cloud Gateway 下不适用。

  Spring Cloud Gateway 提供了多种全局处理的方式,比较常用的一种是实现ErrorWebExceptionHandler并重写其中的handle方法。

@Order(-1)
@Component
@RequiredArgsConstructor
public class GlobalErrorWebExceptionHandler implements ErrorWebExceptionHandler {
    private final ObjectMapper objectMapper;
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
    // ...
    }
}

 

标签:网关,请求,Spring,API,路由,Gateway,Cloud
From: https://www.cnblogs.com/cjhtxdy/p/17891503.html

相关文章

  • refcount_t API 与 atomic_t 的比较 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/refcount-vs-atomic.htmlrefcount_tAPI与atomic_t的比较介绍相关的内存排序类型函数比较非“读/修改/写”(RMW)操作基于增量的操作,不返回值基于减量的RMW操作,不返回值基于增量的RMW操作,返回值通用的减......
  • 核心API文档 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/core-api/index.html#memory-management核心API文档这是核心内核API手册的开头部分。非常感谢您进行文档的转换和编写!核心实用程序本节包含一般和“核心核心”文档。首先是一大堆来自docbook时代的kerneldoc信息,实际上应该在有人有精......
  • 饮冰十年-人工智能-FastAPI-03- FastAPI之模型迁移(类似Django的migrante)
         在开发Web应用程序时,通常会涉及到数据库模型的更改,例如添加新的表、字段或索引。为了使这些更改反映在数据库中,我们使用数据库迁移工具。FastAPI本身并不包含数据库迁移(migration)的功能,但你可以使用第三方库来处理数据库迁移。其中,Alembic是一个常用的数据库迁......
  • FastAPI-请求参数与验证
    最近想搞一下接口,希望能简单上手,前后端分离,大致看了一遍SpringBoot,Gin,NodeJs,Flask,Django,FastAPI等,感觉还是用Python语言来写比较简单呀,关键点在于它语法清晰,能让我直接思考业务逻辑,而不是各种语法折腾.FASTAPI简介Documentation:https://fastap......
  • k8s:通过 kubectl 插件 Kubepug 实现集群升级检查(废弃API资源检查)
    背景:k8s的版本迭代很快,虽然主要版本一直没有变化,但是次要版本一直在迭代,2022年一年就发布了三个次要版本,同时不同的次要版本之间API资源一直在变化,有新加入的,也有废弃删除的。不同版本的api资源版本也有不同,往往不是向下兼容的,比如在低版本中API资源版本为v1beta1,而高版......
  • 通过C语言的API预处理管理MySQL
    一、C的API预处理语句MySQL客户端/服务器协议提供了预处理语句。该功能采用了由mysql_stmt_init()初始化函数返回的MYSQL_STMT语句处理程序数据结构。对于多次执行的语句,预处理执行是一种有效的方式。首先对语句进行解析,为执行作好准备。接下来,在以后使用初始化函数返回的语句句柄......
  • 微型5G智能网关助力打造智能清洁机器人
    智能机器人不断融入我们的生活,提供了越来越多样化的服务,例如专用于卫生清洁的机器人,就已经广泛应用于酒店、体育馆、大型商场、写字楼、工地等各种场景,相较于人工,机器人在此类具有高度重复性、劳动量大的工作中具有显著优势。  清洁机器人通常需要满足大面积的清洁工作,在工......
  • 13、QT窗口API函数基础知识
    QT窗口API函数geometry()用于获取窗口在屏幕上的几何位置和大小QRectgeo=widget->geometry();intx=geo.x();//窗口左上角的x坐标inty=geo.y();//窗口左上角的y坐标intw=geo.width();//窗口的宽度inth=geo.height();//窗口的高度width()函数返......
  • Modbus转Profinet网关同时控制6台232 Modbus伺服
    Modbus转Profinet网关同时控制6台232Modbus伺服利用Modbus转Profinet网关(XD-MDPN100/XD-PNR200),我们可以实现对6台232Modbus伺服的控制。通过连接这些伺服设备到Modbus转Profinet网关,我们可以方便地将它们接入Profinet网络,并实现对它们的远程控制和监测。这就为我们提供了一个便......
  • .net 温故知新【15】:Asp.Net Core WebAPI 配置
    关于Asp.NetCore中的配置实际之前我已经整理过.net中以json方式进行配置的介绍(.net温故知新:【8】.NET中的配置从xml转向json),当时我们说Asp.NetCore也是按照基础方法,只是组织形式的问题,有个封装过程。所以我这里就着重介绍一下Asp.NetCore中配置的重点。1、主机配置和应用程......