您应避免使用的AWS服务

2020-05-10 19:50:51

AWS附带许多组件,涵盖不同的关注领域。但是,大多数都不是通用的,也不够便宜,无法正确应用。如果在错误的上下文中使用,它们最终会浪费时间、资源和金钱,并将在几个月内造成开发人员的摩擦和挫折。

科格尼托在纸面上听起来很棒。它将为您管理用户,包括Google登录、Facebook登录,并处理用户角色分配、重置密码和定义密码规则。它既可以运行在桌面上,也可以运行在移动设备上。它可以与公共用户池和私有用户池一起使用(以限制企业私有资源)。

当向用户请求许可时,Cognito将通过显示它自己的UI来帮助您节省时间。

Cognito有竞争对手:Auth0、OneLogin、Okta等等。如果有足够的时间和团队规模,也可以自己实现上述所有登录工作流。

但是,如果您确实使用Cognito一段时间,丑陋的边缘就会显露出来。您会发现Cognito不能用于Native Mobile登录。当您制作移动应用程序并尝试让用户通过Facebook登录时,如果您已与Firebase集成,则会提示用户打开Facebook应用程序,并允许用户简单地进行身份验证/授权(假设他们已经登录到Facebook应用程序)。

使用Cognito,他们会看到一个嵌入式WebView,提示用户在嵌入式WebView中再次登录Facebook。这造成了很大的摩擦,所以您向询问本地登录的团队提交了罚单。

Cognito确实承诺它将与任何OAuth2身份提供者一起工作。我们认为这意味着我们可以使用它来登录微信,以减少在中国注册应用程序的用户摩擦。经过研究,我们最终选择了微信自己的sdk。使用Cognito实现简单的社交登录没有简单的方法。

如果您需要移动用户管理,那么使用Firebase Social Login会做得更好。开箱即支持Facebook和Google原生社交登录,并在服务器端为您提供足够的支持,为微信用户创建用户记录。

也可以选择滚动自己的认证策略,使用谷歌/苹果/脸书/微信提供的每个SDK。如果你能负担得起时间和工程资源,这是最安全的路线。但是,如果你缺少人力/时间,绝对不要选择科格尼托。它不能在移动环境中交付。

我讨厌云表单。我讨厌“堆栈”参数使用起来非常笨重。模板文件的格式非常冗长。当然,新的YAML CF比旧的JSON CF要好,但是仍然很难读懂复杂的长堆栈。此外,您仍然有一个充满JSON CloudForformation的互联网作为您的参考正文。

您是否需要引用不同堆栈中的一个资源的属性?不行,你需要做输出。好的,如果该堆栈的输出发生更改并需要反映在另一个堆栈中,该怎么办?您需要记住它是在哪里使用的,并执行手动干预。

您是否希望将基础架构的一部分模块化,以便可以跨多个资源重用它?抱歉,您需要使用“嵌套堆栈”,以便在即将陷入IN_PROGRESS或ROLLBACK模式的堆栈上有更多堆栈。明确地说,我要说的是,不要使用嵌套堆栈。

我不喜欢所有的FN:SUB,!参考,FN:加入。老实说,我无法想象一个完整的基础设施会有多个账户、私有网络、子网、对等连接完全记录在CloudForms中。

幸运的是,解决方案很简单!使用Terraform!TerraForm非常棒,我们从2012年初就开始使用它了。它是云不可知论的。您有一个很棒的模块系统,您可以大量使用和利用它,而不必担心自己的生命安全。

您甚至可以使用terraform的count属性在这些模块之上执行逻辑,根据变量添加或不添加资源。

HCL读写美观。TerraForm计划非常适合研究基础设施变化,并让您确信正在改变您的预期。(如果需要,可以使用CF更改集)。

这个故事的寓意是,用大地来减轻自己的压力。使用Terraform,这样您就不会花一整天的时间来担心如何对其他堆栈上下依赖的堆栈进行更改。TerraForm计划。适用TerraForm。

许多初创公司都沦为ElastiCache的牺牲品。这种情况通常发生在团队人手不足、赶在最后期限到来时,他们在AWS控制台中输入Redis:

有什么问题吗?它很贵,而且几个月来没有人注意到。当我们为几个客户做成本分析时,我们已经看到这种情况发生过几次了。首先,默认情况下会给出一个具有健壮cache.r5.Large实例的集群。其次,缓存.*前缀表示此实例的成本为0.216美元/小时,而不是0.126美元/小时,溢价为71.4%。然后,您可能会认为您需要一个用于开发、质量保证和生产的工具。所有这些加起来就是$$。您不会想成为导致AWS账单上3000美元ElastiCache行项目的人。

首先在EC2中运行一段时间的Docker redis。确保它符合您的目的。弄清楚大小对你来说是如何起作用的。请记住,Redis旨在将短暂数据保存在内存中,因此请不要将其视为DB。最好在设计系统时假设Redis可能会丢失内部的任何东西,也可能不会丢失。群集或通过Sentinel实现的HA,都可以在您知道需要时稍后提供!

Amazon Kinesis使您可以轻松地收集、处理和分析实时流数据,以便您能够及时洞察并快速响应新信息。

视频处理/上传等流数据非常适合Kinesis。但是,并不是所有的数据/记录/事件都应该进入Kinesis。它不是通用企业事件总线或队列。

我们曾经在中途加入了一个项目,并且必须支持在部署中包含Kinesis的ETL管道。该应用程序收集小的json记录,并使用python boto3API将它们填充到Kinesis中。另一方面,在EC2/ECS内部运行的工作进程使用boto3拉取这些记录并对其进行处理。然后我们发现,当您有多个Worker时,从Kinesis Streams中检索记录并不是一件容易的事。

您可以使用Kinesis客户端库(KCL)为Amazon Kinesis数据流开发消费者应用程序。虽然您可以使用Kinesis数据流API从Kinesis数据流获取数据,但我们建议您使用KCL提供的消费者应用程序的设计模式和代码。

想象一下,如果您正在运行4个工作进程,并且他们都在监听相同的Kinesis流中的事件。我们如何防止他们参与相同的活动?在传统的排队系统中,您使用锁和所有者列来确保每个任务只由一个工作进程处理。当其中一名工作人员正在处理邮件时,Amazon SQS会将该邮件标记为忙碌,这样其他工作人员就不会重复工作。

要用Kinesis Stream实现相同的模式,您必须实现KCL,它是用Java编写的(Java没有什么问题)。KCL代理将在后台作为第二个守护进程启动,并在应用程序本身接收事件时将事件发送给应用程序。

这意味着:处理Kinesis记录的所有python/ruby/node docker图像都必须安装Java依赖项并在后台运行KCL java进程。KCL通过std-in/out/err与主程序通信,因此从主应用程序进行日志记录也会出现问题!如果应用程序中有bug,您将无法将相关日志打印到STDOUT,因为这会导致KCL代理出错。

此外,为了拥有多个工作进程,Kinesis Streams要求您使用多个碎片。每个工人都会认领一块碎片。更多的碎片=更多的账单。此工作进程到碎片的映射存储在DynamoDB中!因此,简单地说:要将Kinesis用作企业队列,您必须:

将KCL代理捆绑到您的运行环境中,这会增加负载和运行时间,并使日志记录错误变得复杂。

在DynamoDB中购买更多存储空间,以标记哪个工人可以在哪个分片上工作。

正确应用Kinesis流既麻烦又困难,尤其是在寻找企业队列时。如果使用SNS/SQS组合,或者使用基于Redis或传统数据库的排队框架,您会做得更好。

响应来自SNS或SQS的事件-小型异步任务,如图像转换(写入S3)、OCR和ETL(当容量较小时,您可以进行批处理)。

通常情况下,公司可能会选择一个API网关或Nginx来挂载多个微服务,一个用于图书,一个用于用户,一个用于购物车等。或者,他们可能会明智地使用一个整体,将所有4个模块放在一个后端存储库中。

测试单个路由并查看AWS的Lambda UI中的代码变得非常困难。每个lambda都是通过环境变量单独配置的。如果您有5个变量要连接到MySQL RDS实例中,那么突然之间就意味着您有5*100路由=500个变量要在云形成模板中进行配置。

此外,它们中的每一个都将在处理请求时尝试建立数据库连接。对于初学者来说,实际上没有现成的方式在lambdas之间共享资源。

接下来,QA会找到您,询问与QA环境一起使用的后端。继续为所有lambda名称添加“qa-”前缀,并查看lambda仪表板。现在,你有两倍的小羔羊。

接下来,DevOps找到您,询问用于生产环境的后端。继续为所有lambda名称添加“prod-”前缀,并查看仪表板。现在,你有三倍多的小羔羊。

然后您发现代码中的错误,导致请求处理程序抛出HTTP500错误,客户抱怨事情不起作用。您可以深入研究云监视日志。我们有三套原木,全都混在一起。这是不可读的。

几周后,您发现一位队友签入了代码,因此lambdas现在可以递归地调用彼此。这真的很糟糕,因为我们不再知道现在一个请求需要多长时间才能完成。这不仅仅是Lambda的问题,微服务可能会错误地相互调用(这就是为什么我们应该在可能的情况下使用单体)。

QA来找您,他们问如何使用docker在本地运行整个后端堆栈(这是一个合理的要求),这样他们就可以对其运行Selenium或黄瓜测试。当你有数百条路由,每条路由一个小的λ捆绑在一起时,你会怎么做呢?你不能。你的笔记本功能不够强大,不能一次运行所有路线。

DevOps来找您时,我们还想在CircleCI或Jenkins中运行单元测试,以便在您的功能分支合并之前对其进行测试。但是,我们的计算资源有限,不能仅仅为了运行单元测试而启动数百个小的docker进程。

那些本应作为一个整体或小而独立的微服务现在不可能在当地环境中同时运行。

如果您重视交付时间、健全性和工作吞吐量,请不要尝试将Lambda用于rest API端点。使用常规Web框架实现RESTAPI:express/flask/Spring/go-revel/rails。它们都能按预期工作,您会更轻松地使用它们。

好了,这就对了。5我们讨厌的AWS服务。显然,所有这些都有适当的使用方法,但如果您是新手,请小心操作或向专家学习一些设计模式!