双模 PaaS:满足 PaaS 层平滑演进需求
云原生其实源自于 PaaS,所以在应用云原生架构的时候,也先在 PaaS 层遇到了平滑演进的问题。如何让客户 既能保留以前的习惯,同时又能去尝试新的交付模式?在传统的模式中,大家习惯于交付代码包,习惯于基于虚拟机的运维;而云原生时代以容器镜像为交付载体,而运行实例则是镜像实例化容器。我们采用容器来模拟 VM 的运行模式,通过扩展 Deployment 来模拟 VM 的运维模式,同时也支持容器的模式。
无论是基于传统架构的 PaaS,还是基于 K8s 的 PaaS,实现主要操作都是一样的——都是建站、发布、重启、 扩容/缩容、下线等等。实现两套无疑非常浪费资源,也增加了维护成本,对于用户来说干的事情是一样的。所 以,我们用 K8s 实现了所有公共部分——统一元数据、统一运维操作、统一资源抽象。在产品层和运维方式上,我们提供两种界面;同时,在交付的方式上,不仅支持传统的应用模式、技术栈模式,也支持镜像模式,当然,在应用之外我们还可以去支持函数。
SOFA 双模微服务平台
再往上走就是双模的微服务,它同样面临老系统和新系统的问题。我们是通过 Mesh 的方式来统一解决这个问题的。新系统,即云原生架构下,Mesh 是 Pod 里的 Sidecar,但老系统往往没有跑在 K8s 上,就自然不支持 Pod 和 Sidecar 的运维模式,所以我们就得用 Agent 的模式来管理 Mesh 进程,使得 Mesh 能够帮助老架构下的应用完成服务化改造,并支持新架构和老架构下服务的统一管理。
数据面要双模,控制面也支持双模。传统基于 SDK 的微服务会往注册中心进行服务注册,但 Mesh 通常情况下是基于控制面进行服务发现及路由的,于是我们将控制面和传统的注册中心打通,并由后者来做真正的服务注册与发现,以实现全局服务的可见和路由。了解过蚂蚁服务注册体系的人知道,我们是如何在超大规模和多机房环境下实现高可用设计的,而这些能力很难短期在开源社区的控制面实现,我们正逐步将这个能力沉淀到新架构上。所以,这种控制面的双模也非常适合服务化架构在这种混合模式下,平稳过渡到云原生架构。
双模 Serverless 平台
最近 Serverless 非常火热,它的应用场景虽然非常丰富,但背后对性能有很高要求——每个应用的启动速度需要非常快,否则可能无法在生产环境使用。 蚂蚁内部的 Node 系统大量采用 Serverless 架构,并对启动速度进行了优化,目前平均启动速度在 4 秒左右,而且正在往 1 秒内的目标进行优化。但是 Java 应用却因为启动速度问题(普通 Java 应用启动时间大约在 30 秒到 1 分钟之内),很难享受到 Serverless 架构红利。我们采用了 JVM 的 SVM 技术对应用进行静态编译,将一个正常启动时间在 60 秒左右的应用优化到启动只要 4 秒左右,当然这需要牺牲掉反射等一些动态性;同时为了尽量不改应用,我们改了很多中间件的 SDK,以减少这方面适配对应用带来的影响。当这种方式能完美地支持 1 秒以内的启动速度,整个 Java 技术生态就可以平滑地迁移过来,应用场景也会更加扩大。
同时,我们利用应用容器的类隔离性来支持多个模块或者同一个模块的不同版本在一个 Java 运行时里运行,互不打扰,并且可以模拟 Serverless 下的快速冷启动和快速扩缩容。我们将这种具备隔离能力、支持模块快速装载和卸载的 Java 运行时称之为 SOFA Serverless Container,将最小的运行时模块称之为 SOFA Function,这些小代码片段通过一套 Serverless API 进行编程。在过渡阶段,我们将 SOFA Serverless Container 部署成一个集群,并在此之上混合调度多个 SOFA Function,此时 SOFA Serveress Container 和 SOFA Function 的比例是 N:1。到后期,如果能解决 Java 应用的启动速度问题,而这些 SOFA Function 就可以平滑地过渡到 Pod 部暑模式,一个 SOFA Function 只会运行在一个 SOFA Serverless Container 上。
最后,金融级的混合云要满足技术平滑演进的需求,还要具备可演进、可迭代能力。所以我们在 PaaS、微服务、Serverless 等层面都提供了双模的“混合”能力。