这 12 项基本原则能够帮助团队快速高效地构建高度可扩展的应用程序
12-Factor 应用方法论为在短时间内构建应用程序并使其具有可扩展性提供了指导。它由 Heroku 的开发人员创建,用于软件即服务(SaaS)应用程序、网络应用程序以及可能的通信平台即服务(CPaaS)。在有效组织项目和管理可扩展应用程序方面,12 要素应用程序方法论对开源开发具有强大的优势。
12-Factor 应用方法论的原则
12-Factor 应用方法论的规则非常严格,也是开发和部署 SaaS 应用程序的基石,并且不受任何编程语言或数据库的限制。
1:一份基准代码,多份部署
每个应用程序都应该有一个具有多个不同环境/部署的代码库。
开发人员不应仅仅为了在不同环境中设置而开发另一个代码库。不同的环境代表不同的状态,但这些不同的环境应该共享同一个代码库。
在许多开源项目都存储在 GitLab 这样的版本控制系统中的情况下,一个环境可以被视为一个分支。例如,你可以在任何中央版本控制系统中为名为 VoIP-app 的云 VoIP 应用程序创建一个单独的存储库,然后创建两个分支:开发分支(development
)和暂存分支(staging
),并将主分支(master
)作为发布分支。
2:明确声明和隔离依赖关系
应声明所有依赖关系。你的应用程序可能会依赖外部系统工具或库,但不应对系统工具或库有任何 隐含的依赖。你的应用程序必须始终明确声明所有依赖关系及其正确版本。
在代码库中包含依赖关系可能会产生问题,特别是在开源项目中,外部库的更改可能会将错误引入代码库。例如,代码库可能会使用一个外部库,但没有明确声明该依赖关系或版本。如果外部库更新到更新的、未经测试的版本,这可能会与你的代码产生兼容性问题。如果明确声明了依赖关系及其正确版本,你的代码库就不会出现这种问题。
根据技术栈的不同,最好使用软件包管理器,通过读取代表依赖库名称和版本的依赖库声明清单,在各自的系统上下载依赖库。
3:在环境中存储配置
当需要支持多个环境或客户端时,配置就成了应用程序的重要组成部分。不同部署之间的配置应存储在环境变量中。这样就可以在部署之间轻松更改配置,而无需更改代码。
对于闭源应用程序来说,这一原则是有益的,因为你不会希望数据库连接信息或其他秘密数据等敏感信息被公开。然而,在开放源代码开发中,这些细节都是公开的。在这种情况下,好处是你不需要反复修改代码。你只需这样设置变量,只需改变环境,就能让代码完美运行。
4:把后端服务当作附加资源
所有后备服务(如数据库、外部存储或消息队列)都被视为附加资源,由执行环境附加或分离。根据这一原则,如果这些服务的位置或连接细节发生变化,仍无需更改代码。这些细节可以在配置中找到。
备份服务可以从部署中快速附加或分离。例如,如果基于云的电子表格的数据库无法正常工作,开发人员应该能够创建一个从最近备份恢复的新数据库服务器,而无需对代码库进行任何更改。
5:严格分离构建和运行
12-Factor 应用方法论要求严格区分构建、发布和运行阶段。
- 第一阶段是 构建阶段。在这一阶段,源代码被组装或编译成可执行文件,同时加载依赖关系并创建资产。每次需要部署新代码时,构建阶段就会开始。
- 第二阶段是 发布阶段。在此阶段,构建阶段生成的代码与部署的当前配置相结合。最终发布的版本包含构建和配置,可在执行环境中立即执行。
- 第三个阶段是 运行阶段,也是最后阶段:应用程序在执行环境中运行。该阶段不应被其他任何阶段打断。
通过严格区分这些阶段,我们可以避免代码中断,使系统维护更加易于管理。
6:以一个或多个无状态进程运行应用
应用程序作为一个或多个进程的集合在执行环境中执行。这些进程是无状态的,其持久化数据存储在数据库等后台服务中。
这对开源非常有用,因为使用某版本应用程序的开发人员可以在其云平台上创建多节点部署,以实现可扩展性。数据不会在其中持久化,因为如果其中任何一个节点崩溃,数据就会丢失。
7:通过端口绑定提供服务
你的应用程序应作为独立的服务,独立于其他应用程序。它它应该能通过URL供其他服务访问,以服务形式存在。这样,你的应用程序就可以在需要时作为其他应用程序的资源。利用这一概念,你可以构建 REST API。
8:通过进程模型进行扩展
该原则也称为并发原则,它表明应用程序中的每个进程都应能够自我扩展、重启或克隆。
开发人员可以创建多个进程,并将应用程序的负载分配给这些进程,而不是将一个进程变大。通过这种方法,你可以将每种工作负载分配给一个进程类型,从而构建能处理不同工作负载的应用程序。
9:快速启动和优雅终止以增强健壮性
你的应用应当基于简单的进程构建,因此开发者可以放大进程的同时还能在发生问题时重启它们。这使得应用的进程易于丢弃。
根据这一原则构建应用程序意味着代码的快速部署、快速弹性扩展、更灵活的发布流程以及稳健的生产部署。所有这些在开源开发环境中都非常有用。
10:尽可能的保持开发、预发布、生产环境相同
同一项目的团队应使用相同的操作系统、支持服务和依赖关系。这样可以降低出现错误的可能性,减少开发所需的时间。
由于开源项目的开发人员分散在各地,他们可能无法就所使用的系统、服务和依赖关系进行 沟通,因此将这一原则付诸实践对于开源项目来说可能是一个挑战。减少这些差异的一种可能性是制定开发指南,建议使用何种操作系统、服务和依赖关系。
11:把日志当作事件流
日志对于排除生产问题或了解用户行为至关重要。但是,12-Factor 应用方法论并不适合处理日志的管理。
相反,应将日志条目作为事件流,写入标准输出,并将其发送到单独的服务进行分析和存档。机器人流程自动化(RPA)技术可作为处理和分析日志的第三方服务。执行环境将决定如何处理该数据流。这为反省应用程序的行为提供了更大的灵活性和能力。
12:后台管理任务当作一次性进程运行
这一原则实际上与开发无关,而是与应用程序管理有关。管理进程应在与应用程序常规长期运行进程相同的环境中运行。在本地部署中,开发人员可以直接使用应用程序签出目录内的 Shell 命令来执行一次性管理进程。
结论
使用 12-Factor 应用方法论开发应用程序,可以提高效率,加快发布速度。在开源开发中,偏离某些指导原则可能是有意义的,但最好还是尽可能严格遵守这些指导原则。
开源的 12-Factor 应用是可能的。一个很好的例子是 Jitsi, (一个开源视频会议平台), 在疫情期间扩展了 100 倍的规模,取得了巨大成功,它就是采用 12-Factor 应用方法论构建的。