掌握可扩展和可维护应用程序:12-Factor应用程序开发的全面指南

news2024/12/23 17:06:28
e16f6c819eda5fb75d34bef2a9d87af3.jpeg
1*vhxOhTuKSyuuAKu-nUQ5SA.jpeg

在今天的快节奏世界中,软件开发人员需要创建可扩展、可维护和适应性强的应用程序。12-Factor应用程序方法论是一组最佳实践,可以帮助开发人员实现这些目标。

本文深入探讨了12个因素,详细解释了它们的重要性以及如何将它们应用到您自己的应用程序中。通过遵循这些原则,您可以创建更可靠、更高效且更易于管理的软件。

1. 代码库

这个因素可能是最广为人知、最简单的12个因素之一,但它对开发过程有着重大影响。将所有代码放在一个地方允许团队中的每个人都从同一个真相源工作。这简化了跟踪变更、协作和冲突避免。

拥有单一的代码库有许多好处。以下是一些例子:

更容易跟踪变更: 当所有代码都在一个地方时,很容易看到谁做了什么变更以及何时做的。这对于调试和故障排除可能有帮助。•最小化代码冲突: 当多人在同一代码上工作时,他们可能会进行冲突的更改。拥有单一的代码库有助于避免这种情况,因为确保每个人都在同一版本的代码上工作。•促进协作: 当每个人都从同一个代码库工作时,更容易进行协作和分享想法。这可能导致更好的代码和更高效的开发过程。

4fc34e9290c5257669faeb7d470840d9.jpeg
0*QYUcsDdE0q6LhCnr.jpeg

如果您有微服务架构的经验,您可能会想知道为什么在那里不遵循这一做法。然而,事实并非如此。在微服务架构中,每个服务都是一个独立的应用程序,因此每个服务都必须符合12-Factor开发原则。这就是为什么我们为每个服务单独创建存储库的原因。

2. 依赖关系

即使是刚刚入门的开发人员,也可能对库依赖性有所了解。有许多用于不同需求的库可供选择,这就是为什么我们通常会不加思考地安装它们,而不知道它可能带来的混乱。

这个因素强调了明确声明和隔离依赖关系的重要性。这意味着您应该指定应用程序依赖的库和包的确切版本。您还应该隔离依赖项,以确保它们不会相互影响。

38f204c28b69e8744728597fe67822f2.jpeg
0*z7NYskfvg-CDZDlQ.jpeg

明确声明和隔离依赖关系的重要性有几个原因。

首先,它使跟踪依赖关系的变更变得更容易。 如果更改依赖项的版本,您需要确保应用程序仍然正常工作。通过明确声明依赖关系,您可以轻松查看已进行的更改以及它们对应用程序的影响。•其次,明确声明依赖关系使部署应用程序变得更容易。 在部署应用程序时,您需要确保所有依赖项都可用。通过明确声明依赖关系,您可以确保部署包含了所有必要的依赖项。•第三,明确声明依赖关系使调试应用程序变得更容易。 如果应用程序不起作用,您需要能够跟踪问题。通过明确声明依赖关系,您可以轻松看到哪些依赖关系涉及到问题。

最近的Log4j漏洞是管理依赖关系重要性的很好示例。Log4j是一款广泛使用的日志记录库,被许多应用程序使用。该漏洞允许攻击者在使用Log4j的系统上执行任意代码。如果受影响的应用程序的开发人员管理了他们的依赖关系并更新了Log4j到最新/安全版本,这种情况本可以避免的。

3. 配置

将配置设置存储在环境变量中是一种增强安全性、灵活性和可移植性的关键实践。在代码中硬编码配置值可能会使应用程序变得僵化且容易受到安全风险的威胁。通过将配置集中在环境变量中,您可以轻松地更改设置,而无需修改代码。这使您的应用程序更具灵活性和可移植性,并有助于提高安全性。

以下是存储配置设置在环境变量中的好

处的更详细解释:

安全性: 环境变量是一种在代码之外存储配置数据的方式。这对于存储敏感信息,如密码和API密钥,可以提供保护,以便不会暴露给公众。

将API密钥和密码存储在环境变量中相对安全,即使在现在,它仍然被广泛使用,但还有更安全的选项可用。以下是存储API密钥和密码的不同方式,从不安全到最安全:

将它们直接存储在代码中: 这是最不安全的选项,因为任何可以访问您的代码的人都将能够访问您的API密钥和密码。随着环境层次结构的提升,这将使您的代码无法使用。•将它们存储在环境变量中: 这是一种更安全的选项,因为环境变量不存储在代码中,只有运行的应用程序才能访问它们。但是,如果应用程序代码被破坏或环境变量文件被意外共享,环境变量可能会被公开。•将它们存储在磁盘上的文件中: 这可以比将它们存储在环境变量中更安全,因为您可以设置文件权限以限制谁可以访问文件。但是,如果文件未正确保护,它们仍然可能会被公开。•将它们存储在对象存储中: 对象存储,如AWS S3和Google Cloud Storage,比将文件存储在磁盘上更安全。对象存储可以加密,并且可以使用IAM策略限制访问。•使用秘密管理器来存储它们: 秘密管理器,如AWS Secrets Manager和GCP Secret Manager,是存储API密钥和密码的最安全选项。秘密管理器使用加密和其他安全措施来保护您的秘密。

最后三个选项相对类似,因为它们都使用加密和其他安全措施来保护您的秘密。它们之间的主要区别在于它们的管理方式。对象存储由云提供商管理,而秘密管理器通常由使用它们的应用程序或组织管理。人们也经常使用像AWS/GCP秘密管理器这样的提供商管理的秘密管理器。

最终,最适合您的选项将取决于您的具体需求和要求以及您的组织数据政策。如果您需要以安全的方式存储敏感信息,那么我建议使用秘密管理器。

灵活性: 环境变量可以轻松更改,这使得将您的应用程序适应不同的环境变得容易。例如,您可以使用环境变量指定数据库连接字符串、端口号或配置文件的位置。

可移植性: 环境变量与语言和平台无关,因此可以与任何应用程序一起使用。这使得将您的应用程序部署到不同的环境中变得容易。

4. 后备服务

现代应用程序通常依赖于外部服务,如数据库、缓存系统和消息队列。第四个因素要求我们将这些服务视为附加资源。这意味着您的应用程序应该使用配置设置连接到这些服务,而不是将它们硬编码到代码中。

这种解耦使您具有很大的灵活性。您可以轻松更换或扩展这些服务,而无需更改应用程序的代码库。这对于云原生应用程序非常重要,因为它们通常会动态部署和扩展。

c39b92916b4af080f42b73125bf0fa40.jpeg
0*iuE-UVATJWbuTXtV.jpeg

以下是这在实践中可能如何工作的示例。假设您的应用程序使用数据库存储数据。第四因素将指定您不应该将数据库连接字符串硬编码到应用程序的代码中。相反,您应该将连接字符串存储在配置文件中。当应用程序启动时,它将从配置文件中读取连接字符串并连接到数据库。

这样,如果需要更改应用程序使用的数据库,只需更新配置文件即可。您不需要对应用程序的代码库进行任何更改。

虽然这个示例非常简单,但在构建其他人将用作平台的系统时,您将能够充分利用这个原则。确切地说,是使用这个原则的人才能从中受益,因为它们可以消耗您的API的人。

5. 构建、发布、运行

这个因素被认为是今天正在开发的任何现代服务的标准实践,它规定应用程序的构建、发布和运行阶段应该严格分开。构建阶段将您的代码转换为可执行的构件,发布阶段将这些构件与配置组合在一起,运行阶段启动应用程序。

这种分离确保您的应用程序可以在任何环境中部署和运行,而不受底层基础设施的限制。它还使自动化部署过程变得更容易,这有助于提高一致性和可重复性。

虽然这是一个常见的做法,但经常被忽视的一件事是构建

和发布步骤的分离。这种分离对于创建合理的部署和回滚过程非常重要。

当代码合并并进行测试时,生成的镜像或二进制文件应存储在可以在以后发布和部署中检索的存储库/工厂中。这种分离可以实现更简单、更少错误的开发周期。

在较小规模或开发周期的早期,代码和基础设施的更改紧密耦合,可能不需要这种分离。但随着应用程序的增长和成熟,分离这些问题变得越来越重要。

以下是一些在应用程序中实现第五因素的具体示例:

•使用像Jenkins这样的构建工具自动化构建过程。这将有助于确保构建过程是可重复的和一致的。•使用配置管理工具,如AWS的SSM或OCP的Config Map,来管理应用程序的配置。这将有助于将配置与代码分开。•使用像Docker这样的容器化工具将应用程序及其依赖项打包到容器中。这将有助于使您的应用程序具有可移植性和可扩展性。•最后,不要忘记将这些Docker镜像存储在工厂中。

6. 进程

这个因素的重点是使您的应用程序无状态,这意味着您的应用程序不应在内存或磁盘上存储任何数据。这使它们比有状态进程更可伸缩和容错。

可伸缩性是指应用程序处理不断增加的流量的能力。无状态进程可伸缩,因为它们可以轻松复制。当流量增加时,您只需添加更多的无状态进程来处理负载。

任何系统面临的伸缩性问题数量都是管理和存储状态的问题。这对于以软件即服务模式扩展非常重要。这也与有界上下文的概念非常吻合,有界上下文确保每个系统都应该管理其存储层,如果其他系统需要访问该数据,应该通过一个有良好文档的API来访问它。

容错性是指应用程序在某些组件失败时仍然能够继续运行。无状态进程容错,因为它们不依赖于任何共享状态。如果一个无状态进程失败,其他进程可以继续运行而不中断。

如果您还没有注意到,这个因素是REST API的基础。

b3b3118b6d759f0cd1876cc618257c0f.jpeg
0*gAMmnbTGJKBI_B9w.jpeg

7. 端口绑定

第七个因素主张使用明确定义的端口来导出服务。这使应用程序之间的通信更容易,也使管理员更容易管理应用程序。

这个因素已经成为标准做法很长时间了,没有什么特别的变化。此外,许多容器化标准、代理和负载均衡器已经强制执行了这个因素。

主要思想是每个应用程序都应该有一个特定的端口映射。

这意味着每个应用程序都应该在特定端口上监听传入的请求。端口号可以用于传达有关应用程序的信息,例如它提供的服务类型。例如,Web服务器可能在端口80上监听请求,而SSH服务器可能在端口22上监听请求。

e5ce373393eaa20802bfb203f8f464d5.jpeg
0*31lCtHojS36AKQMb.jpeg

8. 并发性

第八因素主张使用并发性来处理不断增加的负载。在这个上下文中,并发性是指应用程序能够同时运行多个实例。

无状态应用程序是实现最大可伸缩性的最佳类型的应用程序。您可以轻松地将所有这些进程分组到负载均衡器下。例如,在电子商务应用程序中,所有订单服务将分组到一个负载均衡器下,而产品服务将分组到另一个负载均衡器下。

99e9fae312156573a9f8924adf951b27.jpeg
0*-4_ZY8fJtpJp7zOp.jpeg

我确定您已经注意到了每个因素中越来越多的冗余,这是因为一个因素是前一个因素的扩展或建立在其上。

9. 可丢弃性

要理解可丢弃性,想象一下能够替换应用程序中的故障部分而不必关闭整个应用程序。这将使您能够在发生问题时保持应用程序的平稳运行。快速启动和优雅的关闭对于应用程序的稳健性至关重要。

这是一个重要的因素,通常在需要时被忽视。启动检查对于确保系统正在运行和正常运行非常重要。健康检查确保系统保持在这种状态或从轮换中移除。

68962d93e399cafd5154948a87838dc6.jpeg
0*whae5tSZTQZrU54I.jpeg

我经常看到关闭过程没有受到同样的关注。人们经常说它是“相对复杂且难以正确执行”的,或者“如果我们不干净地执行它,因为系统不会幸存,所以它无关紧要

”。这个说法是不正确的。第九因素的一个重要部分是确保关闭过程干净且完全,以便应用程序可以在必要时迅速启动和关闭。

10. 开发和生产的平等性

这个因素主张您的开发和生产环境应该尽可能相似。这可以通过使用相同的工具、相同的配置和相同的设置来实现。

003fe7388b4b75069de0bf56c55def25.jpeg
0*XLrJ4s8HrOi9i9uk.jpeg

通过保持这种相似性,您可以确保在开发、测试和生产环境之间更轻松地移动应用程序。这也有助于避免“在我的机器上可以工作”的问题,因为开发和生产环境之间的差异可能导致应用程序在一个环境中运行良好,但在另一个环境中失败。

在实际实现中,开发和生产环境不会完全相同,因为它们的目标和需求不同。但是,它们应该尽可能相似,以确保平滑的部署和运行。

11. 日志

在这个因素中,我们强调了记录的重要性。应用程序应该生成详细的日志,以便在发生问题时进行故障排除和诊断。

日志记录是一种关键的监视和故障排除工具。通过查看日志,您可以了解应用程序的状态、性能和问题。在生产环境中,有一个可靠的日志记录系统非常重要。

c5bc6bfff19aa77dc523928341bf8589.jpeg
0*FXByK4kn-xHrzx_O.jpeg

以下是一些关于日志记录的最佳实践:

记录足够的信息: 确保您的日志包含足够的信息,以便在发生问题时进行故障排除。这可能包括错误消息、异常堆栈跟踪、请求/响应数据等。•结构化日志记录: 将日志记录为结构化数据,而不是纯文本。这使得日志更容易分析和查询。•中心化日志记录: 使用中心化的日志记录工具,如ELK堆栈(Elasticsearch、Logstash和Kibana)或Splunk,将所有应用程序的日志记录到一个位置。•周期性地清理日志: 避免日志文件过大,定期清理旧日志,或将它们归档到长期存储中。

12. 管理进程

最后一个因素强调了管理应用程序进程的重要性。这包括启动、停止和扩展进程。管理进程是确保应用程序稳定运行的关键部分。

1c8fe15957e21e0f5a900f8f8247f330.jpeg
0*OUbq8KmZ7504tKtc.jpeg

管理进程通常需要一些自动化工具,以确保它们可以轻松地启动和停止。这可能包括使用容器编排工具(如Kubernetes或Docker Swarm)来自动化进程的部署和扩展。

确保您的应用程序具有良好的管理进程是非常重要的,因为它可以减轻运维工作的负担,确保应用程序在需要时能够扩展以满足负载。

总结

12-Factor应用程序方法论提供了一组最佳实践,可帮助开发人员构建可扩展、可维护和高效的应用程序。这些因素涵盖了应用程序的各个方面,从代码库和依赖关系管理到配置、构建、发布和运行。

通过遵循这些原则,您可以创建更稳健、更具可维护性和可扩展性的应用程序,同时提高了开发和运维的效率。无论您是在开发单体应用程序还是构建云原生微服务,这些因素都是非常有价值的。

希望这篇文章能够帮助您更好地理解12-Factor应用程序方法论,并在自己的项目中应用这些最佳实践。

更多精彩~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 深度学习 解决遇到的报错问题5

目录 一、conda安装shapefile失败 二、conda安装osmnx失败:To search for alternate channels that may provide the conda package yourelooking for, navigate to 三、ERROR: Could not build wheels for llvmlite, which is required to install pyproject.to…

算法基础--位运算

一、常见位运算总结: 1、基础位运算(^) 其中异或^有2种理解。 2、位图bitset相关(&|) test判断第x位是1函数0: 可以让n右移,也可以让1左移,习惯上选择第一种 (n>>x)&1 判…

初创企业应该选一款怎样的客服系统?

互联网经济时代的飞速发展,促使客户市场对于企业服务的要求越来越高。客户在选择产品的时候已经不单单却决于产品功能和价格,客户服务也是其关注的重点。 优质的客户服务所带来的是客户满意度的提升,以及品牌影响力的提高。所以,…

Linux 服务器下 pypy 下载数据集

Linux 服务器下 pypy 下载数据集 安装 pip install bypy链接自己的百度网盘 命令行直接输入 byby info 就行 byby info查看网盘里面的内容 bypy listbyby list 只显示自动生成的bypy中的文件,上传也是在这个目录中,可以自己在里面新建文件夹 4. 上传…

tsar-性能监控工具

简介 tsar是淘宝自己开发的一个采集工具,主要用来收集服务器的系统信息(如cpu,io,mem,tcp等),以及应用数据(如squid haproxy nginx等)。收集到的数据存储在磁盘上&#…

SMOKE-CMAQ实践技术应用

大气污染物排放是空气污染的源头,气象因素是影响污染程度的重要因素,因此空气质量模式要求气象资料和污染物排放清单作为输入,其中由于大气污染源复杂性、数据滞后性、动态变化、规律性不明显等特点,使得大气污染源排放清单输入准…

【牛客网】OR63 删除公共字符串

思路 创建哈希表,将第二个字符串中出现过的字符添加到哈希表中创建StringBuffer来拼接最后的结果字符串遍历字符串一,如果字符在哈希表中出现过,就不拼接到字符串中,反之则拼接 Java代码 import java.util.*;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public cl…

ISIS的高级特性

1、IS-IS邻接关系建立原则 L1的路由器只能和L1的路由器建立邻接关系,也可以和L1、2的路由建立邻接关系 L2的路由器只能和L2的路由器建立邻接关系,也可以和L1、2的路由建立邻接关系 DIS只有在广播型网络中才会选举 LSP相当于OSPF中的LSA IS-IS链路状态报文…

JUC第十讲:CAS,Unsafe和原子类详解

JUC第十讲:CAS,Unsafe和原子类详解 JUC中多数类是通过volatile和CAS来实现的,CAS本质上提供的是一种无锁方案,而Synchronized和Lock是互斥锁方案; java原子类本质上使用的是CAS,而CAS底层是通过Unsafe类实现的。本文是JUC第十讲&a…

广东海颐开发笔试编程题回顾

题目一 1、现以序列{22, 24, 30, 14, 10, 17, 15, 20, 16, 23}的顺序进行输入,请画出构造出的平衡二叉树?请写出实现二叉树左旋的代码?(具体题目忘记了,就随机搞个排序,思路和方法都是一样的) 图 顺序 {22, 14, 10…

【C++】多态,从使用到底层。

文章目录 前言一、多态的概念二、多太的定义和实现2.1 多太的构造条件2.2 虚函数2.3 重写(覆盖)2.4 C11 override 和 final2.5 重载,隐藏,重写 三、多态的原理3. 1虚函数表3.2 虚函数表如何完成多态的功能3.3 虚函数表存储在内存空间的那个区域&#xff…

服务断路器_Resilience4j超时降级

创建模块cloud-consumer-resilience4j-order80 POM引入依赖 <dependencies><!-- 引入Eureka 客户端依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</a…

【Java 进阶篇】数据库介绍与MySQL详细介绍

数据库是信息科技领域中不可或缺的一部分&#xff0c;它们在我们日常生活中扮演着重要的角色&#xff0c;从手机应用到云计算&#xff0c;无处不在。在本篇博客中&#xff0c;我们将深入探讨数据库的基本概念以及MySQL这一流行的开源关系型数据库的详细信息。不需要数据库专业知…

AI写作生成器-AI写作生成器下载和用途

在当今数字化的时代&#xff0c;AI写作生成器已经成为了各行各业的创作者、企业家和学生的得力助手。这些智能工具以其强大的自然语言处理技术&#xff0c;正在解决着许多用户的写作难题。本文将深入探讨AI写作生成器&#xff0c;以及它如何在不同领域解决用户的写作问题。 147…

【算法分析与设计】递归与分治策略

目录 一、学习要点二、算法总体思想三、递归的概念例1 阶乘函数例2 Fibonacci数列例3 Ackerman函数例4 整数划分问题例5 Hanoi塔问题递归小结 四、分治法1、分治法的适用条件2、二分搜索技术3、大整数的乘法4、Strassen矩阵乘法5、棋盘覆盖6、合并排序7、快速排序8、线性时间选…

嵌入式 - 经典的有刷电机和先进的无刷电机

自从无刷直流电机诞生&#xff0c;“古老的”有刷电机就开始没落&#xff0c;但它依然是低成本应用的可靠选择&#xff0c;并且实现起来简单。 在有刷电机中&#xff0c;磁极方向的跳转是通过移动固定位置的接触点来完成的&#xff0c;该接触点在电机转子上与电触点相对连接。这…

无法从 /var/lib/rpm 打开软件包数据库

使用yum命令安装软件包时&#xff0c;报错“无法从 /var/lib/rpm 打开软件包数据库” 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.原因 是误操作导致 rpm 数据库损坏。&#xff08;/var/lib/rpm 目录下的文件被损坏&#xff09; 2.解决 当RPM 数据库发生损坏&a…

【SAP后台配置】如何通过前台屏幕字段找到对应SPRO后台路径?

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;阿里云社区专家博主&#xff0c;华为云云享专家&#xff0c;腾讯云社区认证作者&#xff0c;CSDN SAP应用技术领域优质创作者。在学习工作中&#xff0c;我通常使用偏后端的开发语言ABAP&#xff0c;SQL进行任务的完成…

C++,对象赋值与对象拷贝的区别、深浅拷贝

在C中&#xff0c;对象赋值和对象拷贝是两个不同的操作&#xff0c;它们有明显的区别&#xff1a; 1. 对象赋值&#xff08;Object Assignment&#xff09;&#xff1a; - 对象赋值是指将一个已经存在的对象的值复制给另一个已经存在的对象。这通常通过赋值操作符&#xff08;…

分布式事务处理:挑战与解决方案

在当今的大数据时代&#xff0c;数据的处理和管理变得越来越复杂。特别是在分布式系统中&#xff0c;如何保证数据的一致性和完整性&#xff0c;是一个巨大的挑战。这就引出了我们今天要探讨的主题——分布式事务处理。分布式事务处理是一种技术&#xff0c;它能够在分布式系统…