当我在 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 微信公众号,了解更多面向开发者的技术分享和云开发动态!
往期推荐
文章作者:Seth Eliot
Principal Developer Advocate, Amazon Web Services
文章译者:郑予彬
亚马逊云科技资深开发者布道师
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。