The Twelve-Factor在Cloud Native时代是否依然适用?

简介:

按语

Heroku是云应用平台的先驱,从对外提供服务以来,他们已经有上百万应用的托管和运营经验。其创始人Adam Wiggins根据这些经验,提出了十二要素应用宣言 。The Twelve-Factor App定义了一个优雅的互联网应用在设计过程中,需要遵循的一些基本原则。

不过, The Twelve-Factor是在特定的时期,针对特定的平台实践所总结出来的。12元素依然璀璨,很多原则依然具有普适性;但是在应用全面迁移到云端的今天,Cloud Native时代的应用开发,需要有更多与时俱进的实践新原则。The Twelve-Factor的哪些原则依然是适用的?哪些在实践需要与时俱进?这些都是众多Cloud Native的实践者需要探求的答案。

新原则1:微服务应该以无状态的方式运行

The Twelve-Factor指出一个应用在运行时,应该以一个或者多个无状态的进程来运行。进程之间需要做到无状态,并且无共享。任何需要持久化的数据,都应该写入到后端服务中,譬如数据库。这一原则,目的是避免进程和进程之间的耦合。让每一个进程,能够独立于其他实体单独构建和运行。

在很多在线系统中,会使用session(会话)来传递当前的状态。当被调用方接收到session后,会将它保存下来,后续的请求,都会被路由到这个服务中。这时请求和请求之间,会有严格的调用顺序。Cloud Native的实践原则是需要避免这种情况。

在Cloud Native理念中,每一个功能实体实际上是以一个微服务的形式运行的。微服务是一个单独的自治系统,它可以不依赖其他服务而单独存在。所有的微服务,都应该是以一种无状态的接口对外提供服务(譬如Restful API)。微服务自身不应该保存任何的状态。如果微服务需要持续地保存数据,应该采用的做法是:调用服务化的存储,将数据保存在另一个存储服务里面。微服务之所以小块头能发挥大能量,正是源于无状态的设计从而保证可以同时由多个实例提供服务,让服务能力能够自由的伸缩。

当然,在实际的实践过程中,特别是针对大的系统,很难做到完全无状态的拆分。对一个完整的微服务架构,会分为事务性服务和存储型服务。通常说来,事务性服务需要做到无状态设计;所有的持久化数据,可以通过存储型服务来进行存储和读取。存储型服务尽量使用云端提供的集中式的服务化存储能力,譬如云端的对象存储。

新原则2:应通过配置来唯一定义一个系统

The Twelve-Factor的第五条原则提到了应用需要严格区分构建、发布、运行这三个步骤:譬如直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。The Twelve-Factor的第五原则,很好的规范了一个应用从开发到运营的标准化的操作流程。但是第五原则,只是保证了应用源码的唯一性。很多时候,一个系统的故障,并不仅仅是由源码导致的,很大一部分故障,和配置以及环境的变化存在关系。所以The Twelve-Factor的第五原则在Cloud Native的理念下,需要与时俱进。

Cloud Native在实践时,是通过Docker+微服务的方式去实现的。Docker实现了Build、Ship、Run的统一。任何系统,都是可以通过一些配置,唯一定义出来的。当这个系统定义出来以后,应该是能够重构出来,不随着时间、运行环境或依赖条件变化而变化。同时,这个系统不管处于开发阶段、测试阶段还是运营阶段,其状态都是唯一的。

譬如,在实践过程中,可以通过Docker Compose的YAML文件唯一的定义一个容器间互联的系统。这个系统的配置是唯一确定的,可以在任何的容器环境下去执行。会有一个唯一的仓库(Docker Registry)来存储镜像。所有的镜像,都是通过Dockerfile唯一定义的。当触发了源码的变更以后,这个系统的各个组件可以自动的去构建,然后更新到“仓库”,在通过Docker Compose组装起来。只要遵循了这套标准化的流程,系统不会区分开发环境,测试环境,运营环境。所有的东西,就只有一个环境;这个环境,是唯一的、可定义的。

在实践这条原则时,需要遵循以下几条规范: 
需要有唯一的源码库,并保证任何的变更都是在源码托管库中进行 
通过Dockerfile来构建镜像而非通过运行中的容器来打包镜像 
通过配置来定义容器之间的连接关系而非手动的部署

新原则3:应该使用服务化存储

The Twelve-Factor 有一条原则是“把后端服务(backing services)当作附加资源”,后端服务是指程序运行所需要的通过网络调用的各种服务,如数据库(MySQL,CouchDB)、消息/队列系统(RabbitMQ,Beanstalkd)、SMTP 邮件发送服务(Postfix)以及缓存系统(Memcached)。这些都是作为“资源”来对待,目的是为了保证模块之间的松耦合。

作为一个系统中最重要的角色,存储模块当然必不可少。存储有很多种类:块存储、对象存储、数据库存储、缓存。传统上,我们接触比较多的是块存储。在Cloud Native的理念下,一个系统中,所有的组成实体都可以服务化。有事务型的服务,也有存储型服务。微服务之间是一种松散耦合的关系。服务和服务之间,是没有任何耦合关系的,只有调用关系。当一个服务,需要存储数据怎么办?一种方案是把数据存在在服务内部,这样势必导致了服务存在状态,从而限制了服务的横向扩展的能力。前面一节,我们提到了一个重要原则是,事务型服务尽量保证是无状态的。所以当一个事务型服务需要存储数据时,应该是将数据存储到另外一个存储型服务中,通过存储型服务提供的标准接口和协议读取或者写入数据。在云上我们通常使用的对象存储,或者云端的数据库,就是这种服务化的存储方式。

使用服务化存储,可以带来三个方面的好处: 
将存储和逻辑处理分离,让系统能够自动化的重构出来 
统一存储,不需要单独考虑服务内部存储的容错、备份等机制 
做到事务型服务无状态,便于横向扩展

总结

The Twelve-Factor APP作为网络应用开发的最佳实践原则,的确具有强大的生命力。每一条原则都是应用开发的珠玑。但是技术总是不停的发展,在云的时代,所有的应用都会迁移到云端,完全基于云的架构设计和开发模式需要一套全新的理念去承载。这个时候,Cloud Native的思想应运而生。在Cloud Native时代,The Twelve-Factor 的核心思想依然璀璨,但是应该随着这种新的理念去延伸、发展。文章提到的三条新原则,也正是The Twelve-Factor 的延伸。未来,随着Cloud Native 思想在开发中使用越来越广泛,一定会延伸出更多的实践的原则。

资料附:Cloud Native时代12新要素

从一个代码库部署到多个环境——一个代码库,包括生产环境软件包,确保了单一的信任源,从而保证了更少的配置错误和更强的容错和复原能力。 依赖管理是声明式的——云平台根据这些声明管理依赖,确保云应用所需的库和服务。 配置信息保存在环境中——环境变量是一种清楚、容易理解和标准化的配置方法,特别适合用不同编程语言编写的无状态应用的使用。 将后台服务视为附加的资源——将每一种资源都视为一种远程的资源,应用因此具有容错和复原能力,因为它一方面要求编码时就要考虑资源不可用的情况,另外一方面也增强微服务方法的好处。 区分构建、发布和运行阶段——Cloud Native应用的构建流程把大部分发布配置挪到开发阶段,包括实际的代码构建和运行应用所需的生产环境配置。 作为无状态进程运行——尽量保持应用栈每一层的轻量级,保证Cloud Native基础设施的速度和效率。 通过端口绑定对外暴露服务——Cloud Native应用的服务接口优先选择 HTTP API 作为通用的集成框架。 通过添加无状态进程实现横向扩展——强调无状态、无共享的设计,这意味着依赖底层平台就能实现横向扩展,不需要技术难度高的多线程编码。 快速地启动,优雅地关停——假设任何进程随时都能启动和关停。 开发、预发布和生产环境运行同样的应用和依赖配置——由于强调自动化和在每个阶段使用同一个云平台,如果每个人用同样的服务器配置,那么“应用在我这里是可以的”就意味着在其他人或者环境那里也是可以的。 日志输出到标准输出,方便日志聚合和事件响应——当日志是由云平台而不是应用包含的库处理时,日志处理机制必须保持简单。 临时任务作为短时进程运行——在Cloud Native中,管理任务也是一个进程,而不是特别的工具;同样重要的是,管理任务的进程不应使用秘密的 API 或者内部机制。

作者简介

刘永峰,腾讯云高级产品经理,布道师,十余年的产品及研发管理经验。国内最早一批从事可信计算研究的探索者。曾就职于中兴通讯,负责流媒体Server后台架构设计,Linux内核相关的研究。2011年起加入腾讯,一直从事公有云的产品设计,云计算市场趋势分析和研究,云计算技术的推广与普及。在技术和产品领域均具有丰富的行业经验。目前主要关注Docker,微服务,Cloud Native, 企业云化趋势等相关领域。





====================================分割线================================


本文转自d1net(转载)

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
存储 Cloud Native NoSQL
【Paper Reading】Cloud-Native Transactions and Analytics in SingleStore
HTAP & 云原生是如今数据库技术演进的两大热点方向。HTAP 代表既有传统的 HANA Delta RowStore+Main ColumnStore,Oracle In-MemoryColumnStore 等方案,也有像 TiDB,Snowflake Unistore这样新的技术架构;云原生代表则是以 S3 为低成本主存的 Snowflake,Redshift RA3,提供灵活弹性和Serverless 能力。SingleStore 则是首次把两者结合起来,基于计算存储分离的云原生架构,用一份存储提供低成本高性能的 HTAP 能力。
【Paper Reading】Cloud-Native Transactions and Analytics in SingleStore
|
9月前
|
存储 缓存 分布式计算
Gluten + Celeborn: 让 Native Spark 拥抱 Cloud Native
本篇文章介绍了 Gluten 项目的背景和目标,以及它如何解决基于 Apache Spark 的数据负载场景中的 CPU 计算瓶颈。此外,还详细介绍了 Gluten 与 Celeborn 的集成。Celeborn 采用了 Push Shuffle 的设计,通过远端存储、数据重组、内存缓存、多副本等设计,不仅进一步提升 Gluten Shuffle 的性能和稳定性,还使得 Gluten 拥有更好的弹性,从而更好的拥抱云原生。
1634 4
Gluten + Celeborn: 让 Native Spark 拥抱 Cloud Native
|
网络协议 关系型数据库 MySQL
Cloud platform build management Topic | Cloud computing (FREE)
云平台构建及管理习题(试读)
120 0
|
Linux Docker Windows
Quarkus构建native-image遇到的问题及解决
构建的时间比较长,构建完成后就会在 ./target 目录下生成一个二进制执行文件,一般名字是 quarkus-demo-1.0-runner,直接执行这个二进制文件就可以运行项目了。
757 0
|
分布式计算 Spark
《Acceleration of Generic SPARK Workloads via a “Sea of Cores” Scalable Compute Fabric》电子版地址
Acceleration of Generic SPARK Workloads via a “Sea of Cores” Scalable Compute Fabric
56 0
《Acceleration of Generic SPARK Workloads via a “Sea of Cores” Scalable Compute Fabric》电子版地址
|
Cloud Native 架构师 关系型数据库
Performance Test on Cloud-native Databases
Performance Test on Cloud-native Databases
107 0
Performance Test on Cloud-native Databases
|
存储 运维 Kubernetes
Cloud Native的黑与白
Cloud Native的黑与白
144 0
Cloud Native的黑与白
|
监控 Java 关系型数据库
Cloud Native 与12-Factor
12-Factor(twelve-factor),也称为“十二要素”,是一套流行的应用程序开发原则。Cloud Native架构中使用12-Factor作为设计准则。 12-Factor 的目标在于: 使用标准化流程自动配置,从而使新的开发者花费最少的学习成本加入项目中。
2617 0
|
安全
Three Reasons to Add Alibaba Cloud to Your Multi-Cloud Strategy
From the minute you chose one of the world’s most popular cloud computing companies as your strategic cloud services provider, your world became multi-cloud.
2087 0
Three Reasons to Add Alibaba Cloud to Your Multi-Cloud Strategy