云计算的概念最先由戴尔公司于1996年提出。2006年,亚马逊公司率先推出了弹性计算云(Elastic Compute Cloud,EC2)服务,随后越来越多的企业开始逐步接受云计算这一概念,并将应用逐步迁移到云端,享受这一新型计算方式带来的技术红利。2009年,阿里巴巴率先开始研制具有完全自主知识产权的云产品——飞天操作系统,由此揭开了中国云计算的序幕。
纵观软件架构的演化历史可以发现,任何新的底层软硬件技术出现后,上层应用软件都需要很长一段时间才能够真正“认识”到新的软硬件给上层应用软件带来的价值,并开发新的软件架构,以便充分利用新软硬件的能力。最典型的例子就是x86 CPU和服务器在面世二十多年后,以CORBA、EJB、RPC、瘦客户端等为主的多层架构才逐步成为应用开发的主流架构。类似的还有容器技术,它最早是由FreeBSD于2000年在Jails中提出的,但真正得到大规模应用是在2013年Docker兴起之后,而应用层的代表则是几年之后基于容器的微服务架构。
对于云计算这一新基础设施来说,也是如此。在2015年之前,对于大多数应用来说,云端只是一个用于计算的场所,开发人员所要做的就是将原来在私有数据中心或IDC中的应用,迁移到云端。在迁移的过程中,应用无须重新编写,只需要重新部署,因为云平台提供的计算、存储、网络等,完全兼容应用迁移之前的计算环境。在迁移模式中,
迁移之后,应用的整体成本(Total Cost ofOwnership,TCO)因为采用了“按量付费”的模式而大幅下降,同时,企业的IT支出从CapEx(Capital Expenditure,资本性支出)模式转变为OpEx(Operating Expense,管理支出)模式,整个IT支出变得更可控。
如果对迁移过程进行技术分析,就会发现大部分应用使用的技术或者产品都在进行“一对一”的替换,只有极少量应用会基于OSS(对象存储服务)、MaxCompute(大数据计算服务)等云服务进行部分重构。OSS能够帮助解决分布式状态的存储问题,而MaxCompute能够解决数据仓库的快速搭建和成本问题。但由于没有或者只进行了少量重构,因此应用的技术栈本身几乎没有发生变化,也就是说,软件的架构没有发生变化,只是软件运行的平台和运维的技术体系发生了变化,即只有平台层面的变化。而软件在分布式场景下需要解决的问题,包括稳定性、组件或服务之间的数据同步、整体的高可用或容灾、CI/CD过程的自动化、资源利用率不高、端到端链路跟踪等,仍然需要应用自行解决。这些问题并不会因为应用迁移到了云平台就从根本上得到了解决。
当然,各云平台为了帮助应用解决上述分布式复杂性问题,不断推出各类云服务,但是由于应用架构本身并没有发生变化,因此这些云服务并不能帮助应用解决整体问题,只能从局部提升应用的效率。
面对大量的业务需求和场景迭代,很多云平台都提供非常专业的垂直领域服务,这些服务比企业基于开源自行搭建的系统具备更高的SLA(Service Level Agreement,服务等级协议)。比如,
如果不是应用的所有存储访问代码都在S3或OSS上重构,那么“木桶效应”就会凸显,即整个系统的数据持久性将取决于能力最差的组件;如果应用不是将所有自持的开源组件都迁移到云平台上,那么当一个机房出现故障时,应用仍然会出现高可用性的问题;如果应用不是基于FaaS(Function as a Service,功能即服务)技术开发的,那么应用仍然需要自行解决单个组件不可用时的Fail Over(失效转移)以及故障恢复时的Fail Back(失效后自动恢复)等问题。
可见,应用迁移到云上并不代表从此以后就高枕无忧了,如果应用本身没有基于“新”的云服务进行重构,而是继续采用“老”的架构,那么即使业务运行没有问题,应用也不能充分利用“新”的云运行环境的能力。因为这些架构是为了“老”的分布式运行环境而设计的,不是“云原生的”,所以需要对这些架构以及围绕这些架构建立的技术栈、工具链、交付体系进行升级,依托于云技术栈将其重新部署、部分重构甚至全部重写,才能将应用变成“云原生的”,从而保证能够充分利用云计算的能力。
为了让应用能够更好地使用云的PaaS平台能力开发SaaS(Software as a Service,软件即服务),Heroku于2011年提出了十二因子应用的概念。十二因子应用适用于任何编程语言,通常被认为是最早的云原生应用的技术特征,详情请参考
之后,Pivotal于2015年明确地提出了云原生的概念,指出云原生是一种可以充分利用云计算优势构建和运行应用的方式。
在经过CNCF的修改后,最新版云原生的定义为:
“云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统做出频繁和可预测的重大变更。”
上面三个主流的定义,分别从顶层架构原则、计算模型和代表技术的角度,对云原生进行了描述。这些定义的共同点是它们都将云原生看作一种新的计算方式,让应用能够充分使用云的计算优势。进一步分析这些定义所体现出的技术观点,我们可以达成这样一个共识:
只有结合云原生所提供的云服务,改造应用的架构,才能够更好地使用云原生技术,更好地构建弹性、稳定、松耦合的分布式应用,并解决分布式复杂性问题。此外,对架构的改造还意味着相关的开发模式、交付方式、运维方式等都要随之改变,比如,采用微服务架构重写应用,用声明式API和自动化工具升级运维方式,等等。简单来说,云原生使得整个软件的生产流水线都发生了巨大的变化,而具体的变化程度又取决于企业对云原生的使用情况。
实际上,云原生的范围还不止于此。要正确实施云原生这一新计算模式,还需要企业的IT决策者、架构师、开发人员与运维人员正确理解和应用云原生的理念,利用合适的云原生技术及产品。有太多的反例可以证明,仅靠单边的技术升级是很难让云原生升级产生价值的。云原生相关概念之间的关系如下图所示。
在上图中,现代化应用在不少场合与云原生应用的概念是等同的,因为它们的很多特征都是相似的,比如,都采用了容器技术打包和交付,都具备很强的弹性能力等。这两个概念的细微差别在于:现代化应用可以与云相关,也可以与云不相关;而云原生应用通常都与云相关。
所以云原生(或者说云原生计算)应当包括云原生技术、云原生产品、云原生架构以及构建现代化应用的开发理念,如DevOps,具体说明如下。
软件能力成熟度模型(Capability Maturity Model for Software,CMM),作为一种评估软件实施能力和帮助企业改善软件质量的方法,对于软件企业在软件的定义、实施、度量、控制和改善等各个阶段的管理工作都进行了详细描述。
1987年,美国的卡内基梅隆大学受美国国防部的委托,对软件行业提出的软件过程成熟度模型,随后成为国际上各软件企业都接受并推崇的软件评估标准。CMM包含初始级、可重复级、定义级、管理级和优化级5个级别,共计18个过程域、52个目标,以及300多个关键实践。
相对CMM而言,云原生架构的目标更简单,主要是帮助企业改善软件的架构,使其能够快速、有效地享用云计算提供的各种服务,提升软件的交付效率,降低软件的整体成本,提高软件的交付质量。在这个框架下,很多基础的软硬件环境等都由云厂商提供,且它们提供的云服务往往都包含业界最佳实践的产品及解决方案。云厂商所具备的大量行业属性的文档也可以作为模板供企业参考,以便企业能够更好地梳理相关流程,实施这些云服务。因此,可以用更简单和更便于操作的方式对云原生架构进行成熟度的定级,如下表所示。
阿里巴巴为大量各行各业的企业客户提供了基于阿里云服务的解决方案和最佳实践,以帮助企业完成数字化转型,并积累了大量经验和教训。阿里巴巴将企业的核心关注点、企业组织与IT文化、工程实施能力等多个方面与架构技术相结合,形成了阿里巴巴独有的云原生架构设计方法——ACNA(Alibaba Cloud Native Architecting)。
(1)ACNA的作用与目的
(2)ACNA的实现步骤
ACNA是一个“4+1”的架构设计流程,其中,“4”代表架构设计的关键视角,包括企业战略视角(ACNA-S1)、业务发展视角(ACNA-S2)、组织能力视角(ACNA-S3)和云原生技术架构视角(ACNA-S4);“1”表示云原生架构的架构持续演进闭环(ACNA-S5)。4个关键视角和1个闭环的关系(命名为ACNA-G1)如下图所示。
ACNA除了是一种架构设计方法,还包含对云原生架构的评估体系、成熟度衡量体系、行业应用最佳实践、技术和产品体系、架构原则、实施指导等。
任何架构都必须服务于企业战略,云原生架构也不例外!与以往架构的升级有所不同,云原生架构的升级不仅是技术的升级,更是对企业核心业务生产流程(即通过软件开发和运营构建数字化业务)的一次重构,云原生架构升级的意义,如同工业时代用更自动化的流水线替换手工作坊一样深刻。
企业必须清楚业务战略与云IT战略之间的关系,即云IT战略只是对业务战略进行必要的技术支撑,还是云IT战略本身也是业务战略的一部分。通常,高科技公司会对云计算提出更高的需求,比如,
实际上,在数字化转型的今天,越来越多的企业认为云IT战略应该在企业业务战略中扮演技术赋能业务创新的重要角色,云IT已经变成了“Cloud First”,甚至“Cloud Only”,只是在全部采用公有云还是采用混合云的策略上存在一些差别。基于云IT战略,云原生架构可以帮助企业实现泛在接入技术,构建数字化生态系统,还可以从技术的角度确保数字化业务的快速迭代,构建面向用户体验管理的数字基础设施,持续优化IT成本,降低业务风险。
阿里巴巴在为企业提供云服务和咨询的过程中发现,数字化业务对技术架构的主要诉求是保证业务连续性、业务快速上线、业务成本控制,以及科技赋能业务创新。
云原生架构升级是对企业的整个IT架构的彻底升级,每个组织在进行云原生架构升级时,必须根据企业自身的情况量体裁衣,其中,组织能力和技术栈处于同等重要的地位。云原生架构涉及的架构升级对企业中的开发、测试和运维等相关人员都带来了巨大的影响,技术架构的升级和实现需要企业中相关组织的积极参与和配合。特别是在架构持续演进的过程中,需要类似“架构治理委员会”这样的组织负责云原生的规划和落地,并不断检查和评估架构设计与执行之间是否存在偏差。
此外,云原生架构的设计还需要考虑组织结构的改变。前面提到一个非常重要的云原生架构原则就是服务化(包括微服务、小服务等),这个领域的一个典型原则就是康威定律,要求企业的技术架构与沟通架构必须保持一致,否则会导致畸形的服务化架构,甚至导致组织沟通成本上升和“扯皮”现象增多的问题。
企业需要考虑的另外一个很重要的问题就是,企业接受改变的程度如何,或者说,企业能够快速进行组织结构调整,并保持业务稳定性的能力如何。云原生架构升级要求大量的企业IT人员也进行技术体系的升级和岗位职能的重新设计,这势必导致原本处于稳定和舒适区的技术领导者和底层员工必须破而再立,所以组织改变的风险不得不慎重考虑。
从技术架构的维度看,ACNA认为架构维度包含七个重要的领域,具体说明如下。
云原生架构演进是一个不断迭代的过程,每一次迭代都要经历从企业战略、业务诉求到架构设计与实施这样一个完整的闭环,整体关系(命名为ACNA-G2)如下图所示。
下面就来详细介绍架构持续演进闭环的关键输入和实现过程。
云原生架构成熟度模型是一种能够帮助企业找到当前软件架构与成熟的云原生架构之间的差距,从而在后续的架构优化迭代中进行针对性改善的评估模型。ACNA参考CMM(Capability Maturity Model,能力成熟度模型)的定义,从主要的架构维度定义了云原生架构的成熟度模型。
我们需要注意到,ACNA的云原生架构成熟度评估模型不会帮助企业从通用技术架构、应用架构或信息架构的维度进行评估,因此它并没有帮助实施者梳理架构的核心利益相关者和架构交付合同。同时,评估模型本身也没有对团队核心人员技能以及组织的流程、文化和流水线建设进行评估,而是从基于云的现代化应用这一特定的软件技术架构进行评估。虽然这样的评估范围相对较小,但是更专业,可操作性更强。
此外,ACNA云原生架构成熟度模型的评估对象不是企业或架构实施人员,而是某个具体软件所采用的架构。因此,对于一个企业而言,可能部分软件的评估结果是零级(初始级),部分软件的评估结果是中级(发展级),这完全取决于每个软件自身的架构情况。
ACNA云原生架构设计共包含6个关键架构维度(Service+Elasticity+Serverless+Observability+Resilience+Automation,简写为SESORA),在此我们先定义关键维度的成熟度级别,如下图所示(命名为ACNA-T1)。
结合云原生架构的四个不同成熟阶段,我们定义了整个架构的成熟度模型,如下图所示。
函数计算主要包含服务、函数、实例、运行环境、触发器、层、应用中心等功能组件,具体产品组件架构图如下图所示。
功能项 | 说明 | 相关文档 | |
---|---|---|---|
多触发器 | 函数计算支持HTTP触发器以及OSS触发器、SLS触发器等多种事件驱动触发器。此外,函数计算无缝集成事件总线EventBridge,进一步动态扩展函数的事件触发源。 | 触发器简介 | |
多语言执行环境 | 函数计算支持Java、Python、Node.js、PHP、Go及.NET Core语言,并且支持通过Custom Runtime的方式来构建其他语言的Runtime,例如Go Custom Runtime、Ruby Custom Runtime和PowerShell Custom Runtime等。为了丰富使用场景,还提供自定义镜像作为运行环境的能力。 | 代码开发概述 | |
灰度发布 | 通过线上新旧版本共存的灰度发布方式,小范围验证新版本的能力,逐步切换流量到新版本。同时,可以快速地切换主版本和灰度版本,只需变更别名指向的版本号,即可完成新旧版本的平滑切换。 | 使用版本和别名实现灰度发布 | |
单实例多并发 | 为了进一步减少实例资源使用量,优化资源成本,降低冷启动,函数计算支持单实例多并发能力。默认情况下,函数的实例并发度为1,即一个实例同时只会处理一个请求。当您设置单实例并发度大于1后,函数计算在弹性伸缩时,充分利用完一个实例的并发度后才会创建新的实例。 | 设置实例并发度 | |
可观测 | 日志服务 | 函数计算支持将函数调用执行的日志存储至阿里云日志服务SLS,再根据日志服务中存储的函数日志来执行代码调试、故障分析、数据分析等操作。 | 配置日志 |
指标监控 | 函数计算提供多层次、多维度的监控指标。通过实时监控和性能数据采集,并进行可视化展示,为您提供端到端的监控排查路径。 | 监控指标 | |
链路追踪 | 阿里云链路追踪Tracing Analysis基于OpenTracing标准,兼容开源社区,为分布式应用的开发者提供了完整的分布式调用链查询和诊断,分布式拓扑动态发现,应用性能实时汇总等功能。
函数计算与链路追踪集成,支持使用Jaeger上传链路信息,使您能够跟踪函数的执行,帮助您快速分析和诊断Serverless架构下的性能瓶颈,提高Serverless场景的开发诊断效率。 |
什么是链路追踪Tracing Analysis | |
应用中心 | 函数计算提供一站式Serverless应用管理。从一键管理应用到快速体验,从GitOps流程到应用管理,帮助开发者快速完成应用从无到有再到多的过程。 | 使用函数计算快速搭建管理NAS的可视化应用 |
触发器是触发函数执行的方式。在事件驱动的计算模型中,事件源是事件的生产者,函数是事件的处理者,而触发器提供了一种集中、统一的方式来管理不同的事件源。在事件源中,当事件发生时,如果满足触发器定义的规则,事件源会自动调用触发器关联的函数。
按照触发器集成方式,函数计算支持的触发器分为双向集成触发器、单向集成触发器和EventBridge触发器,三类触发器的区别如下:
从函数调用方式的角度,触发器又可以分为同步调用触发器和异步调用触发器,两种调用方式的区别如下所示。
双向集成触发器
触发器名称 | 调用方式 | 文档链接 |
---|---|---|
定时触发器 | 异步调用 | 定时触发器概述 |
OSS触发器 | 异步调用 | OSS触发器概述 |
SLS触发器 | 同步调用 | SLS触发器 |
CDN事件触发器 | 同步调用 | CDN事件触发器概述 |
Tablestore触发器 | 同步调用 | Tablestore触发器概述 |
MNS主题触发器 | 异步调用 | MNS主题触发器 |
HTTP触发器 | 同步调用 | HTTP触发器概述 |
单向集成触发器
触发器名称 | 调用方式 | 示例链接 |
---|---|---|
API网关触发器 | 同步调用 | API网关触发器概述 |
DataHub单向触发器 | 同步调用 | DataHub单向触发器 |
EventBridge触发器
触发器名称 | 调用方式 | 示例链接 |
---|---|---|
消息队列RocketMQ版触发器 | 同步调用 | RocketMQ触发器 |
消息队列RabbitMQ版触发器 | 同步调用 | RabbitMQ触发器 |
消息服务MNS队列触发器 | 同步调用 | MNS队列触发器 |
消息队列Kafka版 | 同步调用 | Kafka触发器 |
阿里云官方事件源触发器 | 同步调用 | 阿里云产品事件触发器 |
为满足不同场景下的用户需求,函数计算提供事件函数和HTTP函数两种函数类型,支持内置运行时、自定义运行时和容器镜像三种部署函数的方式。
函数计算目前支持两种类型的函数:
函数计算的编程模型中,入口函数的模型由函数名、函数入参和返回值三部分组成。其中,函数入参也可以调用代码中定义的其他函数。
事件函数和HTTP函数在触发方式和函数入参两方面的区别如下。
函数类型 | 触发方式 | 函数入参 |
---|---|---|
事件函数 |
您可以通过触发函数执行来实现某个特定功能。事件函数支持通过定时器、调用API/SDK或其他阿里云服务的触发器来触发函数执行。支持创建任何除HTTP触发器以外类型的触发器,例如OSS触发器、SLS触发器、CDN事件触发器、Tablestore触发器和EventBridge触发器等。关于支持的触发器类型和更多信息,请参见触发器简介。所有支持类型的触发器均可触发事件函数。 |
以Node.js语言为例,一个简单的入口函数模型如下所示。
有关Node.js事件函数的更多信息,请参见事件请求处理程序(Event Handler)。有关其他编程语言的函数入参介绍,请参见开发语言列表。 |
HTTP函数 |
HTTP函数仅支持通过发送HTTP/HTTPS请求来触发函数执行。您可以自行配置触发方式,例如GET、POST、PUT、DELETE、HEAD和PATCH方式。 为函数创建HTTP触发器后,HTTP触发器通过发送HTTP/HTTPS请求触发函数执行。一个版本或别名下仅支持创建一个HTTP触发器。具体信息,请参见HTTP触发器概述。 |
以Node.js语言为例,一个简单的入口函数模型如下所示。
有关Node.js HTTP函数的更多信息,请参见HTTP请求处理程序(HTTP Handler)。有关其他编程语言的函数入参介绍,请参见开发语言列表。 |
从开发流程角度,函数的部署方式包括通过控制台部署、通过Serverless Devs工具部署和调用API/SDK部署。具体信息,请参见使用控制台创建函数、使用Serverless Devs管理函数资源和CreateFunction。
从Runtime类型角度,函数计算支持三种部署方式:使用内置运行时创建、使用自定义运行时创建、使用容器镜像创建。您可以根据业务情况选择不同的部署方式。
对比项 | 使用内置运行时创建 | 使用自定义运行时创建 | 使用容器镜像创建 |
---|---|---|---|
代码包限制 | 最大支持10 GB原始代码 | 最大支持10 GB原始代码 | 最大支持10 GB未解压镜像 |
代码包格式 | ZIP、JAR(Java)、文件夹 | ZIP、JAR(Java)、文件夹 | 参见什么是容器镜像服务ACR |
是否支持GPU实例 | 不支持 | 不支持 | 支持 |
运行时环境 | Node.js、Python、PHP、Java、.NET Core 、Go | 无限制 | 无限制 |
函数计算工作流程如下图所示。
略
未完成重构的部分:
仅对多引擎部分进行了重构,多引擎和其他组件之间的分布式和消息同步,依然采取的事原始分布式架构的中间件,从宏观上看依然存在scale-up瓶颈