东亚银行、岚图汽车带你解锁 AIGC 时代的数字化人才培养各赛道新模式! 了解详情
写点什么

我们为什么从 Lambda 迁移到了 ECS?

  • 2021-05-23
  • 本文字数:3209 字

    阅读完需:约 11 分钟

我们为什么从 Lambda 迁移到了 ECS?

在本文中,我将深入探讨 Lambda 的成功之处,我们面临的挑战,以及为什么我们最终会决定将一些服务从 Lambda 迁移到 AWS 弹性容器服务(Elastic Container Service,ECS)。


我们要解决的问题是什么?


简单介绍一下背景,我们的产品是 B2B 软件公司的一个集成平台,我们帮助软件公司构建集成,并将这些集成部署给他们的客户。一次简单的集成可能如下所示:


  • 步骤一:在 Dropbox 中下拉 XML 文档。

  • 步骤二:使用一些自定义的 JavaScript 代码处理 XML。

  • 步骤三:使用一些存储的凭证,向第三方 API 发布经过处理的数据。


用户可以按计划配置集成以运行,也可以通过 webhook 触发集成,而平台则负责运行、记录和监控集成(以及一大堆其他内容)。

早期情况


Prismatic 的第一个实现使用 LocalStack。我们希望最终把 Prismatic 托管在 AWS 上(根据需要可能会迁移到 Azure、GCP 等),所以需要在本地启动我们的平台来模拟 AWS。类似 AWS Lambda 的 LocalStack 服务易于迭代,并且在运行中不会出现大问题。这为我们提供了一个非常好的开发反馈回路,我们很快进行了原型设计和测试。


在使用 Lambda 执行集成的每一个步骤时,步骤利用 SQS 传递数据并触发下一个步骤。所以,集成的执行情况如下所示:


  • 执行 Dropbox 的“获取文件”动作以抓取 XML 文件。

  • 在 SQS 中保存 XML 文件的内容,触发下一步骤。

  • 运行客户自定义 JavaScript 代码以处理 XML。

  • 在 SQS 中保存生成的转换数据,并触发下一步骤。

  • 执行一个动作,将处理后的数据发布到第三方 API。

  • 保存上一步骤的结果,触发集成结束。


这对于 LocalStack 来说是一个非常快速的过程。我们可以定义一个 6 步集成,运行它,然后在几秒内就能看到结果。

向实际的 AWS Lambda 迁移


当我们的概念被证明可行之后,我们就将 Prismatic 转到实际生产环境中,使用实际的 Lambda、队列、数据库等等。我们还只是一个小团队,不想花太多的时间来解决 DevOps-y 的基础设施问题。我们希望花更多的时间在核心商品上,而 Lambda 能让我们做到这一点。


此外,Lambda 在很多方面都比较有优势。比如,我们无需担心 CPU 或内存分配、服务器监控或自动扩展,因为这些都是内置的。还可以将包含 JavaScript 代码的 .zip 文件放到 Lambda 上,AWS 负责剩下的工作。Lambda 让我们将代码分成一系列服务(一个用于日志记录、一个用于 OAuth 密钥更新、一个用于集成出错时短信 / 邮件提醒等),这样我们就能很好地理解由哪些代码负责哪些任务。成本也很合理:你只需支付计算时间的费用。我们无需全天候运行服务器,只需在我们的原型执行某些任务时付费。


Terraform 上运行几天之后,我们在 AWS 上有了 Prismatic 的第二个实现。集成运行器运行在实际的 Lambda 上,并且被 SQS 触发。此时,我们就要面对集成运行器的性能问题了。

为何 Lambda 无法工作


在 Lambda 中,我们遇到了速度、SQS 大小的限制以及缺少进程隔离等问题。这让我们重新考虑它作为集成运行器的有效性。下面我们依次对这些问题进行讨论:


速度。我在前文提到过,在 LocalStack 内运行 6 步集成只需几秒。但是在实际的 Lambda 和 AWS 中,这花了整整一分钟。实际上,Lambda 调用非常快,通常为几毫秒。但是,在向 SQS 写入步骤结果的过程中,以及在接下来执行下一步骤的过程中,每一步骤都需要几秒钟。对于更为复杂的集成来说,比如那些循环了 500 多个文件的集成,这就成为一个障碍:谁想要花上几分钟(几小时)来完成他们的集成?


为了加快 Lambda 调用的速度,我们尝试了许多方法。根据指导原则,我们为一些 Lambda 实例保留了“热度”,并将驱动 Lambda 的虚拟 CPU 数量增加到了当时能够达到的最高水平(6 个虚拟 CPU/10 GB 内存),但这只会降低我们集成运行时间的个位数百分比。


SQS 的大小限制。SQS 限制消息大小为 256 KB。在集成的各步骤之间传递的数据量通常会超过这个大小(毕竟,集成开发人员现在一个数兆的 JSON 文件进行处理是完全合理的)。要想绕过这个大小限制,推荐的解决方案是向 S3 写入有效载荷,然后通过 SQS 传递对 S3 对象的引用——但是这个对 S3 的 API 调用只会使速度更慢。


结果表明,如果客户在其集成中编写了像 global.XMLHttpRequest = null; 这样不好的代码,依赖 XMLHttpRequest 库的集成随后将在同一个 Lambda 上运行,这将导致错误。这个问题很大,因为一个客户可能会破坏其他客户的 axios。有些客户甚至可能会恶意执行 global.console.log = (msg) => { nefariousCode(); } 之类的操作,同时,当调用 console.log() 时,同一 Lambda 上执行的其他集成将运行 nefariousCode()。


为了解决共享执行空间的问题,我们做了一些尝试。我们曾强迫 Lambda 每次都冷启动(这是一个坏主意,原因显而易见),也曾试过在 chroot jail 中启动不同的 Node 进程。这两种方法都不起作用:在 Lambda 中启动子 Node 进程需要 3~5 秒的时间,并且在一定程度上与 Lambda 的初衷背道而驰。

向 ECS 迁移


在开发方面,Lambda 为我们提供了很好的服务:我们可以快速迭代,并获得一个原型,但是由于 Lambda 面临的各种问题,我们决定咬紧牙关,花一些开发时间在云基础设施上。


为了扩展已有的 Terraform 脚本,并将集成运行器迁移到 AWS 弹性容器服务(ECS),我们的团队已经开始了工作。使用 ECS 容器,我们可以轻松地、快速地使用 chroot,并将 Node 进程彼此隔离,从而解决了 Lambda 中出现的进程隔离问题。为解决 SQS 的大小限制问题,我们改用了 Redis 支持的队列服务。虽然我们重新发明一些 Lambda 免费提供的“轮子”,比如日志、自动扩展和健康检查,但是最终,我们的 6 步测试集成将在 2 秒内恢复运行。


但是,ECS 也并不完美,有些东西需要进行取舍。比如,ECS 的自动扩展似乎没有 Lambda 快。“扩展”似乎要花费一分钟时间,从 API 调用到 AWS Fargate 获取并初始化一个准备好接受工作的容器。我们不得不让一名开发者从产品开发中抽调出来,参与云基础设施的工作,同时在 CPU 和内存使用、自动扩展规则和监控方面也有许多问题需要解决,但在产品开发的这一阶段,这种痛苦是值得的,因为它能让我们为客户提供一个快速的集成运行器。

Lambda 还有什么?


在 Lambda 中,我们并没有移出所有的微服务:许多微服务仍然保留在无服务器的生态系统中,并且在可预见的将来也是如此。集成运行器并不适用于 Lambda,但是对于其他任务,它似乎是一个明确的选择。在 Lambda 中,我们保留了所有重要的集成服务,而这些服务对 Lambda 的实际执行并不重要。其中包括:


  • 从 ECS 中提取日志并将其发送到 DataDog 的记录器服务。

  • 向 PostgreSQL 数据库写入关于集成执行的元数据的服务。

  • 跟踪和排队调度的集成服务。

  • 如果用户的集成出错,就会向用户发送短信或电子邮件通知的警报服务。

  • 针对第三方服务的 OAuth 2.0 密钥更新授权服务。


我们不希望让这些服务妨碍集成的运行,如果它们需要更多的一两秒钟来运行也没有问题,因为对于 Lambda 来说,这样做是很合适的。

总结


当然,随着时间的流逝,我们的基础设施肯定会发生变化,但是我认为我们一直在做正确的决定。通过 LocalStack 的“Lambda”服务,我们可以进行快速地开发和迭代,我们的 AWS 首次部署非常简单,我们的小型开发团队可以更改我们的基础设施,而无需花费大量的开发时间。


Lambda 看起来是一个很有吸引力的解决方案,可以用于托管和扩展我们的微服务,而且对于许多这样的服务,尤其是那些可能需要一到两秒才能运行的一步服务,仍然是正确的选择。但是,对于我们的集成运行器,我们了解到 Lambda 的规模、速度和进程隔离限制使得 ECS 成为更好的选择,并且值得为这个特定服务创建 ECS 部署所需的开发时间。


Lambda 让我们在早期关注产品开发,当时机成熟时,向 ECS 迁移将会非常顺利。尽管我们在 Lambda 遇到了很多困难,但我很高兴我们走上了正规。


作者介绍:


Taylor Reece,Prismatic 开发技术推广工程师,具有 DevOps/ 云的背景。


原文链接:


https://dzone.com/articles/why-we-moved-from-lambda-to-ecs

2021-05-23 18:462883

评论

发布
暂无评论
发现更多内容

阿里一战封神,百万人跪求的Java面试手册终于开源;

Java架构师迁哥

【LeetCode】扁平化嵌套列表迭代器Java题解

Albert

算法 LeetCode 3月日更

如何在3分钟内实现音频变声和趣味音效?

拍乐云Pano

音视频 RTC 出海社交 社交泛娱乐

一文搞懂Flink SQL执行过程

shengjk1

flink flink源码 flink sql flink sql 执行过程

Flink 计算 PV UV

shengjk1

flink flink 实战

Dubbo的设计理念原来就藏在这三张图中

中间件兴趣圈

dubbo RPC

到底什么是Event Loop?那就来了解一下JavaScript分别在浏览器和Node环境下的运行机制吧

零一

JavaScript 大前端

JVM G1GC的算法与实现

Yano

Java JVM GC G1GC

一文搞懂 Flink 中的锁

shengjk1

flink flink 锁

快速使用Vue3最新的15个常用API(1W5+字详解,建议收藏)

零一

vue.js 大前端 Vue3

java deep vs shallow copies

shengjk1

Java deep copy shallow cop

硬件工程师必备,常用元器件封装速查表

不脱发的程序猿

28天写作 电路设计 3月日更 元器件封装速查表 电子设计

超全Android中高级面试复习大纲,在线面试指南

欢喜学安卓

android 程序员 面试 移动开发

想学IT的必看!漫谈MySQL权限安全,分享一点面试小经验

欢喜学安卓

android 程序员 面试 移动开发

Redis新版本开始引入多线程,谈谈你的看法?

Java架构师迁哥

SDK介绍及相关功能测试

行者AI

测试 sdk

万众瞩目的EGG Network,备受期待的New-DeFi自治共识论坛在海口闭幕

币圈那点事

区块链

FlinkSQL 平台

shengjk1

flink flink sql flink sql 平台

图解TCP的通信机制

零一

TCP 网络

寻找被遗忘的勇气(二十三)

Changing Lin

3月日更

4层板到12层板叠层经典设计方案

不脱发的程序猿

28天写作 电路设计 3月日更 PCB PCB布局

Python-计算机视觉-OpenCV-调色板

Aldeo

Python OpenCV

一文搞懂 FlinkSQL函数 LAST_VALUE 的原理

shengjk1

flink flink sql flink 源码

Flink 提交作业运行的各种模式总结

shengjk1

flink flink 执行

nsq源码阅读之diskqueue

werben

nsq Go 语言

已拿到蚂蚁金服Offer!阿里内部二十三万字Java面试题总结

Java架构追梦

Java 阿里巴巴 架构 面试 金三银四

使用Redis,你必须知道的21个注意要点

Java 数据库 redis 架构 面试

SQLServer性能调优方法小结

嘉为蓝鲸

数据库 sql 运维 SqlServer MAXDOP

一文搞懂 FlinkSQL 的 KafkaSource

shengjk1

flink flink源码 flink sql

Flink 计算 TopN

shengjk1

flink flink 实战 flink topN

Swift 5创建和使用Framework, XCFramework 从入门到精通 John 易筋 ARTS 打卡 Week 42

John(易筋)

ARTS 打卡计划 Framework XCFramework

我们为什么从 Lambda 迁移到了 ECS?_文化 & 方法_Taylor Reece_InfoQ精选文章