DataVisor 是一家专注于风控领域的公司,致力于防范反击战、反作弊等方面的工作。在 DataVisor 的产品开发中,我们不仅在生产环境中应用了 APISIX,还对 APISIX 进行了多个维度的二次开发,如插件方面的二次开发,并最终获得了良好的生产效果。下面将为大家简单分享 DataVisor 应用 APISIX 的经验。
业务痛点
性能压力大: DataVisor 所在的风控行业对性能指标极为敏感,要求风控计算时间在极短的时间内完成。未能在规定时间内完成风控计算可能导致丧失风险控制结果。在这个高度竞争和风险敏感的环境中,确保风控计算的及时性和有效性成为行业内的首要任务。
难以平衡安全与用户体验: 风控任务旨在拦截用户的危险操作,但又要确保不影响用户的正常操作。这要求 DataVisor 的系统能在保障用户使用安全的同时,能够降低对用户体验的不利影响。
网关工具难以满足要求:大部分市面上的 API 网关工具容易出现延迟高或毛刺问题,这种低性能可能对 DataVisor 整个系统的稳定性和可用性产生负面影响,特别是在需要高效处理业务流量的情况下。因此,选择一个性能稳定、延迟低的 API 网关工具对于确保系统的顺畅运行至关重要。
在生产环境中应用 APISIX
DataVisor 在产品领域中采用了一种综合的网关和认证解决方案。在我们的产品体系中,不仅仅使用了 APISIX,同时还整合了 AWS API Gateway、ALB 和 Imperva 等其他产品,以及 Application Load Balancer (ALB),并在加入了一个 OAuth 认证机制。这些组件都有一些网关功能,它们共同协作,实现了我们系统中的流量接入功能。
为何选择 APISIX
在选择适用于我们生产环境的解决方案时,我们进行了多方面的比较,最终决定采用 APISIX。
低成本:相较于由云厂商提供的简单应用网关(例如 ALB),APISIX 为我们节省了大量成本。
高性能、低延迟:APISIX 突显出的卓越性能是其一大亮点。与其他 API Gateway 工具相比,APISIX 不仅不会出现较高的延迟,而且不容易产生 P99 或 P9999 毛刺。并且 APISIX 能够有效应对并刷新这些性能上的问题。
关注行业特性:在风控领域,业务系统规定风控计算时间仅为 50 毫秒。在这短暂的时间内,如果无法完成风控计算,将直接放弃风控结果。风控的任务是拦截用户的危险操作,但不能影响用户的正常操作。
如何使用 APISIX
目前,APISIX 在我们的生产环境中的应用越来越广泛。
由于 DataVisor 本身没有直接的业务,其产品主要销售给各种各样的厂家,由厂家调用我们的服务;因此,APISIX 实际上是我们部署在公网的流量入口,这在实际应用中可能相对较为少见。通常情况下,APISIX 可能会被部署在内网或公网再下一层的网络上,而我们选择将其直接部署在公网,由 APISIX 帮助我们承接来自不同业务上的流量。
为了更具体地说明我们在生产环境中对 APISIX 的应用,以下是一个典型的应用场景示例:
客户 A 首先通过红色线路访问我们的系统,以获取授权访问的 token,然后访问我们内部的授权服务器;或通过 APISIX 接入其他的授权服务器,例如海外常用的 Okta。我们主要使用 Okta 对流量进行鉴权,首先将所有流量转发到 Okta,再由 Okta 进行第一步鉴权。接下来,客户获取到不同的 token 后,我们通过 APISIX 的路由选择,将这些经过授权服务器鉴权的流量录入到不同的 Kubernetes 集群中。
目前,我们已经部署了一个双活 Kubernetes 集群,其中流量被路由到 A 集群或者 B 集群。通常情况下,我们会将流量录入到一个 Kubernetes 集群,另一个集群用于储备,只有在进行大范围升级或者集群升级时才会进行分流。
在网关的使用方面,我们采用了相对简单和常规的部署模式。有一个有趣的观察是,我们可以将 APISIX 部署在我们的 Kubernetes 集群之外。这是因为 APISIX 具有非常高的性能,基本上不会消耗太多 CPU。通过在集群外使用小型机型来部署 APISIX,我们能轻松处理大量的网络流量。
在生产环境中,我们部署了三个 APISIX 节点,每个节点可能只配置了两核,并使用 2G 或 4G 的小型机器来承接流量。APISIX 的性能足够媲美 NGINX 与 OpenResty,甚至超出了我们的预期。
对 APISIX 的二次开发
扩展特权进程
在 NGINX 中并不存在特权进程这个概念,但在 OpenResty 中有所体现,它与 worker 进程处于同一级别。这个进程相对来说较为特殊,因为它并不具备接入网络流量的能力,即不监听任何端口,但却可以执行一系列的计算和采集任务。因此,我们对这个特权进程进行了一定的扩展。
上面的示意图简明地呈现了 APISIX 与我们后端服务之间的关系。我们主要用 APISIX 来接收和分发流量。
在网关层,APISIX 在流量进入之前进行预处理,而我们独特的地方在于在 APISIX 这一层引入了一个小进程。这个进程类似于 Sidecar,它在与 APISIX 进程同时运行的同时,负责执行自身的任务。随后,它将采集到的数据发送给 APISIX,再由 APISIX 传递回到自身的上层,去做一些业务逻辑。这种用法相对较为罕见,通常业务场景较少涉及,但在风控领域可能会遇到这种情况。
而特权进程又该如何实现呢?我们的模型通常采用 master-worker 结构,其中 worker 进程负责处理业务流量,而 master 进程则会 fork 出一个特殊的特权进程。在我们的开发中,特权进程只能有一个。因此,我们采取了一种特殊的策略,即在特权进程中 fork 了另一个进程,由这个进程执行其他任务,以避免干扰特权进程繁忙的工作。
在数据采集方面,特权进程和 worker 进程通过 shared-dict 进行通信。shared-dict 的性能是非常高的,对于大多数场景都能够满足需求。
扩展 ssl-certificate-phase
扩展 ssl-certificate-phase 涉及 APISIX 基于 NGINX + Lua 框架的引入。起初,APISIX 并不支持在 TLS 中的握手阶段进行大量的脚本注入。随后,当 OpenResty 社区支持了在 ssl-client-hello 阶段注入代码的功能时,我们注意到 APISIX 社区尚未跟进。因此,我们只能采取手动修改 APISIX 的方式。
我们参考了之前的代码结构,在 APISIX 的流程中插入了我们自己的代码,使其在 client-hello 阶段运行我们的一些代码。在 client-hello 阶段,可以实现的功能很多,但在 Lua 层面相对较为有限。在许多情况下,我们需要借助 NGINX 进行 module 开发,或者为 NGINX 创建一个小的动态库来完成这些任务。
目前,OpenResty 和 Lua 在加载动态库这方面表现得非常出色。有一个名为 ffi 的功能,可以轻松加载动态库。这只需在动态库中编辑好所需的外部接口,然后通过几个简单的 ffi 命令即可将动态库中的函数导出到 Lua 来使用,它将提供出乎意料的性能提升。使用 ffi + Lua 这种模式编写出来的代码性能大致相当于纯 C 语言编写的 70%。换句话说,假如纯 C 语言一秒可以执行 100 次,它每秒就能执行 70 次,基本可以认为是性能第一。而且,随着运行时间的增加,呈现出来的效果会越来越好。
插件开发
由于我们对 APISIX 进行了二次开发,打包出来的产品中,许多功能仍然硬编码在整个项目中,难以进行动态调整。因此,我们决定打包一些插件,将它们整合到 APISIX 项目中,然后用 Dashboard 再进行修改。
使用 APISIX 进行插件开发非常便利,可以轻松地开发高性能插件。目前,APISIX 不仅支持 Lua 插件开发,还支持多种编程语言,包括 Java、Go,还有 Python,帮助用户实现各种各样的功能。
APISIX 带来的生产效果
我们在生产环境中使用 APISIX 已经超过一年时间,对其稳定性和性能的表现深感满意,使得我们对其应用的信心倍增。部署 APISIX 后,我们整体提升了系统性能,取得了优异的生产效果。
延迟最小化:APISIX 的优异表现体现在显著降低的延迟水平。与其他解决方案相比,我们注意到用户请求的处理时间更短,这对于提供更为流畅的用户体验至关重要。
吞吐量提升:APISIX 的部署带来了显著的吞吐量提升,使得系统能够更高效地处理并发请求。相较于其他 API 网关产品,我们成功实现了更大规模的请求处理,确保了系统在高负载下的稳定性和可靠性。这为应对激增的用户流量提供了可靠的基础。
对 APISIX 的展望
APISIX 是一个极富活力的社区,会持续进行每月的版本迭代。在这一领域,我对 APISIX 的未来发展有两点功能改进的展望。
通过 Dashboard 实现动态新增或更新
当前情况下,一旦插件开发完成,我们就无法实现热更新。插件无法直接通过 post 方式传递到 APISIX server,依然需要重新打包 APISIX server 并重新启动,尤其在 Dashboard 方面。因此,我们期望 APISIX 能够实现热更新的功能,使得插件的动态新增与更新能够更为便捷地通过 Dashboard 实现。
支持使用 run_worker_thread 计算 CPU 敏感型
NGINX 中引入了一项名为线程的特殊机制。这些线程的主要任务是处理一些与网络无关的任务,例如高 CPU 利用率的活动(数据的加解密和压缩)。虽然它与网络 I/O 无关,但高 CPU 使用率可能导致该进程中其他网络请求受到一定的阻塞。
因此,我希望 APISIX 能引入类似的功能。如果能使用 APISIX 处理一些复杂功能计算,比如数据的加解密和转存等,将是一项有益的改进。
总结
DataVisor 特别注重了风控领域的性能需求,并通过采用二次开发的独特策略来解决实际问题。APISIX 在 DataVisor 的应用经验不仅在技术实践中取得了成功,而且为我们公司在风控行业中的稳健运作提供了坚实的基础。通过这些经验的分享,我们希望能够为行业内其他相关企业提供有益的参考,共同推动风控技术的不断创新与进步。
作者介绍:
赵晓彪,DataVisor 高级架构师,Apache Kvrocks Committer,OpenResty 及 Apache APISIX Contributor。
评论