12要素应用
2012 年,Heroku 创始人 Adam Wiggins 发布十二要素应用宣言,又被称为微服务十二要素。
内容
基准代码
- 一个应用一个代码仓库,不要出现一个代码仓库对应多个应用的情况
- 如果多个应用共享一份代码,那么需要将该代码拆分为独立的类库
依赖
规范:
- 应用必须通过配置显式声明出所有的依赖项,即使依赖的工具在所有的操作系统上都存在。比如 python 可以使用 pip 的 requirements.txt 文件声明出所有的依赖包及其版本信息。
- 在运行时需要通过隔离手段确保应用不会调用未显式声明的依赖项。比如 python 应用可以通过virtualenv 技术来确保隔离性。
优点:
- 简化开发者的环境配置,通过构建命令即可安装所有的依赖项。
配置
规范:
- 代码和配置单独管理,不要将配置放到代码仓库中管理。
- 配置传递给应用的方式之一为配置文件,另外一种为环境变量。
后端服务
规范:
- 后端服务分为本地服务和第三方服务,对应用而言都是后端服务,不应该区别对待。
构建、发布和运行
规范:
- 严格区分从代码到部署的三个阶段:构建编译打包代码;将构建结果和部署需要的配置放到环境中;指定发布版本,在环境中启动应用。
- 每个发布版本必须对应一个唯一的 id 标识。
反模式:
- 不可以直接修改环境中的代码,可能会导致非常难同步会构建步骤。
进程
规范:
- 应用的进程需要持久化的数据一定要保存到后端服务中,保持应用进程的无状态。
- 本地的内存和磁盘可以作为应用的缓存数据。
- 反对使用基于 session 的粘滞技术(某一个用户的请求通过一致性 hash 等技术请求到同一个后端服务,而后端服务将用户数据缓存在内存中),推荐将用户数据缓存到Redis 等分布式缓存中。很多互联网公司都会采用 session 粘滞技术,都违背了这一原则。
端口绑定
要求应用自己通过监听端口的方式来对外提供服务。
并发
规范:
- 允许通过多进程或者多线程的方式来处理高并发
- 应用不需要守护进程或者写入 PID 文件,可以借助如 systemd 等工具来实现。
易处理
规范:
- 进程启动速度尽可能快,以便于更好的支持弹性伸缩、部署应用。
- 进程在接收到SIGTERM 信号后需要优雅停止。比如对于 nginx 而言,要等到处理完所有的连接后才可以退出。
- 进程要能够处理各种异常情况。
开发环境与生产环境等价
核心就只有一点,尽可能保证开发环境与生产环境的一致性。
日志
规范:
- 应用程序将日志直接输出到标准输出,标准输出的内容由日志收集程序消费。
反模式:
- 现实中应用程序将日志直接写到了日志文件,并且自己来管理日志文件。
管理进程
规范:
- 仅需要执行一次的进程,跟普通的进程一样的管理思路,比如版本、执行环境等。