【Twelve-factor methodology】项目开发12因素方法论

 

       现如今软件会作为一种服务来交付,被称为网络应用服务或软件即服务(Saas)。12-Factor为构建SaaS应用提供了方法论:

·     使用标准化流程自动配置,从而使新开发者花费最少的学习成本加入此项目。

·     和操作系统之间尽可能的划清界限,在各个系统中提供最大的可移植性。

·     适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。

·     将开发环境和生产环境的差异降至最低,并使用持续交付实施敏捷开发。

·     可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。

       12-Factor应用程序是一组用于创建应用程序的最佳实践,包括实施,部署,监视和管理。 这是一种定义服务应遵循的12-Factor的方法,以便为云环境构建可移植,灵活的应用程序。 提供软件即服务(SaaS)的Web应用程序通常被视为12-Factor应用程序的常见示例。它已经成为衡量组件的关键标准,以确定它们是否真正为云原生部署做好了准备。

       12-Factor应用程序可以用任何编程语言实现,并使用任何支持服务,如数据库,消息传递和缓存。12-Factor应用程序具有开发个人微服务的理想特性。12个因素确保应用程序可以利用云基础架构来提供灵活性和可伸缩性优势。它通常用于为构建为微服务的应用程序定义适当的特性。使用微服务方法构建的应用程序通常需要与微服务架构之外的数据源集成。

==================12-Factor =====================

1.   Codebase(代码库/基准代码):在版本控制中一份基准代码,多份部署。

2.   Dependencies(依赖):显式声明和隔离依赖

3.   Config(配置):在环境中存储配置

4.   Backing services(支持服务):将支持服务视为附加资源

5.   Build, release, run(构建-发布-运行):严格分离构建和运行阶段

6.   Processes(进程):将应用程序作为一个或多个无状态进程执行

7.   Port binding(端口绑定):通过端口绑定钩子/导出服务

8.   Concurrency(并发):通过进程/流程模型扩展

9.   Disposability(易处理性):通过快速启动和正常关闭最大限度地提高稳健性

   10. Dev/prod parity(开发和生产等价):尽可能的保持开发,预发布,线上环境相同

   11.Logs(日志):将日志视为事件流

   ==Admin processes(管理进程):将管理/管理任务作为一次性进程运行

 

下面进一步介绍每个Factor:

A. Codebase代码库/基准代码

       为应用程序中的所有代码使用一个代码库,该代码存储在修订(revision control system)控制系统中,支持许多部署。 例如,部署单元可以是Docker容器,CloudFoundry应用程序或由Helm图表组成的TAR文件。每个微服务应该有自己的项目,有主分支和成员资格,但都应该存储在同一个存储库中。Gradle/Jenkins
 

B. Dependencies依赖

        开发人员常见的问题:显式声明和依赖隔离。构建包可以处理许多这些依赖项目,永远不要依赖系统范围的依赖。以下是典型的语言特定配置:

语言

包管理工具

对应文件

Python

Pip

常见为requirement.txt

Java

Gradle/Maven/Ant

Groovy/POM/build.xml

JavaScript

Npm/Grunt

Package.json/Gruntfile.js

Ruby

RubyGem

.gemspec/Rakefile

前端lib

Bower

bower.json

C++

Cpm

欢迎补充

Perl

Cpan

欢迎补充

PHP

Composer

欢迎补充

 

C.  Configuration配置

      将配置存储在环境中,配置可以更改并且可以有效地跟踪更改。使相同的代码部署到不同的环境:1.在环境中存储配置;2. 从源代码分离配置。配置信息可能包括:

·     处理数据库的资源以及其他支持服务;

·     外部资源的权限问题;

·     每次部署的值(例如主机名、端口等);

·     任何可能在部署之间变化的事情(dev/test/stag/prod);

将配置存储在环境中,切勿存储在以下位置:

·     代码

·     属性文件(通常被认为是代码的一部分)

·     构建(一个构建,多个部署)

·     应用服务器(如JNDI数据源)

       针对K8s将要部署的容器化app的配置存储在YAML文件中,除其他外,YAML文件指定副本集,网络和运行状况检查。同样,容器配置是部署app的一部分,可以在源代码管理中为部署文件管理它。如Nginx的Helm values.yaml文件。

D. Backing Services 支持服务

      支持服务被视为附加资源,它们可能运行在同一台计算机、不同的计算机或第三方主机上。应该同等看待本地和远程资源,可以将以下支持服务视为附加资源:

1.   Database:数据库

2.   Messaging Systems:消息系统

3.   LDAP Servers :LDAP服务器

4.   其他

E.  Build, Release, Run 构建/发布/运行

Codebase(代码库)通过三个阶段转换为(非开发)部署:

1.   Build(构建阶段):所谓的build:是将代码repo转换为可执行的bundle。在部署过程中指定的提交中使用代码版本,构建阶段获取依赖项并编译二进制文件和assets。

2.   Release(发布阶段):获取build阶段生成的构建,并将其与部署的当前配置相结合。生成的版本包含构建和配置,可以在执行环境中立即执行。

3.   Run(运行阶段):通过针对选定版本启动一组应用程序进程,在执行环境中运行应用程序。运行时代码不应该是可修改的,因为无法回滚更改到build阶段。

F.  Processes(进程):以一个或多个无状态进程运行app

     这是构建真正意义上的可扩展、分布式以及云部署app的必知。因为特定进程咩有状态,所以如果丢失进程则无关紧要。因为The traffic(流量)会自动无缝地路由到可以处理该工作的环境中的其他进程。贴心小提示:

1.   不要依赖session affinity/sticky sessions(自己YY)

2.   将状态存储在进程外部的有状态支持服务中

运行时应该是无状态的,但服务可以或确实具有状态。流程图如下:

【Twelve-factor methodology】项目开发12因素方法论_第1张图片

 

       上图中描述了状态如何你存储在服务中并传递到运行时。运行时使用足够长的状态来执行一个工作单元然后将其抛弃。运行时不保持工作单元之间的状态。下面介绍一下app状态的一些关键细节:

1.   服务状态:数据传递到无状态的服务

其范围:交易或工作单元;例如服务操作参数

2.   会话状态:用户会话历史数据

其范围:会议session;例如HTTP会话

3.   Domain状态/域名状态:可用于多个或所有服务的数据

其范围:Global;例如企业DB的记录

【用法】

Client填充来自会话状态的服务状态,服务状态通常包含用于检索域名状态的密钥。

G.Port Binding端口绑定:暴露端口提供服务

       操作和部署模型通常会为开发人员处理此操作,但开发人员需要确保他们不会对端口值进行硬编码。 应用程序应该能够运行并连接到服务,而无需手动指定配置值。

 H.Concurrency 并发:使用process model 向外扩展—水平缩放

其中注意事项如下:

1.  向外扩展而不是向上扩展

2.  要添加容量,请运行更多实例

3. 单个进程可以扩展到多远时有限的

4.  无状态apps使扩展简单

=============【Vertical VS Horizontal】============

    通过vertical  scaling/垂直扩展,可以运行更多app实例。一个运行时运行更多实例,因此运行时需要更多的CPU和内存,这使得它变得臃肿,并且所有CPU和内存都必须属于单个主机。

    通过horizontal scaling/水平扩展,可以运行更多app实例并运行更多运行时,从而使每个运行时保持相同的大小。更多的运行时仍然需要更多的CPU和内存,但它们可以分布在多个主机上,因此所有CPU和内存都不需要属于单个主机。如下图:

【Twelve-factor methodology】项目开发12因素方法论_第2张图片

 

==============================================

I. Disposability易处理性:确保进程快速启动并正常关闭

      处理器应该立即启动,当关闭时不需要额外的工作就可以关闭。其中需要主要的事项:

       1. app instances是一次性的(disposable)

       2. apps 应通过crash-only设计处理关机信号或硬件故障

       3. 容器是基于可出执行原则构建的

        failover(故障转移)是指不要依赖运行时并不意味着用永远持续下去。运行时是不可变的(immutable),因此每个运行时都其他运行时一样。根据需要添加或移除获得弹性(elasticity),如果一个app宕掉或有问题,杀死并start另一个。如下图:

【Twelve-factor methodology】项目开发12因素方法论_第3张图片

J. Development and production parity: 环境平等

        确保development、staging和production环境尽可能相似。这个原理与Agile Software Delivery、Continuous Integration和Continuous Deployment相关,不希望开发或生产环境上过于同步以至于不能反映彼此,只是相似而已。其中需要注意的事项:

       1. 在每个环境中使用相同的支持服务,例如支持服务、工具以及平台

    2.最小化不兼容的元素(Minimize incompatibleelements across)

K. Logs: 日志---将日志视为事件流

       App不会写入或管理日志文件。如果环境中没有正确的telemetry/遥测,就不知道发生了什么。当出现复杂问题时,可能难以修复和理解。因此每个进程都写入stdout。注意事项如下:

1. Apps不应写入专门的日志文件(specialized log files)

2. 环境决定如何收集、聚合和保留stdout输出

     例如:日志工具ELK堆栈(Elasticsearch,Logstash和Kibana)就是是包含流式,存储,搜索和监视日志。

 L. Admin Processes: 设置管理或管理任务流程,甚至是one-off

        不要创建可能重复多次的管理进程,这些进程没有很好地封装为代码本身。创建一个流程非常重要,即使它是一个完成特定任务的一次性流程。管理进程的示例:

·     Migrate a database 迁移数据库

·     创建一个SQL DB

    1.用于创建schema的DDL脚本

    2.用于初始数据的SQL脚本

    3.作为创建数据库的一部分运行这些脚本的脚本

·     Migrate data to new schema 将数据迁移到schema

·     调试

        当执行一次性管理任务时,不要假设它只是一次性的。假设您需要在每个环境(如Dev,Test和Prod)或每个部署中运行一次,或者每次出现问题时都会出现问题。因为您需要重复运行它,所以通过将其变成脚本或程序,可以轻松地重复它。

       该可执行文件可以使用单个命令运行,维护以使其保持工作,存储在源代码管理中,版本化并与其他开发人员和管理员共享。即使它只使用过一次,至少有记录做了什么。

 

=====================总结======================

【Twelve-factor methodology】项目开发12因素方法论_第4张图片

 

你可能感兴趣的:(架构师,Devops)