写点什么

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:002462

评论

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

云数据库TiDB免费试用初体验

TiDB 社区干货传送门

版本测评 安装 & 部署

TiDB SQL调优案例之避免TiFlash帮倒忙

TiDB 社区干货传送门

性能调优 实践案例 故障排查/诊断

Apache APISIX 3.2.0 LTS 正式发布

API7.ai 技术团队

携程 x TiDB丨应对全球业务海量数据增长,一栈式 HTAP 实现架构革新

TiDB 社区干货传送门

文盘Rust -- 安全连接 TiDB/Mysql

TiDB 社区干货传送门

开发语言

网易携手昇腾AI打造玉知-悟空图文理解大模型,做更“懂你”的产品

Geek_2d6073

将TiDB各服务组件混布到物理机集群和K8S环境

TiDB 社区干货传送门

实践案例 集群管理 管理与运维 安装 & 部署 数据库架构设计

TiCDC 源码解读(6)- TiCDC Puller 模块介绍

TiDB 社区干货传送门

TiDB 源码解读 TiCDC 源码解读

搭建阿里云 TiDB 的灾备,让我安欣睡个好觉

TiDB 社区干货传送门

实践案例 安装 & 部署 备份 & 恢复 数据库架构设计

你可能并不了解 Milvus

Zilliz

SaaS Milvus 社区活动

详解ResNet 网络,如何让网络变得更“深”了

华为云开发者联盟

人工智能 神经网络 华为云 华为云开发者联盟 企业号 3 月 PK 榜

未来智安再获安全牛《网络安全优质初创企业HOT50》推荐

未来智安XDR SEC

Java 8 的异步利器:CompletableFuture源码解析(建议精读)

Java你猿哥

Java ssm java8 源码解析

数据湖选型指南|Hudi vs Iceberg 数据更新能力深度对比

袋鼠云数栈

数据湖

HummerRisk 使用教程:主机检测

HummerCloud

监控告警处理之tidb_server_critical_error_total

TiDB 社区干货传送门

监控 故障排查/诊断

手把手教你写spring boot starter

三十而立

Java 程序员 IT springboot boot

基于阿里云数据库TiDB的性能压测初体验

TiDB 社区干货传送门

性能测评 6.x 实践

基于 TiCDC 的 TiDB 复制集群的计划内和计划外切换验证步骤

TiDB 社区干货传送门

性能调优 实践案例 故障排查/诊断 数据库架构选型

百度“文心一言”申请服务测试企业达7.6万,股价拉升涨幅近15%

Geek_2d6073

设计消息队列存储消息数据的 MySQL 表格

Geek_7d539e

BSN-DDC基础网络详解(五):接入DDC网络(2)

BSN研习社

BSN-DDC基础网络

官宣:OpenDAL 成功进入 Apache 孵化器

Databend

“奇遇未来”专访:一个小众、专业的产品经理实训品牌

Geek_2d6073

TiCDC 源码解读(5)-- TiCDC DDL 事件处理逻辑 与 Filter 实现介绍

TiDB 社区干货传送门

TiCDC 源码解读

华秋工艺分享:第八道主流程之丝印文字流程

华秋电子

云图说丨初识华为云安全云脑——新一代云安全运营中心

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 3 月 PK 榜

Dr-autosync TiDB 集群的计划内和计划外切换验证步骤

TiDB 社区干货传送门

实践案例 集群管理 安装 & 部署 数据库架构选型 6.x 实践

阿里是如何使用分布式架构的?阿里内部学习手册分享

Java你猿哥

Java 分布式 微服务 分布式架构

TiDB容器化的管理利器--TiDB Operator

TiDB 社区干货传送门

集群管理 新版本/特性发布 安装 & 部署 新版本/特性解读

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