基于 Apache APISIX,爱奇艺 API 网关的更新与落地实践
本文整理自爱奇艺高级研发师何聪在 Apache APISIX Meetup - 上海站的演讲,通过阅读本文,您可以了解到基于 Apache APISIX 网关,爱奇艺技术团队是如何进行公司架构的更新与融合,打造出全新的网关服务。欢迎感兴趣的同学访问 bilibili 爱奇艺基于 Apache APISIX 的 API 网关落地实践,观看视频。
作者何聪,高级研发师,IIG 基础架构部-计算云,主要负责爱奇艺网关开发和运维工作
背景描述
爱奇艺在之前有开发了一款网关——Skywalker,它是基于 Kong 做的二次开发,目前流量使用也是比较大的,网关存量业务日常峰值为百万级别 QPS,API 路由数量上万。但这款产品的不足随着使用也开始逐步体现。
性能差强人意,因为业务量大,每天收到很多 CPU IDLE 过低的告警
系统架构的组件依赖多
运维开发成本较高
今年在交接到此项目后,我们根据上述问题和困境,开始对相关网关类产品做了一些调研,然后发现了 Apache APISIX。
Apache APISIX 优势
在选择 Apache APISIX 之前,爱奇艺平台已经在使用 Kong 了,但是后来 Kong 被放弃了。
为什么放弃 Kong?
Kong 使用 PostgreSQL 来存储它的信息,这显然不是一个好方式。 同时在调研过程中我们查看了 Apache APISIX 与 Kong 的性能的对比,在性能优化方面 Apache APISIX 比 Kong 提升了 10 倍,这个指标是非常让人惊喜的。 同时我们也比较了一些主要的网关产品,Apache APISIX 的响应延迟比其它网关低 50% 以上,在 CPU 达到 70% 以上时 Apache APISIX 仍能稳定运转。
我们也发现 Apache APISIX 其实和 Kong 一样,都是基于 OpenResty 技术层面做的开发,所以在技术层面的迁移成本就比较低。而且 Apache APISIX 具有良好的环境适应性,能够被轻易地部署在包括云计算平台在内的各种环境上。
同时也看到 Apache APISIX 整个开源项目的活跃度非常高,对问题的处理非常迅速,并且项目的云原生架构也符合我司后续规划,所以我们选择了 Apache APISIX。
基于 Apache APISIX 下的爱奇艺网关架构
爱奇艺网关的总体架构如下图所示,包含域名、网关到服务实例和监控告警。DPVS 是公司内部基于 LVS 做的一个开源项目,Hubble 监控告警也是基于开源项目做的深度二次开发,Consul 这块做了些性能和高可用性方面的优化。
应用场景一:微服务网关
关于网关这块,简单从控制面和数据面介绍一下。
数据面主要面向前端用户,从 LB 到网关整个架构都是多地多链路灾备部署,以用户就近接入原则进行布点。
从控制面的角度来说,因为多集群构成,会存在一个微服务平台,去做集群管理和服务管理。微服务平台可以让用户体验服务暴露的一站式服务,立即使用,无需提交工单。控制面后端会有 Gateway Controller 和 Service Controller,前者主要控制所有的 API 的创建、插件等相关配置,后者则是控制服务注册注销和健康检查。
应用场景二:基础功能
目前阶段,基于 Apache APISIX 调整后的 API 架构实现了一些基础功能,如限流、认证、报警、监控等。
首先是 HTTPS 部分,爱奇艺方面出于对安全性的考虑,证书和密钥是不会存放在网关机器上,会放在一个专门的远程服务器上。之前使用 Kong 时我们没有在这方面做相关支持,采用前置 Nginx 做 HTTPS Offload,此次迁移到 Apache APISIX 后,我们在 Apache APISIX 上实现了该功能,从链路上来说就少了一层转发。
在限流功能上,除了基础的限流、还添加了精准限流以及针对用户粒度的限流。认证功能上,除了基本的 API Key 等认证,针对专门业务也提供了相关的 Passport 认证。对于黑产的过滤,则接入了公司的 WAF 安全云。
监控功能的实现目前是使用了 Apache APISIX 自带插件——Prometheus,指标数据会直接对接公司的监控系统。日志和调用链分析也通过 Apache APISIX 得到了相关功能支持。
应用场景三:服务发现
关于前面提到的服务发现,主要是通过服务中心把服务注册到 Consul 集群,然后通过 DNS 服务发现的方式去做动态更新,其中 QAE 是我们公司内部的一个微服务平台。简单举例说明一下更新后端应用实例时的大体流程。
实例变更时,首先会从 Consul 中注销对应节点,并通过 API 网关 Controller 向网关发送更新 DNS 缓存的请求。缓存更新成功后,Controller 再反馈 QAE 平台可以停止相关后端应用节点,避免业务流量再转发到已下线节点。
应用场景四:定向路由
网关是多地部署的,事先搭建好一整套多地互备链路,同时建议用户后端服务也是多地就近部署。随后用户在 Skywalker 网关平台上创建一个 API 服务,Controller 会在全 DC 网关集群上都部署好 API 路由,同时业务域名默认 CNAME 到统一的网关域名上。
直接为业务提供多地就近接入、故障灾备切换能力,同时也支持用户自定义解析路由。针对用户自身的故障切流、蓝绿部署、灰度发布等需求,用户可以通过采用 uuid 域名来自定义解析路由配置,同时也支持后端服务发现的自定义调度。
应用场景五:多地多级容灾
前边我们也提到过,针对业务量大、集群多,还有客户端受众广的情况,在业务层面我们会有业务就近接入和灾备的需求。
针对灾备,除了要多地多链路互备,还要考虑多级多节点问题,故障节点越向客户端靠近,受影响的业务和流量越大。
如果是最远的后端服务节点故障,依靠网关和服务中心的健康检查机制,可以实现故障单节点的熔断或者故障 DC 的切换,影响范围限制在指定业务上,用户无感知。
如果是网关级别故障,需要依靠 L4 DPVS 的健康检查机制,熔断故障网关节点,影响范围小,用户无感知。
如果故障点并非上述述熔断措施所能修复,就需要依靠域名粒度的外网多点可用性拨测,实现域名解析级别的故障自动切换,这种方式故障修复速度相对较慢,影响业务多,用户可感知。
迁移过程中遇到的问题
在我们从 Kong 到 Apache APISIX 的迁移实践过程中,我们解决、优化了一些架构存在的已知问题,但同时也遇到了一些新的问题。
成果一:解决了前端不支持 SNI 的兼容问题
现在大部分前端都是支持 SNI 的,但也会碰到有一些前端在 SSL 过程中无法传递 hostname。目前我们针对这种情况做了一个兼容,采取端口匹配的方式进行相关证书获取。
成果二:优化了大量 API 路由匹配问题
前边也说过,目前我们线上直接运行的 API 业务数量就有 9000 多个,后续可能还会增加。针对这一问题我们进行了相关性能上的优化,根据 API 来决定优先匹配域名还是路径。
成果三:解决了 ETCD 接口限制问题
在接入 Apache APISIX 后,ETCD 接口的限制问题也已经解决,目前已经解除了 4M 的限制。
成果四:优化了 ETCD 连接数量的性能问题
目前是 Apache APISIX 的每个 worker 都会跟 ETCD 连接,每一个监听目录都会去建一个连接。比如一台物理机是 80 core,监听目录有 10 个,单台网关服务器就有 800 个连接。一个网关集群 10 台的话,8000 个连接对 ETCD 压力蛮大的。我们做的优化是只拿一个 worker 去监听有限的必要目录,和其余 worker 之间共享信息。
除了上述问题,还有一些问题也正在努力优化中。
大量 API 的问题,即使 APISIX 能够支持,我们也要考虑其他依赖组件的瓶颈。比如上述的 ETCD、Prometheus 监控和日志服务。所以后续我们可能会采取大集群共享和小集群独立这两种方式来混合部署业务,比如一些重要业务我们会以小集群方式进行部署。
关于 Prometheus 监控指标,后续我们也会进行相应的缩减和优化,对 DNS 服务发现这块做更多的优化。
对 Apache APISIX 的期望
我们希望 Apache APISIX 能在后续的开发更新中,除了支持更多的功能,也可以一直保持性能的高效和稳定。
关于 Apache APISIX
Apache APISIX 是一个动态、实时、高性能的开源 API 网关,提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。Apache APISIX 可以帮忙企业快速、安全的处理 API 和微服务流量,包括网关、Kubernetes Ingress 和服务网格等。
全球已有数百家企业使用 Apache APISIX 处理关键业务流量,涵盖金融、互联网、制造、零售、运营商等等,比如美国航空航天局(NASA)、欧盟的数字工厂、中国航信、中国移动、腾讯、华为、微博、网易、贝壳找房、360、泰康、奈雪的茶等。
200 余位贡献者,一同缔造了 Apache APISIX 这个世界上最活跃的开源网关项目。聪明的开发者们!快来加入这个活跃而多样化的社区,一起来给这个世界带来更多美好的东西吧!
Apache APISIX GitHub:https://github.com/apache/apisix
Apache APISIX 官网:https://apisix.apache.org/
Apache APISIX 文档:https://apisix.apache.org/zh/docs/apisix/getting-started
评论