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(转载)

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
内部云存储架构在企业中的作用
云存储的地位开始稳固,逐渐走出推广期和早期应用期,进入真正的市场。我们预计云存储结构的应用将开始从外部供应商使用的时期向IT组织想要使用的时期转变。 云存储这个词确实使用得过于频繁了,好像存储厂商发布的所有新产品都跟云有关。 虽然那些产品被厂商称作云存储,但是那并不表示它们就是云存储产品。 云存储是一个含义非常广泛的术语,它通常指的是一个可调性很强、可以配置为内部或外部使用、通常会使用某种形式的群集或网格存储设备的存储系统。它或许会有很多功能,或许功能也不是很多。 这些功能的重要性可能会随着用户的不同而不同,但是它们并非云存储系统所必须的功能。事实上,可能没有一种结构可能被作为云存储的参考结构,就好像没有一种结构可被作为实现SAN或NAS的最佳方案的参考一样。 当你需要解决具体问题时,内部云存储结构就发挥出作用了。用户在使用云存储的时候,它们是想解决性能需求、处理大量数据增长、IT员工工作负荷太重和削减存储成本等问题。 每一个企业或组织对于这些问题的考虑权重都不同,它们会选择能够解决具体问题的最佳方案。上述问题的重要性权重对于不同的企业是不同的。 如果是次要数据,那么成本和可调整性或许...
- 下一篇
Spark和Hadoop分析遇障碍?可以试试容器啊
将定制的Spark和Hadoop试点项目转移到生产中是一项艰巨的任务,但容器技术缓解了这种艰难的过渡。 当团队试图将小型试点项目转变为面向数据科学团队和业务分析人员的大型运营应用程序时,Spark和Hadoop分析工作往往会遇到困难。对于许多人来说,这是他们在大数据分析之路上遇到的最大障碍。 配置的复杂性有时候也是绊脚石。由一个单独的数据科学家构建的自定义配置的原型可能需要很长的时间来重新创建,一旦失败,是由一个更广泛的用户池共享。为了解决这些问题,一些人利用DevOps型容器和微服务技术将Spark和Hadoop组件衔接在一起。 “我们的数据科学团队和业务利益相关者不希望等待过长的时间,等我们建立一个新的Spark集群或其他大型数据环境,并提供所需的所有工具、版本、配置和数据,” 为医疗机构提供分析和咨询服务的公司董事Ramesh Thyagarajan说道。他将Docker容器视为在大数据科学家和企业用户上实现敏捷性的关键技术。 为了将这种DevOps风格部署到其大数据应用程序,咨询委员会正在使用BlueData Software的EPIC软件平台来运行Spark SQL和Spar...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS关闭SELinux安全模块
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2整合Redis,开启缓存,提高访问速度