Saas 应用12个架构规范( 二 )


12-Factor 应用不会区别对待本地或第三方服务 。 对应用程序而言,两种都是附加资源,通过一个 url 或是其他存储在 配置 中的服务定位/服务证书来获取数据 。12-Factor 应用的任意 部署,都应该可以在不进行任何代码改动的情况下,将本地 MySQL 数据库换成第三方服务(例如 Amazon RDS) 。类似的,本地 SMTP 服务应该也可以和第三方 SMTP 服务(例如 Postmark )互换 。上述 2 个例子中,仅需修改配置中的资源地址 。
12-Factor 应用将这些都视作 附加资源,这些资源和它们附属的部署保持松耦合 。

Saas 应用12个架构规范

文章插图
 
构建,发布,运行严格分离构建和运行
基准代码 转化为一份部署(非开发环境)需要以下三个阶段:
构建阶段 是指将代码仓库转化为可执行包的过程 。构建时会使用指定版本的代码,获取和打包 依赖项,编译成二进制文件和资源文件 。
发布阶段 会将构建的结果和当前部署所需 配置 相结合,并能够立刻在运行环境中投入使用 。
运行阶段 (或者说“运行时”)是指针对选定的发布版本,在执行环境中启动一系列应用程序 进程 。
Saas 应用12个架构规范

文章插图
 
12-factor 应用严格区分构建,发布,运行这三个步骤 。 举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤 。
每一个发布版本必须对应一个唯一的发布 ID,例如可以使用发布时的时间戳(2011-04-06-20:32:17),亦或是一个增长的数字(v100) 。发布的版本就像一本只能追加的账本,一旦发布就不可修改,任何的变动都应该产生一个新的发布版本 。这样也便于回退到任意历史版本,而不需要冒风险重新构建 。
新的代码在部署之前,需要开发人员触发构建操作 。但是,运行阶段不一定需要人为触发,而是可以自动进行 。如服务器重启,或是进程管理器重启了一个崩溃的进程 。因此,运行阶段应该保持尽可能少的模块,这样假设半夜发生系统故障而开发人员又捉襟见肘也不会引起太大问题 。构建阶段是可以相对复杂一些的,因为错误信息能够立刻展示在开发人员面前,从而得到妥善处理 。
进程以一个或多个无状态进程运行应用
运行环境中,应用程序通常是以一个和多个 进程 运行的 。
12-Factor 应用的进程必须无状态且 无共享。 任何需要持久化的数据都要存储在 后端服务 内,比如数据库 。
内存区域或磁盘空间可以作为进程在做某种事务型操作时的缓存,例如下载一个很大的文件,对其操作并将结果写入数据库的过程 。12-Factor应用根本不用考虑这些缓存的内容是不是可以保留给之后的请求来使用,这是因为应用启动了多种类型的进程,将来的请求多半会由其他进程来服务 。即使在只有一个进程的情形下,先前保存的数据(内存或文件系统中)也会因为重启(如代码部署、配置更改、或运行环境将进程调度至另一个物理区域执行)而丢失 。
一些系统依赖于 “粘性 session”,这是指将用户 session 中的数据缓存至某进程的内存中,并将同一用户的后续请求路由到同一个进程 。粘性 session 是 12-Factor 极力反对的 。Session 中的数据应该保存在诸如 Memcached 或 redis 这样的带有过期时间的缓存中 。
端口绑定通过端口绑定(Port binding)来提供服务
应用有时会运行于服务器的容器之中 。例如 php 经常作为 Apache HTTPD 的一个模块来运行,正如 Java 运行于 Tomcat。
12-Factor 应用完全自我加载 而不依赖于任何网络服务器就可以创建一个面向网络的服务 。互联网应用 通过端口绑定来提供服务 ,并监听发送至该端口的请求 。
还要指出的是,端口绑定这种方式也意味着一个应用可以成为另外一个应用的 后端服务,调用方将服务方提供的相应 URL 当作资源存入 配置 以备将来调用 。
并发通过进程模型进行扩展
在 12-factor 应用中,进程是一等公民 。12-Factor 应用的进程主要借鉴于 unix 守护进程模型。开发人员可以运用这个模型去设计应用架构,将不同的工作分配给不同的 进程类型。例如,HTTP 请求可以交给 web 进程来处理,而常驻的后台工作则交由 worker 进程负责 。
上述进程模型会在系统急需扩展时大放异彩 。12-Factor 应用的进程所具备的无共享,水平分区的特性 意味着添加并发会变得简单而稳妥 。这些进程的类型以及每个类型中进程的数量就被称作 进程构成。


推荐阅读