java 单机接口限流处理方案
286
2022-06-07
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 等理念,以保证代码的质量和稳定性。
API 网关并非一个新兴的概念,在十几年前就已经存在了,它的作用主要是作为流量的入口,统一处理和业务相关的请求,让 API 更加安全、快速和准确的得到处理,它有以下传统功能:
最近几年,业务相关的流量不再仅仅是由 PC 客户端和浏览器发起,更多的来自手机、IoT 设备等,未来随着 5G 的普及,这些流量会越来越多。同时,随着微服务架构的结构变迁,服务之间的流量也开始爆发性的增长。在这种新的业务场景下,对 API 网关有了更多新需求:
有了这些功能,微服务只需关心业务本身,而与业务相关的周边管理功能,比如服务发现、服务熔断、身份认证、限流限速、统计、性能分析等,均可以在独立的网关层面解决。从这个角度来看,API 网关既可以替代 Nginx 的所有功能处理南北向的流量,也可以胜任 Istio 控制面和 Envoy 数据面的角色,处理东西向的流量。
目前已经有很多可选的网关产品,为什么我们还要进入这个行业进行摸索?我们对现有的产品进行了分析:
行业老大们的技术方案大多基于 Java + JS 无一例外,因为他们都是十几年前起步,倒退到那个年代能选的方案也只有 Java 。如果阿里是现在才起步的,我相信他也会有不同的技术选择,但是在那个年代做大应用,只有 Java 可选。如果要做动态,基本也就只有 JS 这条路,最后的组合均为 JAVA + JS 技术方案。它的问题也比较明显:性能差,体态臃肿,二次开发较困难。
在 Ganter 中远见者行列采用的技术方案目前多是基于 OpenResty 和 Golang,能够看到这些行业远见者在具体实现上,整体都比较重。代码量重往往代表结构复杂,最后也发现他们确实效率不高。
在起步之初,我们意识到必须要比远见者还要好十倍以上,我们才有成功的可能。此时我们看清了要走的一条路:第一要轻巧,第二需要性能极致。最后如果再有丰富的插件生态,就更完美了。
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 引以为傲的点,它们大多是是竞品完全没有的:
如上图所示,图 ① 为网关最初的产品形态,左侧是客户端,右侧是服务,网关在他们中间;由于服务会做聚集分类,如图 ② 中服务分成两类,此时 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,也可以同时包含二者,这种方式让用户能够很容易地解决一堆问题,实现高可用、弹性伸缩、分布式、集群以及故障自动转移。
整个流程是管理员通过 admin API 告诉网关需要做什么并保存下来,这也就是我们常说的控制面。相对的是数据面部分处理外部用户真实请求,要根据管理员的规则,对当前请求根据路由匹配得到配置,然后执行配置中的插件并转发到指定上游。
这里涉及三个最基本问题:
如果这三个基本问题回答好,那么这个网关质量也就基本确定了。
核心思路:技术选型时需要思考到底需要解决什么问题?
APISIX 配置中心并没有选择传统的关系型数据库,而是选用了 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 的数据校验规范 Google 排名第一,换而言之,如果有校验规范且已经排名第一,我们没有必要自己造一个,知识一定要可以复用,于是选择了 jsonschema 这个标准。这个校验标准几乎涵盖了 C、Java、JS 等主流语言,而且官方提供现成的压测结果。我们任何选型都会格外关注性能表现,如果有现成的压测框架和结果就非常棒。
当然,在实际操作中经历了一些波折:最开始选型在 jsonschema 官方找实现,结果发现没有适合我们的,他们大多都是开源库中用了一点便声称支持,实际上耦合度比较高。
我们找到的第一个选型是 lua-rapidjson,它并不在 jsonschema 官方的推荐列表里,是腾讯开源的。但 rapidjson 有一个比较大的问题是编译条件高,它是一个 C/C++ 的实现,而我们做的是开源的项目,简单易用是我们追求的。此外 rapidjson 只支持了 draft4 里 95% 的内容,有些特性也不支持,比如经常用到的 default 。
于是我们根据一个开源的方案进行改造,实现了新的 iresty / jsonschema,主要增加了下面一些点:
这个库采用了编译器的思维方式。我们对其进行了测试:一个简单的对象里面有两个字段,分别是字符串和一个 int 类型,反复进行循环压力测试,跑一百万次,将跑完的时间做比较。iresty / jsonschema 的性能是 lua-rapidjson 的 5-10倍,是 gojsonschema(golang) 性能的 500-1000 倍。
路由是 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 目前的业务架构:左侧是管理员,右侧是用户请求。管理员把信息录入放到 etcd 里面缓存后,用户访问 APISIX 做路由,根据路由信息得到结果,匹配到路由交给具体的微服务、serverless 等。
如上图,APISIX 软件层面基本架构并没有采用传统的层层嵌套的方式,只有基础层和业务层,基础层完全脱离于 APISIX 内核,完全无业务绑定,大家可以在任何 OpenResty 项目中引用。
插件可以热插拔,不用重启服务。并且已经内置了常见的限流限速、身份认证、请求改写、URI 重定向、opentracing、serverless 等插件,开箱即用。APISIX 对插件的支持和友商不太一样,具体表现在以下几点:
总结 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 微服务网关极致性能架构解析
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~