12-Factor因素与云原生

文摘   2024-08-29 07:29   云南  

 


点击上方蓝字关注我们


 

 

基本原则


 

12因素应用是一个为构建SaaS应用提供的方法论,它包括以下12个基本原则:

  1. Codebase: 一个代码库,多个部署。

  2. Dependencies: 明确声明和隔离依赖。

  3. Configuration: 将配置存储在每个部署环境中,最好使用环境变量。

  4. Backing Services: 将后端服务视为资源,通过配置定位。

  5. Build, Release, Run: 严格分离构建、发布和运行阶段,运行时不更改代码。

  6. Processes: 保持所有进程无状态,共享无状态,将状态(和其他持久数据)存储在有状态的后端服务中。

  7. Port Binding: 将每个服务绑定到端口上并监听该端口,不依赖于运行时服务器注入。

  8. Concurrency: 区分进程类型(例如web、后台工作者、实用程序)并独立扩展每种类型。

  9. Disposability: 使进程快速启动并安全关闭。

  10. Dev/Prod Parity: 通过最小化部署之间的时间差距、人员差距(作者=部署者)和环境差距来最大化开发/生产一致性。

  11. Logs: 通过将所有输出流写入stdout来记录日志;使用非应用服务路由流。

  12. Admin Processes: 在与正常进程相同的环境中运行一次性/管理进程。

 

12-Factor 为构建如下的 SaaS 应用提供了方法论


 

  • 使用声明式格式来搭建自动化,从而使新的开发者花费最少的学习成本加入这个项目

  • 和底层操作系统保持简洁的契约,在各个系统中提供最大的可移植性

  • 适合在现代的云平台部署,避免对服务器和系统管理的额外需求

  • 最小化开发和生产之间的分歧,实现持续部署以实现最大灵活性

  • 可以在工具、架构和开发实践不发生重大变化的前提下实现扩展

12因素理论适用于以任意语言编写,并使用任意后端服务(数据库、消息队列、缓存等)的应用程序。

12-Factor


12-Factor

 

行业实践中的一些案例


 

Codebase

CodeBase


GitHub和GitLab,Gogs等版本控制系统,帮助团队管理单一代码库和多个部署。
单一代码库:使用Git作为版本控制系统,确保所有环境使用相同的代码库。应用程序必须有一个代码库,每个应用程序(即微服务)都在版本控制系统中进行跟踪,可以多次部署(开发、测试、暂存和生产环境)。两个微服务不共享同一个代码库。这种模型允许在不影响应用程序其他部分的情况下灵活地更改和部署服务。
严格版本控制:通过Git标签或分支策略管理不同部署的版本。
公有云: 使用Git服务如GitHub或GitLab,结合云服务提供商的CI/CD工具,如AWS CodePipeline或Google Cloud Build。
私有部署: 搭建自托管的Git服务器,如Gitea或GitLab CE,结合Jenkins或GitLab Runner进行CI/CD。

Dependencies

Dependencies


应用程序必须显式声明其代码依赖项,并将它们添加到应用程序或微服务中。依赖项作为微服务JAR/WAR文件的一部分进行打包。这有助于隔离跨微服务的依赖项,并减少同一JAR的多个版本可能产生的任何副作用。
通过使用Docker和Kubernetes,开发者可以声明并隔离依赖,确保环境一致性。
显式声明依赖:使用依赖管理工具,如npm, pip, Maven等。
隔离依赖:使用容器化技术(Docker)或虚拟环境(如Python的venv)
公有云: 使用容器服务如Docker Hub或Google Container Registry来管理依赖。
私有部署: 搭建私有容器仓库,如Harbor或使用Docker Registry。

Configuration

Configuration


将应用程序配置数据从应用程序或微服务中移出,并通过配置管理工具进行外部化。应用程序或微服务将根据其运行的环境来获取配置,允许相同的部署单元在各个环境中传播。
使用环境变量管理系统(如HashiCorp Vault或AWS Secrets Manager)来存储配置,确保配置与代码分离。
环境变量:使用环境变量管理配置,如在Docker容器中使用-e标志或在Kubernetes中使用ConfigMaps和Secrets
公有云: 使用AWS Systems Manager Parameter Store或Azure App Configuration。
私有部署: 使用Consul或Etcd,Nacos, Apollo作为配置中心。


Backing Services

Backing Services


所有外部资源的访问应该是一个可寻址的URL。例如,SMTP URL、数据库URL、服务HTTP URL、队列URL和TCP URL。这允许URL被外部化到配置中,并为每个环境进行管理。
将数据库、消息队列等后端服务作为资源,通过服务发现(如Consul或Etcd)动态定位。
服务化:将数据库、缓存等后端服务作为服务化资源,通过API或服务发现机制访问。

Build, Release, Run

Build, Release, Run


构建、发布和运行的整个过程被视为三个独立的步骤。这意味着,在构建过程中,应用程序被构建为一个不可变的实体。这个不可变的实体将根据环境(开发、测试、暂存或生产)选择相关的配置来运行进程。
使用CI/CD工具(如Jenkins, CircleCI, GitLab CI)自动化构建、发布和部署流程。
构建:使用CI工具(如Jenkins, GitLab CI)自动化构建过程。
发布:使用容器注册中心(如Docker Hub, Google Container Registry)存储构建产物。
运行:在容器编排平台(如Kubernetes)上部署和管理应用。

Processes

Processes


微服务建立在共享无状态模型上。这意味着服务是无状态的,状态被外部化到缓存或数据存储中。这允许无缝扩展,并允许负载均衡或代理将请求发送到服务的任何实例。
使用容器化技术(如Docker)确保进程的无状态性和可复现性。
无状态:设计应用为无状态,所有状态外置到数据库或其他持久化存储。
服务化:将应用拆分为微服务,每个服务运行在独立的容器中。
公有云: 使用AWS Lambda或Azure Functions进行无状态函数部署。

Port Binding


微服务在容器内构建。服务将通过端口(包括HTTP)导出并绑定其所有接口。
通过Kubernetes服务(如NodePort或LoadBalancer)将应用绑定到端口,实现服务的可访问性。
服务端口:每个服务监听自己的端口,通过反向代理(如Nginx)或服务网格(如Istio)进行路由。
公有云: 使用AWS Elastic Load Balancer或Azure Load Balancer。
私有部署: 使用Nginx或HAProxy进行负载均衡。

Concurrency

Concurrency


微服务进程被扩展出去,这意味着为了处理增加的流量,更多的微服务进程被添加到环境中。在微服务进程内部,可以利用响应式模型来优化资源利用率。
Kubernetes的水平扩展能力允许开发者根据负载独立扩展不同类型的进程。
进程类型:区分不同类型的进程(如Web服务器、后台任务)并独立扩展。
容器编排:使用Kubernetes进行服务的扩展和管理。
公有云: 使用Kubernetes或AWS Fargate进行服务的自动扩展。
私有部署: 使用Kubernetes或Mesos, OpenShift进行容器编排和管理。

Disposability

Disposability

理念是构建一个不可变的微服务,具有单一职责,从而最大化鲁棒性,并加快启动时间。不可变性也有助于服务的可替换性。
Kubernetes的Pod生命周期管理确保了进程的快速启动和安全关闭。
快速启动:设计应用以快速启动,例如通过优化启动脚本或使用轻量级容器。
安全关闭:确保应用能够响应终止信号并安全地关闭。
公有云: 利用云服务的自动扩展和健康检查功能。
私有部署: 配置Kubernetes的Liveness和Readiness探针。

Dev/Prod Parity

Dev/Prod Parity


应用程序生命周期中的环境—开发、测试、暂存和生产—应尽可能保持相似,以避免后期出现任何意外。
使用相同的基础设施和配置在开发、测试和生产环境中部署应用,减少环境差异。
环境一致性:使用相同的工具和配置在开发、测试和生产环境中部署应用。
自动化部署:使用CI/CD工具自动化部署流程,减少人为差异。
私有部署: 使用Terraform或Ansible确保环境一致性。

Logs

Logs


在不可变的微服务实例中,作为服务处理的一部分生成的日志是状态的候选。这些日志应被视为事件流,并推送到日志聚合基础设施。
使用日志聚合工具(如ELK Stack或Fluentd)将日志统一收集和分析。
标准输出:将所有日志输出到标准输出(stdout)或标准错误(stderr)。
日志收集:使用日志收集工具(如Fluentd, Logstash)收集日志,并使用日志分析工具(如ELK Stack)进行分析。
公有云: 使用AWS CloudWatch或Azure Monitor Logs, 阿里云SLS


Admin Processes

Admin Processes


微服务实例是长期运行的进程,除非它们被杀死或被新版本替换,否则会继续运行。所有其他管理和管理任务被视为一次性进程:遵循12因素的应用程序不对外部环境做任何假设,允许它们在任何云服务平台上部署。这允许跨环境运行相同的工具/流程/脚本,并以一致的方式部署分布式微服务应用程序。
使用自动化脚本和工具(如Ansible或Terraform)来执行数据库迁移、数据备份等管理任务。
一次性任务:使用脚本或自动化工具(如Ansible)执行数据库迁移、数据备份等管理任务。
环境一致性:确保管理任务在与生产环境相同的配置下执行。
公有云: 使用云服务提供商的管理控制台或CLI工具。

还有一些扩展因素


Audit and RBAC



API First




Pipeline




 

12因素在云原生架构


 


12因素在云原生架构

云原生是一种构建和运行应用程序的方法,它利用云计算的优势,包括:

  • Stateless: 无状态,通过端口绑定运行服务。

  • Scale: 服务作为资源,可以水平扩展。

  • Framework: 构建、发布、运行环境。

  • Configuration: 环境配置。

  • Fast startup and graceful shutdown: 快速启动和优雅关闭。

  • One codebase, many deploys: 一个代码库,多个部署。

  • Infrastructure: 基础设施自动化和编排。

  • Health management: 健康检查和管理。

  • Logging as event streams: 日志作为事件流。

  • Resource lifecycle: 资源生命周期管理。

  • Ad-hoc tasks: 临时任务作为短期进程。

  • Orchestrated processes: 编排进程。

  • Infrastructure Automation: 基础设施自动化。

  • Diagnose and recover from failure: 诊断并从故障中恢复。

云原生应用程序设计为在云环境中运行,利用容器化、微服务架构、持续集成和持续部署等技术,以实现高可用性、可扩展性和弹性。

 

云原生实践案例


 

  • 无状态性: 通过容器化确保应用的无状态性,便于快速扩展和恢复。应用设计为无状态,便于快速扩展和故障恢复,例如使用无状态的微服务架构。

  • 水平扩展: 使用Kubernetes的水平自动扩展(HPA)根据负载自动调整实例数量。

  • 服务网格: 使用Istio或Linkerd等服务网格技术进行服务发现、负载均衡和流量管理。

  • 配置管理: 使用Kubernetes ConfigMaps和Secrets或云服务提供商的配置管理服务。

  • 快速启动和优雅关闭: 优化应用启动流程,响应SIGTERM信号进行优雅关闭。

  • 持续部署: 使用GitOps和CI/CD工具实现自动化的持续部署。

  • 基础设施自动化: 使用Terraform或Ansible等IaC工具自动化基础设施的配置和管理。

  • 健康检查: 使用Kubernetes的探针(Probes)进行健康检查,自动替换不健康的实例。

  • 日志管理: 使用云原生日志服务或自托管的日志管理系统进行日志收集和分析。

  • 资源生命周期管理: 使用容器编排工具管理资源的生命周期,如Kubernetes的Deployments和StatefulSets。

  • 临时任务: 使用Kubernetes的Jobs或CronJobs执行一次性任务和定时任务。

  • 服务编排: 使用Kubernetes或Mesos等工具进行服务编排和管理。

在目前各云厂商已经有对应平台,包含阿里云效,腾讯云CODE已覆盖代码git托管,依赖管理,容器镜像管理,ACK容器方案。

 

SpringBoot技术栈


 

  • 无状态性: 确保Spring Boot应用设计为无状态,所有状态存储在外部数据库或缓存中。

  • 水平扩展: 使用Spring Cloud Netflix Eureka或Consul进行服务发现,结合Spring Cloud Config进行配置管理。

  • 服务网格: 利用Spring Cloud Gateway或Zuul作为API网关,与服务网格技术如Istio集成。

  • 配置管理: 使用Spring Cloud Config Server集中管理不同环境下的配置。

  • 快速启动和优雅关闭: 利用Spring Boot的内嵌容器快速启动应用,通过Spring生命周期管理优雅关闭。

  • 持续部署: 结合Jenkins、GitLab CI等CI/CD工具,实现从代码提交到自动部署的流程。

  • 基础设施自动化: 使用Terraform或AWS CloudFormation等IaC工具自动化云服务的配置。

  • 健康检查: 利用Spring Boot Actuator的健康端点进行应用健康检查。

  • 日志管理: 使用Logback或Log4j2等日志框架,结合外部日志收集系统如ELK Stack。

  • 资源生命周期管理: 使用Spring Cloud Kubernetes进行应用的生命周期管理。

  • 临时任务: 使用Spring Batch或Quartz Scheduler执行定时或一次性任务。

  • 服务编排: 利用Spring Cloud Kubernetes与Kubernetes集成,进行服务的编排和管理。

 

结论


 

  1. 一致性与灵活性: 12因素原则强调了在整个软件开发和部署过程中保持一致性的重要性,同时提供了足够的灵活性来适应不同的环境和需求。

  2. 环境无关性: 通过将配置和后端服务外部化,应用程序可以轻松地在不同的环境中部署,无需担心环境差异带来的影响。

  3. 依赖管理: 显式声明和管理依赖项有助于避免“依赖地狱”,确保应用程序的稳定性和可维护性。

  4. 可维护性和可扩展性: 无状态的微服务设计和共享无状态模型使得应用程序易于扩展和管理,同时提高了系统的容错性。

  5. 快速迭代和部署: 12因素原则支持快速的迭代和部署,通过自动化的构建和发布流程,使得新功能的上线更加迅速和可靠。

  6. 日志和监控: 将日志视为事件流并使用日志聚合工具,有助于更好地监控和分析应用程序的行为,从而快速定位问题。

  7. 简化运维: 通过容器化和自动化的基础设施管理,运维工作变得更加简单和标准化,减少了人为错误的可能性。

  8. 服务的独立性和可替换性: 每个微服务都是独立和可替换的,这有助于快速迭代和维护,同时提高了系统的可测试性。

  9. 持续集成和持续部署(CI/CD): 12因素原则与CI/CD实践相辅相成,自动化的构建、测试和部署流程是实现快速迭代的关键。

  10. 云原生友好: 12因素原则天然适合云原生环境,无论是公有云、私有云还是混合云,都能提供一致的部署和管理体验。

综上所述,12因素应用原则为构建现代云原生应用程序提供了一套全面的指导方针,帮助团队提高开发效率,降低维护成本,并确保应用程序的高可用性和可扩展性。 

 

Megadotnet
为您介绍各体系平台的新闻,系统研发相关框架,组件,方法,过程,运维,设计。企业IT与互联网信息系统或产品解决方案。开源项目,项目管理。
 最新文章