Twelve-Factor简介
如今,软件通常会作为一种服务来交付,被称为网络应用程序,或软件即服务(SaaS)。12-Factor
为构建如下的 SaaS 应用提供了方法论:
- 使用标准化流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目。
- 和操作系统之间尽可能的划清界限,在各个系统中提供最大的可移植性。
- 适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。
- 将开发环境和生产环境的差异降至最低,并使用持续交付实施敏捷开发。
- 可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。
12-Factor
综合了 SaaS
应用的经验和智慧,是开发此类应用的理想实践标准,并特别关注于应用程序如何保持良性成长,开发者之间如何进行有效的代码协作,以及如何避免软件污染。
1. Codebase 基准代码
每个应用只对应一份基准代码,但可以同时存在多份部署。每份 部署 相当于运行了一个应用的实例。
- 一旦有多个基准代码,就不能称为一个应用,而是一个分布式系统。分布式系统中的每一个组件都是一个应用,每一个应用可以分别使用 12-Factor 进行开发。
- 多个应用共享一份基准代码是有悖于 12-Factor 原则的。解决方案是将共享的代码拆分为独立的类库,然后使用 依赖管理 策略去加载它们。
2. Dependencies 显式声明依赖
12-Factor规则下的应用程序不会隐式依赖系统级的类库。 它一定通过 依赖清单
,确切地声明所有依赖项。此外,在运行过程中通过 依赖隔离
工具来确保程序不会调用系统中存在但清单中未声明的依赖项。
例如, Ruby 的 Bundler 使用 Gemfile 作为依赖项声明清单,使用 bundle exec 来进行依赖隔离。Python 中则可分别使用两种工具 – Pip 用作依赖声明, Virtualenv 用作依赖隔离。甚至 C 语言也有类似工具, Autoconf 用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足 12-Factor 规范。
12-Factor 应用同样不会隐式依赖某些系统工具,如 ImageMagick 或是curl。
3. Config 配置管理
配置 在不同 部署 (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括:
- 数据库,Memcached,以及其他 后端服务 的配置
- 第三方服务的证书,如 Amazon S3、Twitter 等
- 每份部署特有的配置,如域名等
实践原则:
- 代码和配置严格分离
- 推荐将应用配置存储于
环境变量
中 - 对于Linux系统,可使用
systemd
, 定义 unit 文件,统一管理每个应用的环境变量
4. Backing Services 后端服务
后端服务
是指程序运行所需要的通过网络调用的各种服务,如数据库(MySQL,CouchDB),消息/队列系统(RabbitMQ,Beanstalkd),SMTP 邮件发送服务(Postfix),以及缓存系统(Memcached)。
12-Factor 应用不会区别对待本地或第三方服务。 对应用程序而言,两种都是附加资源,通过一个 url 或是其他存储在 配置 中的服务定位/服务证书来获取数据。
部署可以按需加载或卸载资源。例如,如果应用的数据库服务由于硬件问题出现异常,管理员可以从最近的备份中恢复一个数据库,卸载当前的数据库,然后加载新的数据库 – 整个过程都不需要修改代码。
5. Build, Release, Run 构建,发布,运行
12-factor 应用严格区分构建,发布,运行这三个步骤。 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。
6. Processes 无状态进程
运行环境中,应用程序通常是以一个和多个 进程 运行的。
12-Factor 应用的进程必须无状态且 无共享 。 任何需要持久化的数据都要存储在 后端服务 内,比如数据库。
7. Port Binding 端口绑定
互联网应用 通过端口绑定来提供服务 ,并监听发送至该端口的请求。
端口绑定这种方式也意味着一个应用可以成为另外一个应用的 后端服务
,调用方将服务方提供的相应 URL 当作资源存入 配置 以备将来调用。
8. Concurrency 并发
12-Factor 应用的进程主要借鉴于 unix 守护进程模型 。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 进程类型 。
12-Factor 应用的进程 不需要守护进程 或是写入 PID 文件。相反的,应该借助操作系统的进程管理器(例如 systemd ,分布式的进程管理云平台,或是类似 Foreman 的工具),来管理 输出流 ,响应崩溃的进程,以及处理用户触发的重启和关闭超级进程的请求。
9. Disposability 易处理
12-Factor 应用的 进程 是 易处理(disposable)的,意思是说它们可以瞬间开启或停止。
进程应当追求 最小启动时间 。
旦接收 终止信号(SIGTERM) 就会优雅的终止 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请进程 一旦接收 终止信号(SIGTERM) 就会优雅的终止 。就网络进程而言,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的请求,然后退出。
10. Dev/Prod Parity 开发与生产环境等价
时间差异: 开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。
人员差异: 开发人员编写代码,运维人员部署代码。
工具差异: 开发人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以及 Linux。
后端服务 是保持开发与线上等价的重要部分,例如数据库,队列系统,以及缓存。许多语言都提供了简化获取后端服务的类库,例如不同类型服务的 适配器
11. Logs 日志
把日志当作事件流
在基于服务器的环境中,日志通常被写在硬盘的一个文件里,但这只是一种输出格式。
在预发布或线上部署中,每个进程的输出流由运行环境截获,并将其他输出流整理在一起,然后一并发送给一个或多个最终的处理程序,用于查看或是长期存档。这些存档路径对于应用来说不可见也不可配置,而是完全交给程序的运行环境管理。类似 Logplex 和 Fluentd 的开源工具可以达到这个目的。
这些事件流可以输出至文件,或者在终端实时观察。最重要的,输出流可以发送到 Splunk 这样的日志索引及分析系统,或 Hadoop/Hive 这样的通用数据存储系统。这些系统为查看应用的历史活动提供了强大而灵活的功能,包括:
找出过去一段时间特殊的事件。
图形化一个大规模的趋势,比如每分钟的请求量。
根据用户定义的条件实时触发警报,比如每分钟的报错超过某个警戒线。
Admin Processes 管理进程
开发人员经常希望执行一些管理或维护应用的一次性任务。
一次性管理进程应该和正常的 常驻进程 使用同样的环境。
12-factor 尤其青睐那些提供了 REPL shell 的语言,因为那会让运行一次性脚本变得简单。
THE TWELVE-FACTOR APP: https://12factor.net/zh_cn/
云原生架构设计方法论——12因素应用程序图解,12 Factor: https://zhuanlan.zhihu.com/p/452532308
如何读取环境变量值?Go 每日一库之 godotenv http://www.taodudu.cc/news/show-4313615.html?action=onClick