写点什么

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

评论

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

2023年10大主流产品路线图绘制软件盘点

爱吃小舅的鱼

产品经理 产品路线图工具

YOWOv2:优秀的实时视频动作检测框架

Zilliz

计算机视觉 构建模型 Milvus

如何通过优化图片、JS等资源加载项来提高网页的加载速度?

兴科Sinco

前端开发 CDN HTTP 网页加速

《深入理解高并发编程:JDK核心技术》-冰河新书上市

冰河

并发编程 多线程 高并发 协程 异步编程

爆火!阿里新版23年面试突击进阶手册,Github标星51k!

Java你猿哥

Java 面试 ssm 面经 八股文

硬核!阿里大佬都在内卷的SpringBoot从入门到实战笔记

Java你猿哥

Java Spring Boot ssm 实战 Spring全家桶

抽丝剥茧还原真相,记一次神奇的崩溃

阿里技术

debug

面试造飞机?GitHub顶级“java面试手册2023”(统计通过率95%)

三十而立

Java GitHub 面试 java面试

Copilot 用“粉紫色磨砂UI”和“啊啊啊BGM ”,梦境了这届网友

B Impact

代码开源!阿里妈妈展示广告Match底层技术架构最新进展

阿里技术

开源

携手共进丨九科信息入选信通院“铸基计划”高质量数字化转型产品及服务全景图,并受邀出席高质量数字转型创新大会

九科Ninetech

DevOps|研发效能不是老板工程,是开发者服务

laofo

DevOps cicd 研发效能 持续交付 平台工程

云智一体,深入生命科学

Baidu AICLOUD

基因测序 AI制药 AI for Science

华大北斗芯片亮相纽伦堡国际嵌入式展EW2023

江湖老铁

Notification(状态栏通知)详解

芯动大师

android Android Studio Notification

如何学习分布式系统,分布式是什么,这里有很好的解释,很全

三十而立

Java 分布式

Jetpack-Compose 学习笔记(二)—— Compose 布局你学会了么?

修之竹

android 前端 android jetpack

互联网工程师1000道Java面试题整理全集,助你一路绿灯

Java你猿哥

Java 面试 SSM框架 八股文 Java八股文

传统企业,如何构建性能测试技术体系

老张

技术 #性能测试

自己动手写虚拟机

ScratchLab

虚拟机 kvm

这六种目前最常见分布式事务解决方案!请拿走不谢

三十而立

Java 程序员 分布式 IT

SpringBoot 实现 MySQL 百万级数据量导出并避免 OOM 的解决方案

Java你猿哥

Java MySQL spring Spring Boot ssm

马士兵教育2023年全新Java架构师学习路线「首发版」

Java你猿哥

Java 学习 架构 面试 后端

战损版JavaAgent方法耗时统计工具实现

Java你猿哥

Java Spring Boot Java Agent ssm

焱融科技荣登《2022中国企业数智化创新TOP50》榜单

焱融科技

文件存储 分布式文件存储 数智化 高性能存储 全闪存储

一个小网站的云原生实践

松然聊技术

架构 云原生

2023金三银四Java高级工程师面试 1000 题+答案(全)

架构师之道

编程 程序员 java面试

浅析三款大规模分布式文件系统架构设计

Java你猿哥

架构 分布式 架构设计 分布式架构 系统架构设计手册

牧云助手:一款面向技术爱好者的远程主机管理工具

百川云开发者

运维 主机管理 终端远程协助

Java实战干货|Spring Boot整合MyBatis框架快速实现数据操作

三十而立

Java spring springboot

三天吃透Spring Cloud面试八股文

程序员大彬

Java 面试 SpringCloud

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