APISIX入门简述

638 阅读11分钟

1.Apache APISIX介绍

1.1 什么是Apache APISIX

Apache APISIX 是一个动态、实时、高性能的云原生 API 网关,提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。可以使用Apache APISIX 处理传统的南北向流量,也可以处理服务间的东西向流量。同时,它也支持作为 K8s Ingress Controller 来使用。 Apache APISlX官网:https:/lapisix,apache.org/

南北向流量:客户端到服务器之间通信的流量 (client → server)
东西向流量:服务器和服务器之间的流量(server → server)

image.png

APISIX主要特性

  • 多平台支持:APISIX 提供了多平台解决方案,它不但支持裸机运行,也支持在Kubemetes 中使用,还支持与 AWS Lambda、Azure Function、Lua 函数和Apache OpenWhisk 等云服务集成。
  • 全动态能力:APISIX 支持热加载,这意味着你不需要重启服务就可以更新APISIX 的配置。
  • 精细化路由:APISIX 支持使用 NGINX内置变量做为路由的匹配条件,你可以自定义匹配函数来过滤请求,匹配路由。
  • 运维友好:APISIX支持与以下工具和平台集成:HashiCorp Vault、Zipkin、Apache SkyWalking、Consu、Nacos、Eureka。 通过 APISIX Dashboard,运维人员可以通过友好且直观的 UI配置 APISIX。
  • 多语言插件支持:APISIX 支持多种开发语言进行插件开发,开发人员可以选择擅长语言的 SDK 开发自定义插件。

1.2 APISIX架构

APISIX 的架构主要分成两部分: 第一部分叫做数据面,它是真正去处理来自客户端请求的一个组件,去处理用户的真实流量,包括像身份验证、证书卸载、日志分析和可观测性等功能。数据面本身并不会存储任何数据,所以它是一个无状态结构
第二部分叫做控制面。APISIX 在底层架构上和其它 API网关的一个很大不同就在于控制面。APISIX 在控制面上并没有使用传统的类似于像 MySQL去做配置存储,而是选择使用 etcd。这样做的好处主要有以下几点:

  • 与产品架构的云原生技术体系更统一
  • 更贴合 API 网关存放的数据类型
  • 能更好地体现高可用特性
  • 拥有低于毫秒级别的变化通知
    使用 etcd 后,对于数据面而言只需监听 etcd 的变化即可。如果轮询数据库的话,可能需要 5-10 秒才能获取取到最新的配置;但如果监听 etcd 的配置变更,就可以将时间控制在毫秒级别之内,达到实时生效的效果。

image.png

etcd官方的定义:分布式系统中最关键数据的分布式、可靠的键值存储。
etcd是一个由CoreOS团队开源的,基于Go语言实现的,用于构建高可用的分布式键值(key-value)数据库。

APISIX 的主要概念和组件

概念/组件描述
Route通过路由定义规则来匹配客户端请求,根据匹配结果加载并执行相应的插件,最后把请求转发给到指走的上游应用。
Upstream上游的作用是按照配置规则对服务节点进行负载均衡,它的地址信息可以直接配置到路由或服务上。
Admin API用户可以通过 Admin API 控制 APISIX 实例。

1.3 Apache APISIX 的技术优势

NGINX 与 Kong 的痛点
在单体服务时代,使用 NGINX 可以应对大多数的场景,而到了云原生时代,NGINX 因为其自身架构的原因则会出现两个问题:

  • 首先是 NGINX 不支持集群管理。几乎每家互联网厂商都有自己的 NGINX 配置管理系统,系统虽然大同小异但是一直没有统一的方案。
  • 其次是 NGINX 不支持配置的热加载。很多公司一旦修改了配置,重新加载NGINX的时间可能需要半个小时以上。并且在 Kubernetes 体系下,上游会经常发生变化,如果使用 NGINX 来处理就需要频繁重启服务,这对于企业是不可接受的。而 Kong 的出现则解决了 NGINX 的痛点,但是又带来了新的问题:
  • Kong 需要依赖于 PostgreSQL 或 Cassandra 数据库,这使 Kong 的整个架构非常臃肿,并且会给企业带来高可用的问题。如果数据库故障了,那么整个 API网关都会出现故障。
  • Kong 的路由使用的是遍历查找,当网关内有超过上千个路由时,它的性能就会出现比较急剧的下降

Kong、OpenResty都是基于Nginx打造的新一代服务器。它们兼具Web服务器的功能,但侧重于网关层特性的延伸

Apache APISIX 和 Kong 相比在技术方面的主要优势,大部分都是在底层模块上的优化和创新。+

无数据库依赖
APISIX 在设计之初,就从底层架构上避免了宕机、丢失数据等情况的发生。因为在控制面上,APISIX 使用了 etcd 存储配置信息,而不是使用关系型数据库,这样做的好处主要有以下几点:

  • 与产品架构的云原生技术体系更统一:
  • 更贴合 API 网关存放的数据类型;
  • 能更好地体现高可用特性,
  • 拥有低于毫秒级别的变化通知。
    使用 etcd 存储配置信息后,对于数据面而言只需监听 etcd 的变化即可。如果采用轮询数据库的方式,可能需要 5-10 秒才能获取到最新的配置信息;如果监听 etcd 的配置信息变更,APISIX 就可以将获取最新配置的时间控制在毫秒级别之内,达到实时生效。

插件热加载
APISIX 和 NGINX 相比,有两处非常大的变化:APISIX 支持集群管理和动态加载。

思考: APISIX是如何实现热加载的
NGINX 热加载的原理
执行 nginx -s reload 热加载命令,就等同于向 NGINX 的 master 进程发送 HUP 信号。在 master 进程收到 HUP 信号后,会依次打开新的监听端口,然后启动新的 worker 进程。此时会存在新旧两套 worker 进程,在新的 worker 进程起来后,master 会向老的worker 进程发送 QUIT 信号进行优雅关闭。老的 worker 进程收到 QUIT 信号后,会首先关闭监听句柄,此时新的连接就只会流进到新的 worker 进程中,老的 worker 进程处理完当前连接后就会结束进程。

image.png

NGINX 热加载的缺陷

  • 首先,NGINX 频繁热加载会造成连接不稳定,增加丢失业务的可能性。NGINX 在执行 reload 指令时,会在旧的 worker 进程上处理已经存在的连接,处理完连接上的当前请求后,会主动断开连接。此时如果客户端没处理好,就可能会丢失业务
  • 这对于客户端来说明显就不是无感知的了。其次,在某些场景下,旧进程回收时间长,进而影响正常业务。比如代理 WebSocket 协议时,由于 NGINX不解析通讯帧,所以无法知道该请求是否为已处理完毕状态。即使 worker 进程收到来自 master 的退出指令,它也无法立刻退出而是需要等到这些连接出现异常、超时或者某一端主动断开后,才能正常退出。再比如NGINX 做 TCP 层和 UDP 层的反向代理时,它也没法知道一个请求究竟要经过多少次请求才算真正地结束。
  • 这就导致旧 worker 进程的回收时间特别长,尤其是在直播、新闻媒体活语音识别等行业。旧 worker 进程的回收时间通常能达到半小时甚至更长,这时如果再频繁 reload,将会导致 shutting down 进程持续增加,最终甚至会导致 NGINX OOM,严重影响业务。

APISIX 在内存中直接生效的热加载方案
在 Apache APISIX 诞生之初,就是希望来解决 NGINX 热加载这个问题的。 image.png

通过上述架构图可以看到,之所以 APISIX 能摆脱 NGINX 的限制是因为它把上游等配置全部放到 APISIX Core 和 Plugin Runtime 中动态指定。
以路由为例,NGINX 需要在配置文件内进行配置,每次更改都需要 reload 之后才能生效。而为了实现路由动态配置,Apache APISIX 在 NGINX 配置文件内配置了单个server,这个 server 中只有一个 location。我们把这个 location 作为主入口,所有的请求都会经过这个 location,再由 APISIX Core 动态指定具体上游。因此 Apache APISIX的路由模块支持在运行时增减、修改和删除路由,实现了动态加载。所有的这些变化,对客户端都零感知,没有任何影响。
比如增加某个新域名的反向代理,在 APISIX 中只需创建上游,并添加新的路由即可,整个过程中不需要 NGINX 进程有任何重启。再比如插件系统,APISIX 可以通过 ip-restriction 插件实现 IP 黑白名单功能,这些能力的更新也是动态方式,同样不需要重启服务。借助架构内的 etcd,配置策略以增量方式实时推送,最终让所有规则实时、动态的生效,为用户带来极致体验。

高性能路由匹配算法
API 网关需要从每个请求的 Host、URI、HTTP 方法等特征中匹配到目标规则,以决定如何对该请求进行处理,因此一个优秀的匹配算法是必不可少的。Apache APISIX 使用的是** RadixTree**,它提供了 KV 存储查找的数据结构并对只有一个子节点的中间节点进行了压缩,因此它又被称为压缩前缀树。此外,在已知 API网关产品中 Apache APISIX 首次将 RadixTree 应用到了路由匹配中,支持一个前缀下有多个不同路由的场景
当对某个请求进行匹配时,RadixTree 将采用层层递进的方式进行匹配,其复杂度为O(K)(K 是路由中 URI的长度,与 API数量多少无关),该算法非常适合公有云、CDN以及路由数量比较多的场景,可以很好地满足路由数量快速增长的需求,

高性能 IP 匹配算法 假设现在有一个包含 500 条 IPv4 记录的 IP 库,APISIX 会将 500 条 IPv4 的记录缓存在Hash 表中,当进行 IP 匹配时使用 Hash 的方式进行査找,时间复杂度为 O(1)。而其他 API 网关则是通过遍历的方式完成 IP 匹配,发送到网关每个请求将逐个遍历最多500 次是否相等后才能知道计算结果。所以 APISIX 的高精度 IP 匹配算法大大提高了需要进行海量IP 黑白名单匹配场景的效率.

精细化路由
API 网关通过请求中的流量特征完成预设规则的匹配,常见特征包含了请求中的 HostURI路径、URI 查询参数、URI路径参数、HTTP 请求方法、请求头等,这些特征是大部分 API 网关产品所支持的。相较于其它产品,Apache APISIX 支持了更多特征以解决复杂多变的使用场景。具体看怎么使用吧,这里只是笔记记录

  • Apache APISIX 支持 NGINX 内置变量
  • Apache APISIX 支持将条件表达式作为匹配规则、
  • Apache APISIX 支持设置路由 tt1
  • Apache APISIX 支持自定义过滤函数

支持多语言插件
APISIX 目前已经支持了 80 多种插件,但仍然难以涵盖用户的所有使用场景。在实际使用场景中,很多企业都会针对具体业务进行定制化的插件开发,通过网关去集成更多的协议或者系统,最终在网关层实现统一管理。
在 APISIX 早期版本中,开发者仅能使用 Lua 语言开发插件。虽然通过原生计算语言开发的插件具备非常高的性能,但是学习 Lua 这门新的开发语言是需要时间和理解成本的。
针对这种情况,APISIX 提供了两种方式来解决:第一种方式是通过 Plugin Runner 来支持更多的主流编程语言(比如 Java、Python、Go等等)。通过这样的方式,可以让后端工程师通过本地 RPC 通信,使用熟悉的编程语言开发 APISIX 的插件。
这样做的好处是减少了开发成本,提高了开发效率,但是在性能上会有一些损失。那么,有没有一种既能达到 Lua 原生性能,同时又兼顾高级编程语言的开发效率方案呢?

image.png

好好学习,天天向上。