基础架构即代码 | 亚马逊如何在现实生活中实践 DevOps

2024-01-22 14:28

本文主要是介绍基础架构即代码 | 亚马逊如何在现实生活中实践 DevOps,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当我在 2005 年作为开发人员加入亚马逊时(那时 Amazon Web Services 还不存在),我从公司领了一个传呼机(如图 1 所示)。在亚马逊,开发人员不仅要设计实现一个具体的服务,还要负责这个服务的部署和管理。为了完成运营任务,开发人员需要轮流 “值班”,随时准备故障诊断和处理。传呼机就是值班用的。

图片


图1: 亚马逊发给员工值班用的传呼机

这一切表明,亚马逊在 “DevOps” 这个术语出现之前就已经在实现 DevOps 的路上了。Amazon.com 在亚马逊云科技提供的平台上运行着成千上万个系统,来支持其全球市场业务、视频传递和其他消费者服务。当架构需要重新设计的时候,亚马逊开发人员就会考虑 DevOps,以便在值班期间更轻松地为客户提供最佳体验。

亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术,观点,和项目,并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏,看到这里请一定不要匆匆划过,点 这里让它成为你的技术宝库!

在这篇文章中,我们将通过三个实用案例分享 Amazon.com 的研发团队如何通过 “基础架构即代码” 的方式来实现微服务的连续、自动、独立的部署。

这种方式将业务逻辑与微服务以及负责它们的团队对齐,使得问题能够更快地传达给正确的团队,并且可以实现更快地更改并推向生产环境,同时不会干扰其他组件。这加速了业务的创新,也减轻了值班的工作量。

IMDb

互联网电影数据库我们称之为 IMDb ,是世界上最流行的电影、电视和名人内容来源。

多年来,他们的后端一直是一个单体架构,运行在数百个 EC2 实例主机上的 REST API。这种架构虽然有效,但不够灵活,这也意味着运维工程师需要面对繁琐的值班任务。

IMDb 的后端负责提供节目标题、演员姓名、星级评分汇总、图像、发布年份等等。GraphQL 是后端应用很好的选择。使用联合 GraphQL,后端可以被划分为多个微服务,每个微服务专注于特定的业务逻辑:一个用于服务图像,一个用于处理评级,另一个则知道哪些演员出现在哪些节目中。联合 GraphQL 使得每个服务只需要知道它自己的模式,同时客户断可以跨多个微服务完成数据请求。

以下是它的工作原理:

图 2 在左侧显示了一个 GraphQL 查询(缩写),用于在 Jackie Chan 页面上查询“知名作品”的插件,地址指向 https://www.imdb.com/name/nm0000329/?trk=cndc-detail。 演员有以 nm 开头的 ID(例如成龙的 ID 是 nm0000329),而节目(包括电影或电视系列)有以 tt 开头的 ID。查询请求发送给网关,网关了解整个模式,拆分每个部分并路由到适当的微服务(称为图形元素),每个微服务都由 Amazon Lambda 提供计算。Lambda 是无服务器计算,这意味着无需配置服务器,直接运行您的代码。图 2 的顶部的微服务负责展示有哪些电影,下面的微服务负责关于电影的元数据(标题、年份等等),以此类推。

图片


 图 2: IMDb 结合 GraphQL 在实际应用中的效果

网关和每个 graphlets 都是独立栈,可以分别部署。正如我们所看到的,每个 graphlets 的业务逻辑都是被明确定义的,负责这些 graphlets 的团队熟悉它和实现它的技术。一些 graphlet 是由旧服务创建的,并使用 Lambda 作为前端,以便能够将正确的响应形状适应 GraphQL 查询。其他 graphlet 是较新的,完全无服务器化的。旧的也可以被无服务器的替代,而不会对系统的其余部分造成任何干扰。因为没有了单体架构,问题发生在哪里以及哪个团队拥有解决方案变得更加清晰。现在,团队发现值班更轻松了。

Amazon Relay 面向卡车司机的移动应用

亚马逊另一个重要业务就是物流,这也是亚马逊最知名的业务之一。

在 Amazon.com 上购买的物品需要在正确的时间送达正确的位置。在配送中心、邮局和供应商之间,亚马逊在北美有数万个通过大卡车运输货品的转运站(图 3)。

图片


 图 3: 亚马逊的 18 轮卡车,也称为“大型卡车”

多年来,亚马逊已经开发出了复杂的系统模型用来指导将物品投放到正确的位置,但这只是计算机中的程序模型。要实际移动物品,卡车司机需要知道什么时间?去哪里?拿什么?和将其放在哪里?这就是 Amazon Relay 应用的作用。Amazon Relay 应用(图 4)将复杂模型转化为具体可行的行动方式。

Amazon Relay: https://relay.amazon.com/?trk=cndc-detail

图片


 图 4: Amazon Relay 应用程序为卡车司机提供了一切必要的信息。

与 IMDb 类似,Relay 团队设计了一个网关,应用程序与之通信,并将业务逻辑放入多个后端服务中,这些服务称为“模块”。例如,一个服务/模块确认配送中心的访问,并生成在图 4 中可见的门禁通行证,另一个服务/模块用于计算执行(司机何时去哪里)。网关和模块都是独立部署的且具有独立的流水线。

图 5 显示了他们是如何做到这一点的:

图片


 图 5: Amazon Relay 应用程序使用网关和称为“模块”的独立后端服务进行工作。

通过 Amazon API Gateway,用域名作为外部访问的单一入口,并使用基于路径的路由,这样就使得每个调用都能准确对应相应的服务。因此,对 example.com/message 的请求面向运行消息功能的模块,而 example.com/navigate 请求面向导航模块。API Gateway 允许为从指定路径到指定 Lambda 创建对应的 API。新建模块是无服务器架构的,使用 Lambda、DynamoDB(NoSQL 数据库)和 SQS(队列服务)。更新旧模块,将 Lambda 放在前端,并与 API Gateways 进行集成。

Amazon API Gateway: -https://docs.aws.amazon.com/apigateway/latest/developerguide/...

DynamoDB: -https://docs.aws.amazon.com/amazondynamodb/latest/developergu...

SQS: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSD...

团队使用多个 API 网关来隔离他们的应用模块,这使得他们能够独立部署各个模块,先部署对业务不那么关键的模块,如果出现问题可以回滚而不影响关键模块。这是通过利用各模块之间的隔离和分阶段部署实现的。

这种架构更容易实现多区域策略。无论东部还是西部的卡车司机,都可以从更低的延迟中受益,因为他们的请求被指引到更接近他们的 Amazon Web Services 区域。而这种多区域架构对灾难恢复策略也适用,在必要时刻,所有流量都可以路由到某具体的一个区域。有关 Amazon Relay 如何启用多区域的更多详细信息,请参见此视频:https://www.buildon.aws/posts/how-amazon-does-devops-in-real-...

配送中心

我们已经介绍了配送中心之间卡车的运行方式,现在让我们来谈谈配送中心本身。全球范围内,亚马逊运营着 500 多个配送中心。Amazon Fulfillment Technologies and Robotics 是设计、部署和运营支持这些配送中心服务的亚马逊部门。这包括收货系统以及确定物品在仓库中的位置、告诉工作人员在哪里找到满足客户订单的物品、生成运输信息、确定使用哪个包装盒等系统。

正如大家现在所预期的那样,每个服务都独立部署,除此之外,亚马逊还采用了仓储架构来实现更高级别的独立部署。在仓储架构中,每个仓储都是一个独立完整的服务、一个独立实例(图 6),仓储之间没有共享。根据某些关键的分区,入站请求会被指向特定的仓储。

图片


 图 6: 采用仓储架构,每个仓储都是独立完整服务、独立实例,它们是独立的,不互相共享状态。

对于支持亚马逊配送中心系统,配送中心本身是自然的关键。配送中心之间不共享状态,因此将每个配送中心映射到特定的仓储是自然的选择。这样通过故障隔离来提高韧性的最佳实践。具体细节可以考虑图 7:三个配送中心比邻,服务于同一地理区域。

图片


 图 7: Fulfillment Technologies and Robotics 分配配送中心给仓储,以便每个地理区域由分布在不同仓储中的配送中心提供服务。

如果有故障发生,无论是新部署软件中的缺陷,还是基础设施出现了问题,这个具有韧性的架构可以缓解这些故障,这也是仓储架构的存在的意义。故障仅会影响到存在问题的仓储,和他们所匹配的配送中心的运营。但其他仓储受到故障隔离的保护,可以继续正常地响应请求。在图示案例做,故障仅会影响我们组中的一个配送中心(图 8),但由于该地理区域的配送中心位于不同的仓储中,其他配送中心继续为该地区的客户提供服务。

图片


 图 8:隔离将故障限制在一个仓储中,其他仓储正常运行。

每个仓储独立部署,且具有独立的自动化部署流水线。每个仓储都是后端服务的独立堆栈。图 9 显示每个仓储都部署在独立的 Amazon Web Services 帐户中,有一个用于测试的预生产(“pre-prod”)帐户和用于日志数据和跟踪的共享帐户。部署是顺序进行的,等待前一个仓库部署成功并稳定后才部署下一个仓库。

图片


 图 9: 每个仓储都会按顺序在独立的 Amazon Web Services 帐户中部署。

持续、自动化、独立部署取胜

通过上述场景案例,我们看到亚马逊仓库物流系统是如何通过持续化、自动化和独立部署来提升敏捷性、运营效率和弹性的。这些关键理念也适用于云中的任何工作负载。DevOps 模式有助于团队快速创新、灵活响应市场变化并取得业务效益。

请持续关注 Build On Cloud 微信公众号,了解更多面向开发者的技术分享和云开发动态!

往期推荐

#Generative AI 新世界

#架构模型最佳实践

#GitOps 最佳实践

文章作者:Seth Eliot

Principal Developer Advocate, Amazon Web Services

文章译者:郑予彬

亚马逊云科技资深开发者布道师

图片

文章来源:
https://dev.amazoncloud.cn/column/article/64a7b0ffcb09cf15dc4b02ca?sc_medium=regulartraffic&sc_campaign=crossplatform&sc_channel=CSDN 

这篇关于基础架构即代码 | 亚马逊如何在现实生活中实践 DevOps的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/633245

相关文章

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

利用Python调试串口的示例代码

《利用Python调试串口的示例代码》在嵌入式开发、物联网设备调试过程中,串口通信是最基础的调试手段本文将带你用Python+ttkbootstrap打造一款高颜值、多功能的串口调试助手,需要的可以了... 目录概述:为什么需要专业的串口调试工具项目架构设计1.1 技术栈选型1.2 关键类说明1.3 线程模

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

Spring Boot 整合 SSE的高级实践(Server-Sent Events)

《SpringBoot整合SSE的高级实践(Server-SentEvents)》SSE(Server-SentEvents)是一种基于HTTP协议的单向通信机制,允许服务器向浏览器持续发送实... 目录1、简述2、Spring Boot 中的SSE实现2.1 添加依赖2.2 实现后端接口2.3 配置超时时

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指