本文部分内容引用自https://12factor.net/zh_cn/。
12-factors目的是分享现代软件开发过程中发现的一些系统性问题,并这些问题进行抽象出的一套方法论。
基于这些方法论,开发出的应用程序,更容易和当前基于Kubernetes的云原生生态相结合。
12-FACTORS
1基准代码
一份基准代码、多份部署
基准代码和应用之间总是保持一一对应的关系。每个应用只对应一份基准代码。
微小的差异可以通过branch或者tag来进行区分。
这样做是为了方便后面当某一应用版本出现问题,方便定位和去修改。
2依赖
显式声明依赖关系
显式声明依赖为新加入的开发者简化了环境配置流程。新入开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,并且只需要通过一个构建命令来安装所有的依赖,即可开始工作。
可以提供类似makefile的文件以及deploy目录来描述构建,部署相关说明。
3配置
在环境中存储配置
通常应用的配置在不通部署环境(开发,预发布,生产等)会有很大差异。这其中包括
- 数据库等中间件以及其他后端服务的配置
- 第三方服务证书
- 每份部署特有配置,如域名等。
应用添加配置的方法大概有三种: - 常量
- 配置文件
- 环境变量(env)推荐这种,可以非常方便的在不同部署之间做修改,不用改动一行代码;比配置文件的优点是不小心把他们放入代码库概率低,并与语言无关。
4后端服务
把后端服务当做附加资源
后端服务指的是程序运行所需要的通过网络调用的各种服务,如数据库(mysql,redis,mongodb,es等)、消息队列系统、SMTP邮件发送服务,缓存系统。
12factor不会区分本地或第三方服务,每个不同的后端服务都是一份资源。部署可以按需加载和卸载资源。eg:当应用的数据库由于硬件问题出现故障,管理员可以从最近的悲愤中恢复一个数据库,卸载当前数据库,然后加载新的数据库,整个过程都不需要修改代码。
5构建、发布、运行
严格分离构建和运行
基准代码到上线部署(非开发环境)需要以下三个阶段:
- 构建阶段 将代码仓库转换为可执行包的过程,构建时会使用指定版本代码,获取和打包依赖项,编译成二进制文件和资源文件
- 发布阶段 将构建结果和当前部署所需要的配置相结合,并能够立即在运行环境中投入使用。
- 运行阶段 针对选定的发布版本,在执行环境中启动一系列应用程序进程。
12factor应用严格区分构建、发布、运行这三个步骤。每一个发布版本必须对应一个唯一的发布ID,新的代码在部署之前,需要开发人员触发构建操作。便于早先发现问题。
6进程
以一个或多个无状态进程运行应用
运行环境中,应用程序通常是以一个和多个进程运行的。
12-factor应用的进程必须无状态且无共享。任何需要持久化的数据都要存储在后端服务中。
过去Java web应用的session存储在服务器端,这些粘性session是12-factor反对的。session的数据应该存储在类似redis这样的带有过期时间的缓存中。
7端口绑定
通过端口绑定提供服务
互联网应用有时会运行于服务器的容器之中。例如Java应用运行于Tomcat。
12factor应用完全自我加载而不依赖任何网络服务器就可以创建一个面向网络的服务。互联网应用通过端口绑定来提供服务,并监听发送至该端口的请求。
8并发
通过进程模型进行扩展
任何计算机程序,一旦启动,就会生成一个或多个进程。进程是开发人员可操作的最小单位。
12factor应用中,进程是一等公民。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的进程类型。eg: http请求可以交给web进程来处理,而常驻的工作进程则交给worker来负责。类似java netty的线程模型。
9易处理
快速启动和优雅终止可最大化健壮性
12factor应用的进程是易处理的,意思是他们可以瞬间开启或停止的。这有利于快速,弹性的伸缩应用。迅速部署变化的代码或配置,稳健的部署应用。
进程一旦接收终止信号SIGTERM 就会优雅终止。 对于网络进程,优雅终止是指停止监听服务的端口,即拒绝所有新的请求,并继续执行当前已接收的哦请求,执行完成然后退出。
无论如何,对于12factor应用都应该涉及户能够应对意外的、不优雅的终结。
10开发环境与线上环境等价
尽可能的保持开发、预发布、线上环境相同
应用的所有部署,包括开发,预发布,以及线上环境,都应该使用同一个后端服务的相同版本。
利用一些CICD工具,打造可持续构建,可持续部署的工具流。
11日志
把日志当作事件流
日志使得应用程序运行的动作变得透明。在基于服务器的环境中,日志通常被写在硬盘的一个文件中,但这只是一种输出格式。
日志应该是事件流的汇总,将所有运行中进程和后端服务的输出流按照时间顺序收集起来。
利用ELK将日志采集采集,作为报警的一个指标。通过可视化界面更好的展示log,并方便的去发现问题。
12管理进程
后台管理任务当做一次性进程运行
进程构成是指用来处理应用的常规业务(比如处理web请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务。例如:
- 运行数据迁移
- 运行一个shell来执行一些脚本
在代码中应该将这些一次性进程脚本进行代码版本管理。并和发布一起。避免后面针对该版本的修改出现异常。