2019 年 10 月 27 日,又拍云联合 Apache APISIX 社区举办 API 网关与高性能服务最佳实践丨Open Talk 杭州站活动,Apache APISIX PPMC 成员王院生做了题为《 Apache APISIX 微服务网关极致性能架构解析》的分享。本次活动,邀请了来自阿里巴巴、蚂蚁金服、Apache APISIX、PolarisTech、又拍云等企业的技术专家,分享网关和高性能服务的实战经验。

王院生,深圳支流科技创始人,Apache APISIX PPMC 成员,OpenResty 社区发起人,《 OpenResty 最佳实践》作者。

以下是分享全文:

前言

大家好,我是来自深圳支流科技的王院生。今年 3 月份,我和志同道合的伙伴一起创业,发起了 APISIX 项目,目前这个项目已进入 Apache 孵化器。Apache APISIX 是一个高性能、可扩展的微服务 API 网关。它是基于 Nginx 和 etcd 来实现,和传统 API 网关相比,APISIX 具备动态路由、插件热加载、gRPC 协议转换等功能,特别适合微服务体系下的 API 管理。

Apache APISIX 是一个蓬勃发展的开源项目,在 2019 年 6 月 6 号开源后,很快就获得了开发者的关注和兴趣,并在开源一个月后被收录到 CNCF(云原生软件基金会) 的全景图中。现在 Apache APISIX 在 GitHub 有 1500 多个 star,近40 多名贡献者,是一个聚集了 800 多人的开发者社区。从开源之初,APISIX 保持每个月发布一个版本,并坚持测试驱动开发、自动化 CI/CD 等理念,以保证代码的质量和稳定性。

Apache APISIX 微服务网关

微服务 API 网关

API 网关并非一个新兴的概念,在十几年前就已经存在了,它的作用主要是作为流量的入口,统一处理和业务相关的请求,让 API 更加安全、快速和准确的得到处理,它有以下传统功能:

  • 反向代理和负载均衡,这和 Nginx 的定位和功能是一致的;
  • 动态上游、动态 SSL 证书和动态限流限速等运行时的动态功能,这是开源版本 Nginx 并不具备的功能;
  • 上游的主动和被动健康检查,以及服务熔断;
  • 在 API 网关的基础之上进行扩展,成为全生命周期的 API 管理平台。

最近几年,业务相关的流量不再仅仅是由 PC 客户端和浏览器发起,更多的来自手机、IoT 设备等,未来随着 5G 的普及,这些流量会越来越多。同时,随着微服务架构的结构变迁,服务之间的流量也开始爆发性的增长。在这种新的业务场景下,对 API 网关有了更多新需求:

  • 云原生友好,架构要轻巧,便于容器化;
  • 对接 Prometheus、Zipkin、Skywalking 等监控组件;
  • 支持 gRPC、Dubbo、websocket、MQTT 等协议的代理,以及 http 到 gRPC 之间的协议转换,以便适应更广泛的场景;
  • 做身份验证,与 Auth0、okta 等身份认证提供商的服务对接,把流量的安全作为头等大事;
  • 通过运行时动态执行用户函数的方式来实现 serverless,让网关的边缘节点更加灵活;
  • 支持插件的热加载,新增、删除和修改插件,都不用重启服务;
  • 开源不锁定用户,支持混合云的部署架构;
  • 最后是网关节点自身要无状态,可以随意的扩容和缩容。

有了这些功能,微服务只需关心业务本身,而与业务相关的周边管理功能,比如服务发现、服务熔断、身份认证、限流限速、统计、性能分析等,均可以在独立的网关层面解决。从这个角度来看,API 网关既可以替代 Nginx 的所有功能处理南北向的流量,也可以胜任 Istio 控制面和 Envoy 数据面的角色,处理东西向的流量。

目前已经有很多可选的网关产品,为什么我们还要进入这个行业进行摸索?我们对现有的产品进行了分析:

  • ⾏业老大:大多基于 Java + JS,闭源性能差,不支持⼆次开发

行业老大们的技术方案大多基于 Java + JS 无一例外,因为他们都是十几年前起步,倒退到那个年代能选的方案也只有 Java 。如果阿里是现在才起步的,我相信他也会有不同的技术选择,但是在那个年代做大应用,只有 Java 可选。如果要做动态,基本也就只有 JS 这条路,最后的组合均为 JAVA + JS 技术方案。它的问题也比较明显:性能差,体态臃肿,二次开发较困难。

  • 行业远见者:多基于 OpenResty 或 Golang,少数开源

在 Ganter 中远见者行列采用的技术方案目前多是基于 OpenResty 和 Golang,能够看到这些行业远见者在具体实现上,整体都比较重。代码量重往往代表结构复杂,最后也发现他们确实效率不高。

  • Apache APISIX 机会:轻巧 + 极致性能 + 热插件

在起步之初,我们意识到必须要比远见者还要好十倍以上,我们才有成功的可能。此时我们看清了要走的一条路:第一要轻巧,第二需要性能极致。最后如果再有丰富的插件生态,就更完美了。

Apache APISIX 发展历程

4 月初,我们开始第一行代码,我们选择在 6 月 6 日开源,因为产品名叫 APISIX,我们希望它容易被大家记住。

7 月,APISIX 进入 CNCF 全景图,这是目前最火的软件基金会。

8 月,我们拥有了第一家商业用户,搞定商业用户的过程确实非常爽,借助 APISIX 内核前两周,就帮用户把 QPS 提升了一倍。

9 月,开源用户贝壳找房正式上线,现在每天至少有 1 亿的流量需要处理(截止目前已经有 2.5 亿日流量),它的 CPU 大约 1% 左右。

9 月我们也开始和 Apache 接触,着手准备捐赠,10 月就真正成功了。这应该是国内第一家由初创公司捐赠的 Apache 项目。通常一个项目要进入 Apache 基本都是以年为单位,但我们只用了一个月。

10 月,我们在继续奔跑,已实现了全平台支持。除了常见的操作系统,两大主流 X86 架构和 ARM64 架构也均全部支持,并经过完整用例回归。APISIX 是一个测试驱动的项目,测试覆盖率到 80% 以上,只要测试用例能完整运行,可以确保在生产中正常使用。

Apache APISIX 的优势

以下是 Apache APISIX 引以为傲的点,它们大多是是竞品完全没有的:

  • ASF 第一个 API ⽹关类项⽬
  • 极简核⼼代码量,不到 4000 ⾏,去除空行、注释行数甚至不到 3000 行
  • 极致的动态转发性能,测试报告显示属于 NO.1
  • 最低的平均请求延迟:740 us
  • 插件热加载/卸载,新旧插件均可,同类竞品中独一无二
  • 允许插件挂载 Nginx 任何阶段
  • 所有的组件都是插件,包括路由自身,这在业内是独一份的,把自由交给用户
  • 完整支持 ARM64
  • 完整支持 IPv6
  • 动态转发物联⽹ MQTT 协议
  • 运行时可以是 OpenResty / Tengine ,自由选择
  • 极致性能校验器 iresty / jsonschema ,已知 jsonschema 校验器实现方案中性能最高

Apache APISIX 技术选型

API 网关产品形态演化

如上图所示,图 ① 为网关最初的产品形态,左侧是客户端,右侧是服务,网关在他们中间;由于服务会做聚集分类,如图 ② 中服务分成两类,此时 API 网关的重要性就体现出来,它需要对外做无感知,需要根据用户请求的流量信息做分发,此时 API 网关就会成为单点故障;由此演化出图 ③ 的形态,有两个 API 网关,它们都可以访问后面的任何一个服务集群,互为备份,是一个高可用的基本形态,客户端可以请求任意一个网关;在图 ④ 中,API Gateway 负责流量转发,etcd 负责配置存储,API Gateway 是管理人员的控制台,所以如果只有 API Gateway 高可用是远远不够的。

真正能够让用户安心的方案应该是 API Gateway、配置中心、控制中心都能够完整支持高可用,作为一个微服务 API 网关需要部署灵活,API Gateway、etcd、管理控制台均需要满足任意数量伸缩,需要多少就部署多少。

这对我们的开源版本提出了一个非常高的挑战,安装形态到底应该什么样子?

我们需要有上图中的三种形态都允许用户去部署:Admin、Gateway、Gateway+Admin。我们的解决方案首先是 All In One,即只有一个 “Gateway+Admin” 的包,当用户需要将 Gateway 和 Admin 分别部署时,只需修改配置,是否启用 Admin 就可以实现。

我们通过配置的方式简单区分节点类型,而任何一个节点里面,既可以单独包含一部分,如 Admin 或者 Gateway,也可以同时包含二者,这种方式让用户能够很容易地解决一堆问题,实现高可用、弹性伸缩、分布式、集群以及故障自动转移。

API 网关基本架构

下面介绍 API 网关的基本架构,这里简单对它做了拆分:

整个流程是管理员通过 admin API 告诉网关需要做什么并保存下来,这也就是我们常说的控制面。相对的是数据面部分处理外部用户真实请求,要根据管理员的规则,对当前请求根据路由匹配得到配置,然后执行配置中的插件并转发到指定上游。

这里涉及三个最基本问题

  • 路由:匹配用户请求,需要功能强大,并且性能足够好
  • 校验器:校验用户请求数据是否合法,需要通用、高性能
  • 配置中心:存储配置,高可用易用,支持增量订阅

如果这三个基本问题回答好,那么这个网关质量也就基本确定了。

Apache APISIX 技术选型

核心思路:技术选型时需要思考到底需要解决什么问题?

  • 配置中心:高可用、增量订阅、历史记录
  • 语言或开发平台:动态、高性能、网关的周边资源丰富
  • 数据校验:开放标准、有一定的生态系统
  • 加分项:顶级路由实现
  • 选型捷径:学习竞对,从 Ganter 报告中获取前辈列表,做分析和比较,尝试站在巨人肩膀总是对的

配置中心:etcd why?

APISIX 配置中心并没有选择传统的关系型数据库,而是选用了 etcd,当时主要考虑到以下要素:

  • 优雅的集群支持
  • 支持历史,可以获取到历史的修改记录
  • 要能够支持事务,有些数据的存放是有条件的
  • 低于毫秒级别的变化通知

通过分析发现 etcd 非常适合我们,当真正看到官方的 why etcd 的说明列表时(如下图),我们就知道我们选对了。

语言和开发平台:OpenResty

新选型 API 网关开发平台基本只有两条路,一个是Lua,即 OpenResty,另一个就是 Golang。Golang 是静态语言,其动态能力不如 Lua ,所以最后选择 OpenResty。我个人从 2014 年到现在一直沉浸在 OpenResty 社区,对它的理解和把控力也会更好。

我们是全新的项目,所以我们直接基于最新的版本来做,OpenResty >= 1.15.8,Tengine>= 2.3.2,二者都是基于 Nginx,搭配他们任何一个作为运行时都可以运行 APISIX。

我们需要借助更通用的语言来吸纳它的周边生态,这方面 Lua 与 C/C++ 是不在一个量级,常见做法可以通过调用 C/C++ 的动态库来这么做。此外,也可以调用基于 Golang 的库。从这个角度看,我们选择 OpenResty 作为基础平台开展 APISIX 业务开发会很顺畅,不用担心周边库匮乏的问题。而且 OpenResty 这几年被用在 API 网关比较多,有很多现成组件也可以利用,APISIX 可能只需要拿过来做二次整合。当然整合过程中也发现了一些项目的开源版本写得不好,二次优化的事情也没少干。

数据校验:jsonschema

jsonschema 的数据校验规范 Google 排名第一,换而言之,如果有校验规范且已经排名第一,我们没有必要自己造一个,知识一定要可以复用,于是选择了 jsonschema 这个标准。这个校验标准几乎涵盖了 C、Java、JS 等主流语言,而且官方提供现成的压测结果。我们任何选型都会格外关注性能表现,如果有现成的压测框架和结果就非常棒。

当然,在实际操作中经历了一些波折:最开始选型在 jsonschema 官方找实现,结果发现没有适合我们的,他们大多都是开源库中用了一点便声称支持,实际上耦合度比较高。

我们找到的第一个选型是 lua-rapidjson,它并不在 jsonschema 官方的推荐列表里,是腾讯开源的。但 rapidjson 有一个比较大的问题是编译条件高,它是一个 C/C++ 的实现,而我们做的是开源的项目,简单易用是我们追求的。此外 rapidjson 只支持了 draft4 里 95% 的内容,有些特性也不支持,比如经常用到的 default 。

于是我们根据一个开源的方案进行改造,实现了新的 iresty / jsonschema,主要增加了下面一些点:

  • 运行时支持 OpenResty
  • 完整支持 draft4
  • 完整支持 draft6、draft 7

这个库采用了编译器的思维方式。我们对其进行了测试:一个简单的对象里面有两个字段,分别是字符串和一个 int 类型,反复进行循环压力测试,跑一百万次,将跑完的时间做比较。iresty / jsonschema 的性能是 lua-rapidjson 的 5-10倍,是 gojsonschema(golang) 性能的 500-1000 倍。

路由:为什么造了 resty-radixtree 路由?

路由是 API 网关的生命,没有高性能的路由,就没有快速的匹配过程,API 网关的性能无法提升。只有路由是 100% 每次参与用户请求的,配置中心和参数校验也不是,因此路由必须要高性能。同时路由匹配条件也要足够灵活和强大,除了要支持最基本的 uri、host,其他可选的如 IP 地址、请求参数、请求头、Cookie 等也需要。

原本以为做到这一步就可以了,但开源项目的用户还是会有其他的需求,最后我添加了自定义函数,用户可以写 Lua 脚本,这也再次使用了 Lua 的动态特性。换而言之,用户完全可以创建判断规则,涉及特别不好表达或还未支持的逻辑,都可以用自定义函数方式先绕着走。

集大成者的路由 resty-radixtree,目前单核心每秒可以达到百万次的匹配,相比之前的选型 libr3,radixtree 的性能至少提升了一个数量级。并且它允许引用任意的 nginx 的内置变量,索引的自由创建也让它轻松支持 uri 或 host+uri 的使用场景。

自此三个选型确定:路由 resty-radixtree,校验器 iresty / jsonschema,配置中心 etcd,Apache APISIX 雏形诞生。

Apache APISIX 架构

如上图,这是 Apache APISIX 目前的业务架构:左侧是管理员,右侧是用户请求。管理员把信息录入放到 etcd 里面缓存后,用户访问 APISIX 做路由,根据路由信息得到结果,匹配到路由交给具体的微服务、serverless 等。

如上图,APISIX 软件层面基本架构并没有采用传统的层层嵌套的方式,只有基础层和业务层,基础层完全脱离于 APISIX 内核,完全无业务绑定,大家可以在任何 OpenResty 项目中引用。

插件可以热插拔,不用重启服务。并且已经内置了常见的限流限速、身份认证、请求改写、URI 重定向、opentracing、serverless 等插件,开箱即用。APISIX 对插件的支持和友商不太一样,具体表现在以下几点:

  • 按需“继承”
  • 优先级排序
  • 允许挂载 Nginx 所有阶段
  • 插件热加载、卸载
  • 插件临时禁⽤

总结 Apache APISIX 三板斧如下:

  • 配置分发借助 etcd ,精简核心
  • 基于 resty-radixtree 的高性能前缀匹配
  • 高性能基础库apisix/core:Nginx 变量提取增强 ;错误日志优化;table 池优化

Apache APISIX 性能测试

Apache APISIX 目前已经具备 30 多个功能,已经基本超过大多开源竞品。通常来说,引入了前面提到的几十项功能,会伴随着性能的下降,那么究竟下降了多少呢?这里我做了一个性能的测试对比。

如上图,右侧是我为了测试写的一个虚假的服务,这个服务是空的,只是把 ngx_lua 里的一些变量拿出来,传给了什么都不做的 fake_fetch,后面的 http filter、log 阶段等一样,没有任何计算量。

随后对 APISIX 和右边的虚假服务分别跑压力测定,对比结果发现 APISIX 的性能仅仅下降了 15%,也就是说在接受了 15% 的性能下降的同时,就可以享受前面提到的所有功能。我们在阿里云的计算平台,单核下可以跑到 23-24k QPS,4 核可以跑到 68k 的 QPS。

欢迎大家通过 github 检索 APISIX 了解更多,同时我们也对外提供一对一的企业服务,欢迎感兴趣的同学和我们联系。

演讲视频观看及 PPT 下载:

Apache APISIX 微服务网关极致性能架构解析

王院生:Apache APISIX 微服务网关极致性能架构解析的更多相关文章

  1. springcloud(十)-Zuul微服务网关

    为什么要使用微服务网关 前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服 ...

  2. OpenResty 社区王院生:APISIX 的高性能实践

    2019 年 7 月 6 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·上海站,OpenResty 软件基金会联合创始人王院生在活动上做了&l ...

  3. 微服务架构学习与思考(10):微服务网关和开源 API 网关01-以 Nginx 为基础的 API 网关详细介绍

    微服务架构学习与思考(10):微服务网关和开源 API 网关01-以 Nginx 为基础的 API 网关详细介绍 一.为什么会有 API Gateway 网关 随着微服务架构的流行,很多公司把原有的单 ...

  4. 使用 Node.js 搭建微服务网关

    目录 Node.js 是什么 安装 node.js Node.js 入门 Node.js 应用场景 npm 镜像 使用 Node.js 搭建微服务网关 什么是微服务架构 使用 Node.js 实现反向 ...

  5. 微服务网关哪家强?一文看懂Zuul, Nginx, Spring Cloud, Linkerd性能差异

      导语:API Gateway是实现微服务重要的组件之一.面对诸多的开源API Gateway,如何进行选择也是架构师需要关注的焦点.本文作者对几个较大的开源API Gateway进行了压力测试,对 ...

  6. 微服务网关 Spring Cloud Gateway

    1.  为什么是Spring Cloud Gateway 一句话,Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是 ...

  7. Zuul微服务网关

    Zuul简介:         Zuul是Netflix开源的微服务网关,它可以和Eureka.Ribbon.Hystrix等组件配合使用.Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能 ...

  8. SpringCloud Gateway微服务网关实战与源码分析-上

    概述 定义 Spring Cloud Gateway 官网地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3 Spring Cl ...

  9. Bumblebee微服务网关的部署和扩展

    Bumblebee是.netcore下开源基于BeetleX.FastHttpApi扩展的HTTP微服务网关组件,它的主要作用是针对WebAPI集群服务作一个集中的转发和管理:作为应用网关它提供了应用 ...

随机推荐

  1. ios发送短信验证码计时器的swift实现

    转载自:http://www.jianshu.com/p/024dd2d6e6e6# Update: Xcode 8.2.1 Swift 3 先介绍一下 属性观测器(Property Observer ...

  2. python解释器执行文件的流程

    一: 启动python解释器,加载内置模块. 找到主文件读入内存,这里涉及到编码问题,一般都是utf8 解释器拿到主文件开始语法词法分析,编译然后执行

  3. Chrome插件开发(三)

    在日常工作中,我们可能经常需要在手机端测试我们所做的页面,如果每次在手机端测试都手输网址,网址短的还好,如果长的网址也需要一个字母一个字母去敲,那无疑是一场噩梦,试想我们有一个工具只需要点击一个按钮就 ...

  4. JDK JRE JVM的区别与关系

    JDK JAVA开发工具包    他包含了JRE   JAVA运行环境   JVM JAVA虚拟机他是跨平台的核心主件   他将Java源文件编译成 .class结尾字节码文件交由不同计算机执行    ...

  5. Go调用cpp类

    CGO是C语言和Go语言之间的桥梁,所以GO是没有办法直接使用CPP的类的. 我们可以通过增加一族C语言函数接口作为CPP类和CGO之前的桥梁的,这样 就可以实现C和Go之间的互联. my_buffe ...

  6. Angular开发规范

    目录  一.         前言 1.1.       规范目的 1.2.       局限性 二.         文件规范 2.1.       文件结构约定 2.2.       单一职责原则 ...

  7. 大数据之路week01--自学之集合_2(Iterator迭代器)

    选代器:是遍历集合的一种方式.迭代器是依赖于集合而存在的.我有一个集合: Collection c = new ArrayList();我们给集合中添加元素: c. add("hello' ...

  8. 猫眼电影App抓包获取评论数据接口

     之前在CSDN程序人生公众号上看到了这篇文章<邪不压正>评分持续走低,上万条网友评论揭秘,是救救姜文还是救救观众?,文中提到了通过抓包猫眼App发现了评论的数据接口:http://m.m ...

  9. VLAN的 基本用法与配置

    需求:在一家小型企业中,所有员工都使用一台交换机,老板为了避免员工私下通信,将他们分配了不同网段,但偶尔还是会发现,有些员工会自行修改网段和别人通信.如果你是这家企业的网络工程师,你该如何处理? 1. ...

  10. java本地缓存

    1.为什么要使用缓存 由于服务器.数据库.网络等资源有限,无法支撑越来越多的请求与计算量,所以将一部分数据放在缓存中,以此减小薄弱环节的计算量和请求流程. 网站中缓存的应用场景:        1:可 ...