手把手搞定渐进式 Node FaaS

编者按:本文为蚂蚁集团保险服务业务前端负责人齐穹在 SEE Conf 2022 的演讲内容。Needle 希望构建一种渐进式的 FaaS 解决方案,给 BFF 开发者们带来全新的研发体验。本文将重点分享在金融级业务实践中积累的关键技术思路,如 Node 容器隔离和调度、高可用保障等。

演讲视频链接:player.bilibili.com/player.html…

1.Why:蚂蚁 BFF 挑战和思考

1.1. BFF 研发的挑战和瓶颈

在 BFF 研发中,我们一直会遇到很多问题,比如大 BFF 应用交付时因为迭代分支问题被个别需求“堵车”,再比如大应用需要考虑大量模块的兼容适配,协作成本极高,质量和发布风险也很高。

为了解决这类问题,我们过往一直在代码组织(框架、规范)、工作流(代码管理、协作工具)方面做了很多非常棒的努力,包括成熟的 chair 企业级框架及其配套设施、 gitflow 代码管理和 scrum 项目协作,尽力让各类问题得以缓解。但应用级别的交付粒度,必然注定了业务代码的耦合和人员的非必要协作成本,协同框架、流程虽然缓解了问题,但也加剧了复杂度,导致BFF研发门槛更高、研发部署耗时也更大。

BFF 一般都是业务粘合接口,接口在代码形态上天然就是函数,如果我们能迁移到函数级别的交付平台上,那在交付上就可以做到快写、快测、快发,代码组织也无需框架极大降低门槛,大部分协作问题也自然消失了。

但是,蚂蚁因为其金融属性和大流量高保场景,暂时安全可靠的 FaaS。其实很多友商也有类似问题,因为基建迁移成本和社区 FaaS 方案的成熟度问题等考虑,迟迟无法支持 FaaS 落地。这就像“智子锁死”一样,让BFF研发一直卡在了应用交付模式上无法更进一步。

1.2.渐进思路解决 FaaS 落地瓶颈

我们把 FaaS 的特性拆解下会发现,**一方面我们借助其函数粒度的快速开发、动态部署可以极大加速我们的交付效率,另一方面是借助他的弹性扩缩容能力实现 Serverless 免运维。**我们受限的弹性扩缩容的硬件资源调度能力,但我们却可以在应用层先做到函数动态部署,释放 FaaS 研发效能的巨大优势!

大致思路是我们在现有的应用框架上,利用框架的插件机制实现一套支持隔离、动态部署的容器方案,这样就解决了业务代码的动态部署运行的能力,又可以复用现有应用的硬件资源和弹性能力。

当然,这样的方案毕竟是无 FaaS 基座下的过度方案,为了上层应用后续能平稳持续运行,我们还需要考虑渐进支持迁移到标准的 FaaS 基建上。

2.How:Node FaaS 平台关键设计和思考

2.0.企业级平台的设计思考方法

从一个技术想法到企业级平台,一共有几步?我们认为是三步。

首先肯定是技术选型,技术里没有银弹,选择最合理的技术方案是关键。先回答基石技术(决定性技术)是什么?然后作为技术**“产品”**,要理清用户、业务、技术三者的诉求、权重,作为后续的选型标准和架构原则。最后就是对关键技术要素进行客观的对比分析,得到理性结果,而不是笼统的拍个脑袋,或是吵得面红耳赤。

其次,就是基于选型好的技术方案和路线,做好架构设计方案,落地整体可用的方案。一般我们会用产品化和架构设计两个视角去做架构设计,分别按时间维度梳理生命周期、按空间维度设计拓扑架构。

最后,我们要根据业务、技术和用户的特点,还有架构实现过程中遇到的明显问题,进行进一步的加固或优化,这就是精益求精的过程。在 Needle 这就体现为高可用方面的重点加固以及高性能和渐进迁移能力的深度优化甚至重构。

2.1.运行容器技术选型

技术选型中,如上文 1.2 所述,决定性技术是函数的运行容器。**运行容器的方案选择,**决定了需求支持的完整度、架构设计方案、整体方案的上下限。

接着是分析技术要求和优先级。在蚂蚁的 BFF 研发场景,金融业务是严肃型业务,对于错误、失败的容忍度非常低,因此高可用是绝对的首要要求;但 BFF 只做数据粘合,逻辑复杂度低,对计算、空间要求都相对低。用户方面,主要服务于蚂蚁的前端开发同学,一方面他们的开发任务非常重,亟需提效解决原有的开发部署成本;另一方面因为都是一方开发者,可信可控,只需要隔离和权限管理保证不互相影响,不用过度追求资源隔离。综上,我们需要保证可靠性优先和效率优先,性能和高级别隔离是可选的。

最后我们对可选方案和技术要素进行客观的直接对比如下:

从表格可见,vm 在数据隔离、启动性能、研发成本上,有比较大的优势,是当前最符合我们技术要求的选项。

数据隔离上,vm 是 node 原生支持的稳定特性,底层是用了 v8 引擎的 ScriptCompiler::CompileUnboundScript 来编译,上下文层面实现了隔离,但在语言的对象引用链上还是难免会有遗漏,可以满足正常业务隔离,无法解决恶意的攻击行为。

执行性能上,vm 相对较慢,原因是每次触发 vm.runInContext 时,都会重新调用 v8 的 JSFunctionBuilder::build,这里涉及到解释运行到编译优化部分,因为每次重新 build,用于触发编译优化的 feedback_vector 上的计数器始终不会增加,导致 TurboFan 编译不会触发,一直停留在解释器运行的模式。不过因为大部分 BFF 层接口都是 IO 密集而不是计算密集,因此这块的性能瓶颈不是主要问题。

2.2.架构设计思路

大型系统的架构设计,我们通常需要从多个维度考虑架构的构成、组织关系。Needle 作为一个偏服务端的技术产品,可以参考 PaaS 类技术平台的架构设计思路,从拓扑结构和生命周期两个角度组织关键能力。

从拓扑结构上看,Needle 需要支撑开发者的开发运维需求(管控平面)和产物的可靠运行(运行平面),因此我们架构分层为了运行时和管控时两个大模块。运行时通过网关作为对外服务的边界和入口,对内通过文件服务和管控时应用进行产物同步。为了保持最简设计达到高可用和低维护成本,我们尽量低耦合和少依赖,比如控制指令常用的消息通道,而是直接由文件变更自动触发和自解释(监控我们还是用了消息通道,但是属于旁路设计,不影响主链路使用)。

从一个技术产品的能力上看,我们可以根据资源生产的生命周期,或者用户使用路径来梳理,分为开发、质量、部署、运维四个阶段,分别提供对应的工具支撑和流程规范限制,来提升效率和确保质量。比如我们在开发时就使用了在线的文档式编辑器,对于少量代码的 BFF 接口可以直接远程开发调试并部署,同时文档式(类似数据和AI领域中大受欢迎的 Python Notebook )将注释文档化并支持图文,更利于维护。

2.3.高可用重点加固

安全生产一定是所有业务的生命线,在国民级金融平台上,就更是绝对的重中之重。为了能够更大范围支持好蚂蚁的数字金融业务,必须确保Needle平台能达到最高级别的高可用水准,这对我们项目组同学是非常大的考验。

不过,蚂蚁安全生产的方法论是比较成熟的,**“可灰度,可监控,可应急”**三板斧高标准执行好了,大概率是不会有问题的。作为研发平台要做的就是,提供高标准的三板斧工具。我们梳理出了架构中变更和运行链路的关键环节进行针对性加固:

  1. **可灰度:**所有变更是默认可灰度,可以选择流量和用户级别,这个不赘述;
  2. **可监控:**核心在于感知速度和归因能力,因此我们在 runtime 实例中重点加强了变更感知、心跳感知和异常感知,并且保证全链路可以在秒级反馈到管控平台,并做了持久化存储供全流程追溯归因;其次我们在管控平台提供了每个资源的健康度可视化面板和实时告警机器人;
  3. **可应急:**应急的基础操作是回滚和增量变更(不可回滚场景),除了实现能力以外,我们还重点关注文件同步服务和热更新速度,确保链路在分钟级别可以完成资源文件/配置可以完成替换,并完成热更新,对外提供正确的服务

2.4.阶段成果

在研发效能上,我们克服了应用开发的开发耦合、部署慢等关键问题,从天级别交付可以最快做到分钟级别交付;

整体应用规模上,我们投产半年预估节约人日 400+,平台应用到了 40+ 业务应用中,在蚂蚁财富、保险业务中大范围落地;

3.Next:下一步技术探索方向

Needle 半年多时间从原型到试点再到推广,一直围绕解决可用的问题进行建设,我们接下来将继续探索,从可用到好用的转变,将更多场景纳入到我们的重点支持场景中,比如中后台应用的数据透传接口开发复用、营销场景的云端一体敏捷开发、智能服务的消息卡片一体化敏捷开发。

同时,我们也希望在更硬核的技术上有一定突破,解决长期困扰我们的问题。我们选择了 3 个关键问题:

  1. **降低请求延迟:**当前受限于框架冷启动、执行性能不佳等问题,我们的单接口请求延迟还有不少可优化空间,更短的延迟意味着更快的用户操作响应
  2. **降低单 QPS 成本:**数字金融每天都在承载着海量的业务请求,如果我们能用更少的机器更低的负载完成服务,对我们机器成本优化乃至绿色低碳责任都是非常有益的
  3. 向后兼容支持完整 FaaS:现有的方案还是过渡性方案,先释放技术同学的研发效能,但最终我们还是会拥抱 FaaS 基座,才能有更好的资源调度和隔离能力,彻底解决资源最优化和安全问题,因此向后兼容设计和低成本迁移升级是一个重要命题,同时,对齐标准也为开源打开可能性

猜你喜欢

转载自juejin.im/post/7074851112855011359
今日推荐