12要素应用

2012 年,Heroku 创始人 Adam Wiggins 发布十二要素应用宣言,又被称为微服务十二要素。

内容

基准代码

  1. 一个应用一个代码仓库,不要出现一个代码仓库对应多个应用的情况
  2. 如果多个应用共享一份代码,那么需要将该代码拆分为独立的类库

依赖

规范:

  1. 应用必须通过配置显式声明出所有的依赖项,即使依赖的工具在所有的操作系统上都存在。比如 python 可以使用 pip 的 requirements.txt 文件声明出所有的依赖包及其版本信息。
  2. 在运行时需要通过隔离手段确保应用不会调用未显式声明的依赖项。比如 python 应用可以通过virtualenv 技术来确保隔离性。

优点:

  1. 简化开发者的环境配置,通过构建命令即可安装所有的依赖项。

配置

规范:

  1. 代码和配置单独管理,不要将配置放到代码仓库中管理。
  2. 配置传递给应用的方式之一为配置文件,另外一种为环境变量。

后端服务

规范:

  1. 后端服务分为本地服务和第三方服务,对应用而言都是后端服务,不应该区别对待。

构建、发布和运行

规范:

  1. 严格区分从代码到部署的三个阶段:构建编译打包代码;将构建结果和部署需要的配置放到环境中;指定发布版本,在环境中启动应用。
  2. 每个发布版本必须对应一个唯一的 id 标识。

反模式:

  1. 不可以直接修改环境中的代码,可能会导致非常难同步会构建步骤。

进程

规范:

  1. 应用的进程需要持久化的数据一定要保存到后端服务中,保持应用进程的无状态。
  2. 本地的内存和磁盘可以作为应用的缓存数据。
  3. 反对使用基于 session 的粘滞技术(某一个用户的请求通过一致性 hash 等技术请求到同一个后端服务,而后端服务将用户数据缓存在内存中),推荐将用户数据缓存到Redis 等分布式缓存中。很多互联网公司都会采用 session 粘滞技术,都违背了这一原则。

端口绑定

要求应用自己通过监听端口的方式来对外提供服务。

并发

规范:

  1. 允许通过多进程或者多线程的方式来处理高并发
  2. 应用不需要守护进程或者写入 PID 文件,可以借助如 systemd 等工具来实现。

易处理

规范:

  1. 进程启动速度尽可能快,以便于更好的支持弹性伸缩、部署应用。
  2. 进程在接收到SIGTERM 信号后需要优雅停止。比如对于 nginx 而言,要等到处理完所有的连接后才可以退出。
  3. 进程要能够处理各种异常情况。

开发环境与生产环境等价

核心就只有一点,尽可能保证开发环境与生产环境的一致性。

日志

规范:

  1. 应用程序将日志直接输出到标准输出,标准输出的内容由日志收集程序消费。

反模式:

  1. 现实中应用程序将日志直接写到了日志文件,并且自己来管理日志文件。

管理进程

规范:

  1. 仅需要执行一次的进程,跟普通的进程一样的管理思路,比如版本、执行环境等。

参考