Apache APISIX 助力有赞云原生 PaaS 平台,实现全面微服务治理

戴诺璟

更新时间 9/15/2021

作者戴诺璟,来自有赞技术中台,运维平台开发工程师

有赞是一家主要从事零售科技 SaaS 服务的企业,帮助商家进行网上开店、社交营销、提高留存复购,拓展全渠道新零售业务。在今年,有赞技术中台开始设计实现新的云原生 PaaS 平台,希望通过一套通用模型来进行各种应用的发布管理和微服务相关治理。而 Apache APISIX 在其中起到了非常关键的作用。

为什么需要流量网关

有赞 OPS 平台

有赞 OPS 平台是前期基于 FLASK 的单体应用,主要以支持业务为主。后来逐渐上线了很多业务,部署了很多业务端代码,进入容器化阶段。网关在当时只是内部 FLASK 应用的一部分功能,且没有一个明确的网关概念,仅作为业务应用的流量转发功能使用。下图展示的就是当时的网关 1.0 业务结构。

1.0 业务结构

由于前期整个体系主要着重于业务方向,所以没有产生太多的动力去进行改造。从 2018 年开始,通过内部交流我们发现,如果没有一个很好的网关层治理,对后续产品功能的实现和业务接入度上会带来越来越明显的瓶颈。

没有网关层治理出现的问题

问题一:性能方面

  1. 每次新增后端服务,都需要进行编码变更
  2. 流量转发的代码用 Python 简单实现,未按“网关”要求进行设计
  3. Flask 框架的性能限制,单机 QPS 范围局限在 120-150
  4. 重复造轮子:不同的业务需求都生产一套对应入口
  5. 管理麻烦,运维复杂

基于这个问题,我们的行动方向是:专业的工作交给专业的系统去做。

问题二:内部业务方面

内部业务问题

  1. 需要管理的内部服务数量非常多(上百)
  2. 部分服务未对接 CAS 实现鉴权
  3. 新的服务对接 CAS 存在对接成本,重复开发耗时耗力
  4. 所有服务直接配置在接入层,没有内部服务的规范及最佳实践

带着以上这两方面问题,我们就开始对网关类产品进行了相关的调研。

为什么选择了 Apache APISIX

最早我们也调研了很多的网关系统,比如 Apache APISIX、Kong、traefik 和 MOSN,还有我们公司内部的两个相关项目 YZ7 和 Tether。

网关系统预选

考虑到产品成熟度和可拓展性,最终我们在 Kong 和 Apache APISIX 中进行对比选择。

多维度对比

从上图对比中可以发现,两者在很多方面基本不相上下,所以存储端成为我们重点考虑的一点。因为 etcd 在我们公司内部的运维体系上已经比较成熟,所以 Apache APISIX 相较 Kong 则略胜一筹。

同时考虑到在开源项目层面,Apache APISIX 的国内交流与跟进处理速度上都非常优秀,项目的插件体系比较丰富全面,对各个阶段的使用类型都比较契合。

所以在 2020 年调研之后,最终选择了 Apache APISIX 作为有赞即将推出云原生 PaaS 平台的流量网关。

使用 Apache APISIX 后的产品新貌

当我们开始接入 Apache APISIX 后,前文提到的两方面问题逐一得到了解决。

效果一:优化了架构性能

Apache APISIX 作为入口网关部署在内部服务区域边缘,前端的所有请求都会经过它。同时我们通过 Apache APISIX 的插件功能实现了与公司内部 CAS 单点登录系统的对接,之前负责流量转发的账号变为纯业务系统。同时在前端我们提供了一个负责鉴权的 SDK 与 Apache APISIX 鉴权接口进行对接,达成一套完整又自动化的流程体系。

优化架构

于是问题得到了解决:

  1. 每次增加新的后端服务,只需调用 Apache APISIX 接口,将新的服务配置写入
  2. 流量转发通过 Apache APISIX 完成,在网关该做的事情上,它完成得十分优秀
  3. 网关不再是架构中的性能瓶颈
  4. 对不同的业务需求,可以统一使用同一个网关来实现;业务细节有差异,可以通过插件实现

效果二:内部服务接入标准化

接入 Apache APISIX 后,公司新的内部服务接入时将自带鉴权功能,接入成本极低,业务方可以直接开始开发业务代码。同时在新服务接入时,按内部服务的规范进行相关路由配置,后端服务可以统一拿到鉴权后的用户身份,省时省力。

具体关于内部服务的一些调整细节这里简单介绍一下。

鉴权插件 OPS-JWT-Auth

鉴权插件是基于 JWT-Auth 协议去开发的,用户访问前端时,前端会先去调用 SDK,去前端本地获取可用的 JWT-Token。然后通过下图的路径获得用户有效信息,放在前端的某个存储里,完成登录鉴权。

登录鉴权

部署配置升级

在部署层面,我们从简单版本经历三次迭代后实现了目前的多集群配置部署。

  • 版本一:双机房 4 个独立节点,管理程序分别写入每个节点的 etcd
  • 版本二: 双机房 4 个独立节点,主机房三节点 etcd 集群
  • 版本三: 三机房 6 个独立节点,三机房 etcd 集群

目前我们还是计算与存储混合部署在一起,后续我们会去部署一个真正高可用的 etcd 集群,这样在管控平面 Apache APISIX 运行时就可以分离出来,以无状态模式部署。

新增鉴权插件 PAT-Auth

在今年我们又新增了 Person Access Token(PAT)的鉴权插件,这个功能类似于在 GitHub 上去调用 Open API 一样,会生成一个个人 Token,可以以个人身份去调用 Open API。

因为我们自己的运维平台也有一些这样的需求,比如本地的一些开发插件需要以个人身份去访问云平台上的接口时,这种情况下个人 Token 方式就比较方便,允许开发自己给自己授权。

目前 Apache APISIX 2.2 版本后已支持多个 Auth 插件使用,现在可以支持一个 Consumer 运行多个 Auth 插件的场景实现。

更多玩法待开发

升级运维自动化

在使用 Apache APISIX 的过程中,我们也经历了几次版本变动。但每次升级,都或多或少出现因为兼容性而导致改造开发,完成后进行线上变更,运维效率较低。所以后续我们会尝试在存储面部署三机房 etcd 集群的同时,将 Apache APISIX 运行面容器化实现自动发布。

traffic split 插件使用

traffic split 是 Apache APISIX 在最近几个版本中引入的插件,主要功能是进行流量分离。有了这个插件后,我们可以根据一些流量头上的特征,利用它去自动完成相关操作。

traffic split

如上图在路由配置上引入 traffic split 插件,如果当有 Region=Region1 的情况,便将其路由到 Upstream1。通过这样的规则配置,完成流量管控的操作。

东西向流量管理

我们的使用场景中更多是涉及到在内网多个服务之间去做服务,调用鉴权时可以依靠 Apache APISIX 做流量管理。服务 A、服务 B 都可以通过它去调用服务 C,中间还可以加入鉴权的插件,设定其调用对象范围、环境范围或者速率和熔断限流等,做出类似这样的流量管控。

流量管理

内部权限系统对接

之后我们也打算将公司的权限系统与 Apache APISIX 进行对接,鉴权通过后,判定用户是否有权限去访问后端的某个资源,权限的管理员只需在管控平面上做统一配置即可。

系统对接

这样带来的一个好处就是后端的所有服务不需要各自去实现权限管控,因为当下所有流量都是经过网关层处理。

Go Plugin 开发

目前 Apache APISIX 在计算语言层面已支持多计算语言,比如 Java、Go 以及 Python。刚好我们最近实现的云原生 PaaS 平台,也开始把技术栈从 Python 往 Go 上转移。

希望后续在使用 Apache APISIX 的过程中,可以用 Go 去更新一些我们已经实现了的插件,期待在后续的迭代中给有赞产品带来更多的好处。