硬核干货——《中小企业 AI 实战指南》免费下载! 了解详情
写点什么

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

  • 2016-07-19
  • 本文字数:3547 字

    阅读完需:约 12 分钟

按语

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 新要素

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

作者简介

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


感谢木环对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-07-19 19:002802

评论

发布
暂无评论
发现更多内容

透气胶浆、无手感透气胶浆

C13713145387

透气胶浆 仿拔印浆 无手感透气浆

Linux grep 命令

一个大红包

4月日更

避免人工智能存在“歧视”,要从这8大方法入手

澳鹏Appen

人工智能 机器学习 大数据 人脸识别

「 留言参与 」—— InfoQ 写作平台【 1 周年盛典 】

InfoQ写作社区官方

1 周年盛典 热门活动

BOE(京东方)2020年报发布: 营收1355.53亿元 净利润大幅增长162.46%

《采访彩食鲜 CTO 乔新亮:如何从一名程序员晋阶为CTO》(采访提纲)

石云升

28天写作 4月日更 调查采访能力考核

重读《重构2》- 提炼变量

顿晓

重构 4月日更

Modus串行链路系统电气特性:2线-Modus、4线-Modus、RS232-Modus和RS485-Modus的特性

不脱发的程序猿

通信协议 4月日更 Modus 串行链路 RS232、RS485

最全 MongoDB 基础教程

若尘

数据库 mongodb mongo

对混沌工程的五个常见误解

混沌工程实践

混沌工程 故障注入 误区 生产事故 监管合规

多年后,我终于看清了比特币的本质

陈东泽 EuryChen

比特币 区块链

阿里巴巴云原生 etcd 服务集群管控优化实践

阿里巴巴云原生

容器 运维 云原生 k8s 存储

基于深度神经网络的噪声标签学习

华为云开发者联盟

神经网络 损失函数 深度神经网络 噪声 噪音数据

第一篇测试

童童

架构训练营

PHP自动加载原理

Sakura

4月日更

Modbus协议在串行链路上的实现

不脱发的程序猿

通信协议 物联网常用协议 4月日更 Modbus 串行通信

SpringCloud(Netflix)-技术专题-自定义配置Ribbon

码界西柚

SpringCloud Ribbon

联邦学习,为何而生?

博文视点Broadview

KubeVela 1.0 :开启可编程式应用平台的未来

阿里巴巴云原生

容器 云原生 k8s 消息中间件 Go 语言

SpringCloud(Netfix)-技术专题-服务注册与发现

码界西柚

SpringCloud

CloudQuery v1.3.6发布,更加完善的数据操作支持

BinTools图尔兹

数据库 sql 数据安全 数据管理工具

云原生势不可挡,华为云GaussDB加速企业数字化转型

华为云开发者联盟

华为云 GaussDB

1小时破千万点击量!阿里巴巴首发:Java核心框架指导手册

Java架构追梦

Java 阿里巴巴 架构 面试 核心框架

投资的狠人,往往是这样的

陈东泽 EuryChen

比特币 区块链 投资 李笑来 debank

应对海量时序数据,华为云GaussDB(for Influx)有妙招

华为云开发者联盟

云原生 数字化转型 时序数据 华为云GaussDB

LeetCode题解:剑指 Offer 49. 丑数,三指针,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

防晒衣专用水性油墨说明书

C13713145387

防晒衣专用水性油墨 防水尼龙水性油墨

华为云PB级数据库GaussDB(for Redis)揭秘第七期:高斯Redis与强一致

华为云开发者联盟

redis 华为云 GaussDB(for Redis) 强一致 PB级数据库

【LeetCode】实现 Trie (前缀树)Java题解

Albert

算法 LeetCode 4月日更

全球案例 | NTT:Atlassian 帮助我们重塑危机中的可能性

Atlassian

敏捷 团队协作 数字化转型 Atlassian Jira

智慧城市:大数据运营中心 IOC —— Web GIS 地图应用

一只数据鲸鱼

WebGIS ioc 数据可视化 智慧城市 数据运营

The Twelve-Factor在Cloud Native时代是否依然适用?_语言 & 开发_刘永峰_InfoQ精选文章