当前云原生应用的开发模式在 FaaS 环境下存在挑战,本文提出一种开发模式构想:“单体式编程,编译时拆分,分布式执行”,旨在简化云应用开发,提升开发效率和应用性能。思路是通过编译器自动拆分单体应用代码,实现云基础设施上的分布式运行。(Solo 社区 投稿)

背景

云原生应用通常形象地解释为应用架构出生或生长在云基础设施上的应用程序。此类基于云基础设施构建的应用程序能够有效利用云提供的自动扩缩、高可靠性等特性,这对于个人开发者和中小型企业来说,不需要关心基础设施的复杂性,又能获得强大的支撑能力,显然是一件很香的事情。

现状

那么,现在是怎么开发云应用程序的?提到云原生应用,大家通常会想到容器、微服务,这两项技术也在 CNCF 对云原生的定义中被提到。一个典型的开发流程可能是:开发者开发微服务粒度的应用代码,封装成容器,最终托管到 PaaS 平台上。

但随着云的发展,函数计算(Function as a Service, FaaS)已经成为云的重要组成部分。相较于 PaaS,FaaS 与云的各项能力结合的更紧密,在扩缩容、冷启动等方面,FaaS 的性能也更加强悍,例如,AWS Lambda 的冷启动时延已经达到百毫秒级。

问题

那么,微服务、容器的开发模式是否仍适用于基于 FaaS 的云原生应用?分析来看:

  1. 函数承载的服务通常被称为 NanoService,比微服务的粒度更小,如果由开发者将一个应用程序的每个函数逐个打包、发布,即使云厂商提供了命令行工具,整个操作过程也会比较繁琐
  2. 将一个应用程序拆分成若干个函数进行开发,各个函数在代码关系上互不相干,函数间的调用必须通过 SDK 进行,这使得开发一个应用需要在不同函数间反复切换,在编程思维上极不连贯
  3. 对函数进行编排需要了解云基础设施提供的事件机制、编排工具等,有了更高的学习成本

整体来说,直接基于 FaaS 的开发模式体验较差,如何有效管理和协调这些函数成为了一个重要问题。显然,我们不希望开发一个应用程序是这种体验,那么,我们该如何开发云原生应用呢?在这里提出一个构想:单体式编程,编译时拆分,分布式执行

联想

看到这个构想,你可能会觉得这与并行编程框架 OpenMP 的思路比较相近,的确如此。OpenMP 利用编译器在代码并行区域添加多线程代码实现并行执行,而在这个构想中同样是利用编译器识别并提取可独立计算的代码区域,但具体的分布式执行则交由云基础设施负责。

大数据计算的 MapReduce、Spark 可能也有些相似,以及近来比较火热的 Ray,同为云计算领域,同样都是面向大规模分布式计算。这里,与以上各类框架显著不同的一个点是,底层运行时实现方式的不同。以上各类框架都是各自构建了一套底层运行时环境来支撑特定种类任务的分布式执行,而这里的构想则是希望基于云基础设施提供的 FaaS 作为统一的底层环境,来实现通用计算,支撑各类云原生应用。两种方式相较而言,前者针对特定负载可能有调度、性能优势,而后者能与云基础设施提供的各项能力结合的更紧密,同时也能让各种场景的负载有结合的可能。

在开发体验上,的确是相近的。

构想

为什么要“单体式编程”

因为我们在开发一个单体应用程序时体验是非常好的,我们的上下文都在一个工程项目中,变量间的依赖关系、函数间的调用关系能够在执行前由 Lint、Format 工具,IDE 插件等各类工具进行检查。

为什么能“编译时拆分”

没有任何编程约束的代码文件的确难以进行拆分,但是可以通过定义关键字、特殊类、特殊函数等方式来指导编译器对代码进行拆分。

例如下面这份代码,可以将 Function 看作使特殊类,而它在构造函数中传递的函数定义就可以被分析提取成一个独立的计算模块。当然,在实际实现时肯定需要考虑更多的情况。

class Function  {
constructor(fn: (...args: any[]) => any) { /* ... */ }
} const fn = new Function((a: number, b: number ) => { return a + b; }); async main() {
const c = await fn.invoke(1, 1);
console.log("1 + 1 = ", c);
}
main();

特别的是,在拆分出一个个计算模块后,整个代码文件相应去除各个计算模块的代码,剩下的部分也应该成为一个计算模块。而这个计算模块就是整个应用程序的入口,类似单体应用中的 main 函数,而这个 main 函数就可以完成整个应用程序的逻辑编排。

这样,我们就获得了单体式编程的开发体验,并通过编译时拆分的方式获得了基于云的分布式执行的能力。这种开发模式的产物是直接长在云基础设施上的,属于云原生应用。

示例

来看一个基于这种构想的示例程序。这个程序是利用蒙特卡洛计算 Pi,整个代码逻辑很简单:创建 10 个 Worker,每个 Worker 各自执行 100 万次采样,最终汇总采样结果。

const calculatePi = new Function((iterations: number): number => {
let insideCircle = 0; for (let i = 0; i < iterations; i++) {
const x = Math.random();
const y = Math.random();
if (x * x + y * y <= 1) {
insideCircle++;
}
} const piEstimate = (insideCircle / iterations) * 4;
return piEstimate;
}); async main() {
const workerCount = 10;
const iterationsPerWorker = 1000000; let piPromises: Promise<number>[] = [];
for (let i = 0; i < workerCount; i++) {
piPromises.push(calculatePi.invoke(iterationsPerWorker));
} const piResults = await Promise.all(piPromises); const piSum = piResults.reduce((sum, current) => sum + current, 0);
const pi = piSum / numWorkers;
console.log(`Estimated value of π: ${pi}`);
} main();

这份代码执行起来的预期效果应该像上面这张图展示的:

  1. 在编译阶段,拆分出两个计算模块,一个对应 calculatePi,另一个对应整体代码去除 calculatePi 后的剩余代码(main 代码)。
  2. 然后将两个计算模块部署成两个 FaaS 资源实例。
  3. 部署完成后,调用执行 main 代码对应的 FaaS 实例,从日志中获取输出结果。

更复杂的示例可以从这里了解:

2024 年 Pluto 也将基于这个构想继续进行尝试,在具体实现时,会利用静态分析、IaC 等技术来支撑,感兴趣或有适用场景的朋友也欢迎交流。如果觉得想法不错,可以给项目点个 Star,谢谢。

GitHub 仓库: https://github.com/pluto-lang/pluto

订阅

这个专栏会同步更新在 Solo 社区、公众号、知乎、社群。

微信搜索"Solo 独立开发者社区"或者扫描二维码,即可手机订阅。

Solo开发者社区-重新思考云原生应用的开发模式的更多相关文章

  1. 解锁云原生 AI 技能 - 开发你的机器学习工作流

    按照上篇文章<解锁云原生 AI 技能 | 在 Kubernetes 上构建机器学习系统>搭建了一套 Kubeflow Pipelines 之后,我们一起小试牛刀,用一个真实的案例,学习如何 ...

  2. CNCF 旗下首个为中国开发者量身打造的云原生课程,《CNCF x Alibaba 云原生技术公开课》即将上线

    伴随着以 Kubernetes 为代表的云原生技术体系的日益成熟以及 CNCF 生态的逐渐壮大,“云原生”已然成为了未来云计算时代里一个当仁不让的关键词.但是,到底什么是“云原生”?云原生与 CNCF ...

  3. Canonical 开源 MicroK8 | 云原生生态周报 Vol. 25

    业界要闻 1.Canonical 开源 MicroK8 面向工作站和边缘/物联网的零运维 Kubernetes!MicroK8 是 Canonical 提供的一款功能强大的企业级 Kubernetes ...

  4. 云原生生态周报 Vol. 2

    摘要: Cloud Native Weekly China Vol. 2 业界要闻 Kubernetes External Secrets 近日,世界上最大的域名托管公司 Godaddy公司,正式宣布 ...

  5. 视频课程 | 云原生下的Serverless浅谈

    京东云开发者社区在3月底于北京举行了以"Cloud Native时代的应用之路与开源创新"为主题的技术沙龙,现场多位技术大咖与开发者们面对面就Cloud Native进行了深入交流 ...

  6. 牛年 dotnet云原生技术趋势

    首先祝大家:新年快乐,牛年大吉,牛年发发发! 2020年的春节,新冠疫情使得全球业务停滞不前,那时候,没有人知道会发生什么,因此会议被取消,合同被搁置,项目被推迟,一切似乎都停止了.但是我们却见证了I ...

  7. 专访 KubeVela 核心团队:如何简化云原生复杂环境下的应用交付和管理

    作者 | Infoq Tina 背景 12 月 9 日,在 2021 年 KubeCon 云原生技术峰会上,CNCF 开源项目 KubeVela 宣布推出了 1.2 版本. KubeVela 是一个简 ...

  8. 拥抱云原生 2.0 时代,Tapdata 入选阿里云首期云原生加速器!

      3月9日,阿里云首期云原生加速器官宣,Tapdata 突出重围,成功入选31 强,将与多家行业知名企业,携手阿里云共建云原生行业新生态,加速拥抱云原生新时代的无限潜能.   2021年,阿里云正式 ...

  9. Java云原生崛起微服务框架Quarkus入门实践

    @ 目录 概述 定义 GraalVM简介 为何使用 特性 官方性能 实战 入门示例 步骤 安装GraalVM 创建quarkus工程 Idea导入项目 Idea运行和调试 打包成普通的Jar 打包成依 ...

  10. 分布式云原生平台Kurator v0.2.0正式发布!一键构建分布式云原生平台

    摘要:北京时间2023年2月9日,Kurator 正式发布 v0.2.0 版本. 本文分享自华为云社区<分布式云原生平台Kurator v0.2.0正式发布!一键构建分布式云原生平台>,作 ...

随机推荐

  1. ETSI GS MEC 013,UE 位置 API

    目录 文章目录 目录 版本 功能理解 Relation with OMA APIs Relation with OMA API for Zonal Presence Relation with OMA ...

  2. 国产linux系统(银河麒麟,统信uos)使用 PageOffice 国产版在线动态填充 word 文件

    PageOffice 国产版 :支持信创系统,支持银河麒麟V10和统信UOS,支持X86(intel.兆芯.海光等).ARM(飞腾.鲲鹏.麒麟等)芯片架构. 在实际的Word文档开发中,经常需要自动填 ...

  3. 西门子PLC设备如何接入AIRIOT物联网低代码平台 ?

    西门子PLC设备广泛应用于工业控制领域,高性能和稳定是它最大的优势.下面我们要把西门子300 1200 1500 PLC设备连接到AIRIOT物联网低代码平台,具体操作如下所示: 西门子驱动配置(配套 ...

  4. python的requests模块详解

    原文链接:https://www.cnblogs.com/lanyinhao/p/9634742.html 1.模块说明 requests是使用Apache2 licensed 许可证的HTTP库. ...

  5. C#利用win32API创建窗体

    效果图 代码实现 1 using System; 2 using System.Runtime.InteropServices; 3 //using System.Windows.Forms; 4 5 ...

  6. PHP常用排序算法02——快速、归并

    接着上篇,我们继续来学习下工程中最常用的排序算法,适合大规模数据排序的算法,快速排序(quickSort)和归并排序(mergeSort). PS:对排序等算法还不太了解的同学,可以去看下这个链接哦, ...

  7. 如何在多个 Git 平台玩转一个仓库

    版本控制在软件开发中至关重要,而 Git 是广泛使用的代码管理工具.有时,我们可能需要在多个平台 (如 GitHub.GitLab 和 Gitee) 上同步同一 Git 仓库,以便备份.协作等. 本文 ...

  8. sql数据的查询

        数据的查询操作             子查询 联合查询 多表查收等等             基本查询 模糊查询 分组查询 子查询             基本查询语句 查询表结构中所有字段 ...

  9. Mysql联合索引生效、失效条件

    引言 联合索引又叫复合索引.两个或更多个列上的索引被称作复合索引. 对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key inde ...

  10. 给你的博客加上个Live2D看板娘吧

    Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 给你的博客加上个Live2D看板娘吧 日期:2017-12 ...