十二要素应用: 云原生应用最佳实践

本文介绍了开发部署云原生应用的一套最佳实践,通过这套最佳实践,可以最大限度利用云原生的能力,创建灵活、健壮、易管理的现代云原生应用程序。原文: The Twelve-Factor App: Best Practices for Cloud-Native Applications[1]

alt
导言

软件如今通常以服务的形式交付,被称为网络应用(web apps)软件即服务(software-as-a-service),而十二要素应用(The twelve-factor app)就是构建软件即服务应用的一种方法。

十二要素应用是Heroku联合创始人亚当·威金斯(Adam Wiggins)在2012年的一篇题为"十二要素应用:云原生应用的最佳实践(The Twelve-Factor App: Best Practices for Cloud-Native Applications)"的开创性论文中提出的,该方法源自Heroku部署及运营基于云的应用程序所获得的经验和见解。

十二要素应用的主要目标是提供一种标准化的方法,用于开发可在云原生环境中运行的应用程序,同时保持灵活性、健壮性和易管理性。

十二要素应用方法论为我们提供了一套最佳实践,用于构建符合如下要求的现代云原生应用程序:

代码库(Codebase)

  • 在版本控制系统中跟踪代码库。
  • 多个部署共享同一个代码库。

依赖(Dependencies)

  • 显式声明并隔离依赖。
  • 避免依赖全局范围的包。

配置(Config)

  • 将配置存储在环境中。
  • 将配置与代码分离。

后端服务(Backing Services)

  • 将后端服务(数据库、缓存)视为附加资源。
  • 通过环境变量访问。

构建、发布、运行(Build, Release, Run)

  • 严格隔离构建、发布和运行阶段。
  • 保持构建和发布的不可变性。

进程(Processes)

  • 以无状态进程的方式执行应用程序。
  • 在数据库或外部服务中存储共享状态。

端口绑定(Port Binding)

  • 通过端口绑定导出服务。
  • 保持应用程序的独立。

并发性(Concurrency)

  • 通过进程模型进行扩展。
  • 启用水平缩放。

可处置性(Disposability)

  • 通过快速启动和优雅关机最大限度提高鲁棒性。
  • 目标是快速启动并优雅处理流程故障。

研发/生产环境一致(Dev/Prod Parity)

  • 尽可能保持开发、预发布和生产环境一致。
  • 最小化差异以减少bug的产生。

日志(Logs)

  • 将日志作为事件流进行处理。
  • 将日志流传输到集中位置进行分析。

管理进程(Admin Processes)

  • 将管理任务作为一次性进程运行。
  • 避免将管理进程与主应用程序代码混在一起。
为什么选择十二要素应用程序?

要知道我们为什么需要十二要素应用,首先要了解创建应用的传统流程。

以前,你必须满怀希望、克服重重困难才能将想法传播到全世界,你需要花费数天、数周甚至数月的时间来订购并收到服务器来托管应用程序。最终,一旦将应用托管到服务器上,今后都将依赖该服务器。

你编写的代码只能在该服务器上运行,不能在其他服务器上运行,如果需要扩容,必须扩展该服务器上的资源。

如果用户正在做某件事情,而服务器崩溃了,用户在此之前所做的一切都会丢失,从而不得不重新做一遍。

但是,如今我们生活在高增长的世界里,快速创业公司的用户数量在短短几个月内可以从零增长到数百万

如果你有一个想法,只需要花几天时间开发代码,配置和托管可以在几小时内完成。如今大多数云平台都可以在几分钟内提供服务器和其他资源,并且云平台预计在 99.99% 的时间内都能正常工作,这意味着不需要停机并关闭应用程序

对于这种情况,应用程序需要从底层基础设施中解脱出来。通过这种方式,你可以将应用托管在任何想要的地方,无论是本地、GCP、AWS还是AZURE,这就是所谓的可移植性。

可移植性意味着无需更改应用代码,就能在不同环境中运行相同的应用程序。

这意味着你的应用首先需要具有可移植性。

说到扩容,在过去,你不得不关闭应用程序来增加服务器资源,这就是所谓的垂直扩容

如今,你需要提供和运行更多服务器,并运行更多应用程序实例,这就是所谓的水平扩容

总结一下

现代应用程序需要具备可移植性,因此不能与底层基础设施紧密耦合。

开发、测试和生产环境之间进行部署时,应尽量减少分歧,以实现持续部署。

而且必须能够通过同时启动多个实例来轻松扩容,并适配现代云平台。

为了实现这一目标,在开发应用程序时必须牢记某些原则。

大约十年前,Heroku 的工程技术人员提出了构建现代应用程序时需要考虑的十二个因素,被称为"十二因素应用"。

让我们深入探讨一下"十二要素应用"的每一项原则。

1.代码库

在代码版本控制系统中跟踪代码库,进行多次部署。

第一条规则是为应用程序建立单一的代码库。

假设应用程序支持多种服务,如订单或付款,不要将所有服务都放在一个代码库中,每个服务应该有单独的代码库来实现分布式系统。

每个代码库都必须部署在不同的环境中,如研发预发布生产环境,维护单个和多个代码库的工具就是 git

Git 是一种底层技术,它能对代码库进行版本控制,并在团队成员之间提供良好的协作。

而 GitHub 是一个网络平台,为代码版本控制提供托管服务。

alt
2.依赖

明确声明并隔离依赖关系。

大多数编程语言都提供包管理系统,用于安装或分发支持的库,例如 Python 的 pip 或 Perl 的 CPAN。

库安装在包管理系统中,可以全局安装,也可以安装在包含应用程序的目录中(称为绑定)。

全局安装意味着该计算机上的所有项目和应用程序都可以使用。

而安装范围仅限于应用目录,则意味着在项目自身的目录结构中专门为项目安装库。

十二要素应用从不依赖隐含的全局系统软件包。

因此,通过依赖声明清单文件(如 Python 中的 requirments.txt)来完整、准确的声明所有依赖关系,该文件可由 pip 包管理系统安装。此外,在执行过程中使用依赖隔离工具,以确保没有隐式依赖关系从周围系统"泄漏"进来。例如,Python 有虚拟环境(venv) 的概念。

因此,有了依赖关系声明清单文件和依赖关系隔离工具(如 Python 中的 venv),就能定义需求和隔离依赖关系。

然而,如果应用所依赖的工具与编程语言无关,怎么办?

比如,curl命令和其他系统依赖工具。请记住,curl必须安装在主机操作系统上,才能在像 Python 这样的虚拟隔离环境中与应用程序一起工作。venv 本身不会提供 curl 二进制文件,而是依赖于主机系统的 curl。

这就需要一种能在所有不同编程语言中使用的更通用的方法,如 Docker 容器

Docker 允许我们在一个与主机系统隔离的独立环境中运行应用程序,它是一种更高效、更可靠的管理依赖关系的方式。

通过使用 docker,我们可以完全遵循第二条规则 "明确声明并隔离依赖关系"。

alt
3.配置

在环境中存储配置

配置是指应用程序在开发、测试、预发和生产等不同环境中运行所需的配置设置。

配置设置,如数据库连接字符串、应用程序接口密钥和其他参数,这些参数会因部署环境而异。

因此,十二要素应用并不将配置设置存储在传统的配置文件或代码中,而是将其配置存储在环境变量(env vars)中

环境变量是一种在运行时向应用程序传递信息而无需更改代码本身的方法。环境变量易于在不同部署(开发、测试、预发和生产)之间更改,而无需更改任何代码。

因此,在十二要素应用中,配置应与代码严格分离,并存储在环境变量中。这意味着只需构建一次应用程序,就可以在多个环境中进行测试、部署和运行。

十二要素应用没有说明如何存储密钥和 API token 等,为此我们建议使用Secrets管理工具来管理这些加密信息,如 HashiCorp Vault、AWS Secrets Manager 或任何其他类似工具。

alt
4.后端服务

将后端服务视为附加资源

例如数据库(Mysql)、Redis、用于外发电子邮件的 SMTP 服务(如 POSTFIX)等。

后端服务可以是本地管理的服务,也可以是任何第三方服务,如 AWS、S3 或 AWS RDS,两者都是附加资源,可通过 URL 或存储在配置中的其他定位器/凭据访问。

十二要素应用的部署应能将本地 MYSQL 数据库与由第三方(如 AWS RDS)管理的数据库进行互换,而无需对应用程序代码进行任何更改。

alt
5.构建、发布、运行

将构建和运行阶段严格分离。

十二要素应用将构建、发布和运行阶段严格分开。

将代码库转化为特定环境中运行的应用程序需要经历以下几个阶段。

1.构建阶段

构建阶段使用代码及其依赖关系来生成构建结果。

构建阶段是软件开发流程的初始阶段,在这一阶段,应用源代码将被编译、测试并转化为可部署的工件,这一阶段通常包括编译代码、运行单元测试以及将应用打包为容器镜像或其他可部署格式等操作。

2.发布阶段

发布阶段基于构建工件及其配置来生成发布版本。

一旦完成构建,就进入发布阶段,在这一阶段,需要定义运行多少个应用程序副本,使用哪些容器和镜像,如何将应用程序暴露给外部,以及应用正常运行所需的其他配置。

3.运行阶段

运行阶段运行一个或多个版本实例。

运行阶段包括将应用程序作为实时工作负载运行、处理多个并发请求并管理其生命周期,这些流程可实现明确的分工,并应使用 CI/CD 流水线实现自动化。

alt
6.进程

将应用程序作为一个或多个无状态进程执行。

十二要素应用程序进程是无状态的,不共享任何东西,任何需要持久化的数据都必须存储在有状态的后端服务(通常是数据库)中,这种方法提供了重要的运维优势,使其更容易扩展并从故障中恢复。

无状态进程意味着应用程序的每个实例都应是独立的,不存储任何特定于单个用户或请求的状态或数据。

该要素是其他十二要素准则(如并发性和可处置性)的重要前提。

alt
7.端口绑定

通过端口绑定暴露服务。

十二要素应用是自成一体的独立进程,不受父进程控制,通过监听端口暴露自己的服务,这也意味着它们可以充当其他应用程序的后端服务。

端口绑定的概念对于面向网络的服务或任何需要通过互联网访问的基于网络的服务至关重要,通过将应用程序绑定到特定端口,应用程序就可以通过该端口的网络地址进行访问,从而允许客户端(如网络浏览器或其他应用)与应用程序进行通信。

alt
8.并发性

通过进程模型扩大规模。

并发性是指应用程序如何扩展和处理多个并发请求或任务。十二要素应用程序提倡无状态进程,这意味着应用程序的每个实例都应是独立的,不存储任何特定于单个用户或请求的状态或数据,这样就能轻松实现水平扩容。

十二要素应用主张基于负载均衡器来处理不断增加的并发量,将传入的请求分配到多个应用实例上。十二要素应用确保应用程序的设计能够处理多个并发请求,并能在不影响响应速度或资源利用率的情况下轻松扩展。

这种方法非常适合需要同时处理大量用户和请求的现代网络应用程序和服务。

alt
9.可处置性

通过快速启动和优雅关机最大限度提高稳健性。

十二要素应用进程是一次性的,这意味着可以快速、无缝的启动和停止,从而可以在不中断系统的情况下轻松扩展和快速部署更新。

进程应力求缩短启动时间,最好只需几秒钟,以便灵活、轻松的在机器之间移动。

当进程需要关闭时,它们会优雅的完成正在进行的任务,并在收到信号后退出。对于网络进程来说,这意味着拒绝新请求,允许完成当前业务,然后关闭。

alt
10.研发/生产环境一致

尽可能保持开发、预发和生产环境的相似性。

传统上,开发环境和生产环境之间存在巨大差距,这些差距主要体现在三个方面:

  • 时间差:开发人员可能需要几天、几周甚至几个月的时间才能将代码投入生产。
  • 人员差距:开发人员编写代码,运维工程师部署代码。
  • 工具差距:开发人员可能使用 Nginx、SQLite 和 OS X 等技术栈,而生产部署则使用 Apache、MySQL 和 Linux。

十二要素应用旨在通过保持开发与生产之间的较小差距来实现持续部署[2]

  • 缩短时间差:开发人员可能会在编写代码数小时甚至几分钟后就将其部署,频繁部署可最大限度缩短代码在不同环境下的时间差。
  • 缩小人员差距:编写代码的开发人员密切参与代码部署,并观察其在生产中的行为,让开发人员负责部署和监控自己的应用程序,而不是由单独的运维团队负责。
  • 缩小工具差距:尽可能保持开发和生产环境的相似性。
alt
11.日志

将日志视为事件流。

十二要素应用非常清楚,写入日志的内容应该是可理解的,并像流一样处理,而不是将日志写入存储在计算机磁盘上的文件中。

应用不必担心日志的去向或存储方式,相反,应用程序的每个部分都会将日志或信息写入名为 stdout 的特殊输出。

在开发过程中,可以直接在屏幕或终端上看到这些信息。在预发或生产环境中,执行环境会收集所有消息或日志,并使用 LogplexFluentd 等工具将其发送到最终目的地。这些目的地可以是文件或日志,也可以是 HadoopELK 等分析系统。

alt
12.管理程序

将管理任务作为一次性进程运行。

十二因素应用方法的管理进程原则建议,管理任务应与应用程序流程分开,并应在相同的设置下运行,而且应具有自动扩展性和可重复性。

因此这些管理任务,如

运行数据库迁移。

运行控制台或在某些情况下使用单独的命令。

运行提交到应用程序版本库的一次性脚本。

一次性管理程序应在完全相同的环境中运行,并与发布版本相对应。管理代码必须与应用程序代码一起发布,以避免同步问题。

alt
结论

十二要素应用方法论为构建现代云原生应用程序提供了一套全面的最佳实践。在当今软件普遍以服务形式交付的时代,遵守这些原则对于实现可扩展性、可移植性和可维护性至关重要。

通过遵循十二要素应用,开发人员可以克服传统应用程序开发的挑战,因为传统应用程序开发的部署非常繁琐,而且与特定服务器绑定。由于注重代码库管理、明确的依赖关系声明和基于环境的配置,应用程序变得更加灵活,可以轻松适应不同的部署环境。

构建、发布和运行阶段的分离确保了开发和生产之间的明确区分,使开发人员能够快速迭代和部署变更,将干扰降到最低。无状态进程可实现水平扩容,而端口绑定可确保应用能够轻松将其服务暴露给外部访问。

十二要素应用强调可处置性,促进快速启动和优雅关闭,从而增强弹性和可扩展性。通过将日志视为事件流,将管理任务作为一次性进程运行,开发人员可以更好的洞察应用程序行为,并维护更简洁的代码库。

通过遵循"十二要素"指南,开发人员可以创建现代云原生软件即服务(cloud-native software-as-a-service)应用程序,这些应用具有可移植性、弹性,并专为云时代设计。


你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。为了方便大家以后能第一时间看到文章,请朋友们关注公众号"DeepNoMind",并设个星标吧,如果能一键三连(转发、点赞、在看),则能给我带来更多的支持和动力,激励我持续写下去,和大家共同成长进步!

参考资料
[1]

The Twelve-Factor App: Best Practices for Cloud-Native Applications: https://medium.com/@tech_18484/introduction-701b7a8f4730

[2]

持续部署: http://avc.com/2011/02/continuous-deployment

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/446919.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爬虫与DataFrame对象小小结合

import pandas as pd import requests from lxml import etree #数据请求 url"https://www.maigoo.com/brand/list_1715.html" headers{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari…

【实验报告】C语言实现猜单词的小游戏

之前帮别人写的一个简单的报告,无偿分享给大家~代码在后面,有一些图片出于懒惰没有上传。比较简单,喜欢的话关注我~,请勿商用~ 1 系统功能模块结构图 该程序主要思路: 头文件设计,存储结构设计&#xff0…

Jmeter+Ant+Git/SVN+Jenkins实现持续集成接口测试,一文精通(一)

前言 Jmeter,Postman一些基本大家相比都懂。那么真实在项目中去使用,又是如何使用的呢?本文将一文详解jmeter接口测试 一、接口测试分类 二、目前接口架构设计 三、市面上的接口测试工具 四、Jmeter简介,安装,环境…

计算机网络—OSPF单区域配置

目录 目录 1.实验环境准备 2.配置 OSPF 3.验证 OSPF 配置 4.修改 OSPF hello 和 dead 时间参数 5.OSPF缺省路由发布及验证 6.控制 OSPF DR/BDR 的选举 7.配置文件 拓扑图&#xff1a; 1.实验环境准备 基本配置以及IP编址。 <Huawei>system-view Enter system vi…

YOLOv8改进 | 注意力篇 | 利用YOLO-Face提出的SEAM注意力机制优化物体遮挡检测(附代码 + 修改教程)

一、本文介绍 本文给大家带来的改进机制是由YOLO-Face提出能够改善物体遮挡检测的注意力机制SEAM&#xff0c;SEAM&#xff08;Spatially Enhanced Attention Module&#xff09;注意力网络模块旨在补偿被遮挡面部的响应损失&#xff0c;通过增强未遮挡面部的响应来实现这一目…

【JAVA】CSS定位与CSS3属性、渐变、CSS3字体、2D变换

1 定位 1.1 相对定位 相对定位没有脱离文档流 定位元素的显示层级比普通元素高 定位元素可以通过margin&#xff0c;float调整位置&#xff0c;但不推荐 包含块&#xff1a;父元素 left和right同时写&#xff0c;右失效 上下同时写&#xff0c;下失效 <head><s…

从零学习Linux操作系统 第三十四部分 Ansible中的执行流控制

一、ansible中的迭代循环 循环迭代任务# 1、简单循环# loop: ##赋值列表 – value1 – value2 – … {{item}} 迭代变量名称 2、循环散列或字典列表 二、Ansible中的条件语句 when: 条件1条件2 条件判断 ‘’value “字符串”,value 数字‘<’value < 数字‘>…

【基础计算机网络2】物理层——通信基础

【前言回顾】 【考纲内容】 一、物理层的基本概念 1.1 物理层的主要任务 物理层解决如何在连接各种计算机的传输媒体上传输数据比特流&#xff0c;而不是指具体的传输媒介。物理层的主要任务&#xff1a;确定与传输媒体接口有关的一些特性。 1.2 物理层的一些特性 机械特性…

C++变参模板

从c11开始&#xff0c;模板可以接受一组数量可变的参数&#xff0c;这种技术称为变参模板。 变参模板 下面一个例子&#xff0c;通过变参模板打印一组数量和类型都不确定的参数。 #include <iostream> #include <string>void print(void) {std::cout<<&quo…

【最新版】ChatGPT/GPT4科研应用与AI绘图论文写作(最新增加Claude3、Gemini、Sora、GPTs技术及AI领域中的集中大模型的最新技术)

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

关于playbook中when条件过滤报The conditional check ‘result|failed‘ failed的问题

问题现象 在使用plabook中的when做过滤脚本如下&#xff1a; --- - hosts: realserversremote_user: roottasks:- name: Check if httpd service is runningcommand: systemctl status httpdregister: resultignore_errors: True- name: Handle failed service checkdebug:ms…

docker常用操作-docker私有仓库的搭建(Harbor),并将本地镜像推送至远程仓库中。

1、docker-compose安装&#xff0c;下载docker-compose的最新版本 第一步&#xff1a;创建docker-compose空白存放文件vi /usr/local/bin/docker-compose 第二步&#xff1a;使用curl命令在线下载&#xff0c;并制定写入路径 curl -L "https://github.com/docker/compos…

基于Spring Boot + Vue的电影购票系统

基于Spring Boot Vue的电影购票系统 功能介绍 分为用户端和商家端&#xff0c;商家端只能让拥有商家角色的人登录 商家可以在系统上面注册自己家的影院信息选择影院进去管理&#xff0c;在选择完要进行操作的影院后&#xff0c;可以在系统的电影库选择电影为当前的影院进行电…

Docker容器Docker桌面配置镜像加速

打开Docker Desktop应用程序&#xff0c;点击设置 具体配置如下&#xff1a; {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"features": {"buil…

VScode(Python)使用ssh远程开发(Linux系统树莓派)时,配置falke8和yapf总结避坑!最详细,一步到位!

写在前面&#xff1a;在Windows系统下使用VScode时可以很舒服的使用flake8和yapf&#xff0c;但是在ssh远程开发树莓派时&#xff0c;我却用不了&#xff0c;总是出现问题。当时我就开始了漫长的探索求知之路。中间也请教过许多大佬&#xff0c;但是他们就讲“能用不就行了&…

Windows10/11配置WSL(Ubuntu)环境

文章目录 WSL介绍WSL部署扩展&#xff1a;辅助工具Windosw Terminal安装下载 WSL介绍 传统方式获取Linux操作系统&#xff0c;是安装完整的虚拟机及镜像环境&#xff0c;例如虚拟机VMware 而使用WSL,可以以非常轻量化的方式&#xff0c;得到Linux系统环境 它无需单独虚拟一套硬…

PaddlePaddle----基于paddlehub的OCR识别

Paddlehub介绍 PaddleHub是一个基于PaddlePaddle深度学习框架开发的预训练模型库和工具集&#xff0c;提供了丰富的功能和模型&#xff0c;包括但不限于以下几种&#xff1a; 1.文本相关功能&#xff1a;包括文本分类、情感分析、文本生成、文本相似度计算等预训练模型和工具。…

计算机设计大赛 行人重识别(person reid) - 机器视觉 深度学习 opencv python

文章目录 0 前言1 技术背景2 技术介绍3 重识别技术实现3.1 数据集3.2 Person REID3.2.1 算法原理3.2.2 算法流程图 4 实现效果5 部分代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习行人重识别(person reid)系统 该项目…

【C语言基础】:深入理解指针(终篇)

文章目录 深入理解指针一、函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 typedef关键字 二、函数指针数组三、转移表四、回调函数4.1 什么是回调函数4.2 qsort使用举例4.2.1 使用qsort函数排序整形数据4.2.2 使用qsort排序结构数据4.2.3 qsort函数的模拟实现 …

WPF(1)的MVVM的数据驱动学习示例

MVVM Model:数据模型、View 界面、ViewModel 业务逻辑处理 项目结构 界面数据绑定 <Window x:Class"WpfApp1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/x…