微服务+ CQRS实现

问题描述 投票:-1回答:1

我正在使用CQRS模式实现微服务架构。我有一个使用API​​网关,Lambda和DynamoDB的有效实现,但有一个例外-事件源。

Event Sourcing让应用程序将通知发布到平台上其他服务可以使用的事件流。此通知表示作为原始HTTP请求的一部分发生的事件。例如,如果用户使用完整的“将患者送入医院检查”模型进行HTTP POST,则Lambda会将其分解并按顺序发布多个事件。

已签入的患者(包括患者ID,医院ID +访问ID)

分配的房间(包括房间号,+访问ID)

已测试的患者(包括已测试的患者+访问ID)

患者已签出(访问ID)

此模式的目的是提供对患者在医院期间发生的所有事件的审核跟踪。此示例(不是我实际构建的示例)将存储在可以随时重播的事件源中。如果在所有服务中都删除了VisitId,我们可以按顺序一次重播事件,并复制原始记录的精确副本。您认为所有记录都是不变的,以实现此目的。每个POST都会推送到事件源,然后进入数据库,该数据库将在HTTP GET请求期间提取数据。订阅者还可以获取这些数据并做其他事情-例如“访问调查”服务,该服务将监听“患者已签出”事件并准备事后调查。

我研究了几种提供此功能的AWS服务。我了解Kinesis Data Streams,但我不喜欢定价结构,也不想处理分片(无自动缩放)。由于我的整个平台都是基于消费定价(Dynamo,Lambda等)构建的,因此我想以相同的方式保留事件源。这使我更容易估​​计每个用户的费用,因为我只是根据每个用户每月的估计请求进行数学计算。

我一直在对流本身使用SNS,传递通知,这很棒。超快速,在开发时没有任何重大问题。但是,问题在于这不适合重播存储-仅传递事件消息。对于一个重播商店,我认为Kinesis Firehose很有道理...同时将其发送到S3 + SNS。事实证明SNS不是可用的传递目的地。我可以自己放入S3,然后发布到SNS,但是当我可以设置S3触发器来触发Lambda并只有另一个小的Lambda对S3中的事件着陆做出反应并执行插入操作时,这似乎是代码库中的重复工作进入DynamoDB。我已经看到,这可能比通过SNS发布要慢得多。我也不确定关于Put事件的重试策略。尽管我可以重用触发的Lambda中的代码来重播存储桶路径中的所有事件,但这简化了重试。

我可以先放入PutObject,然后在同一HTTP POST Lambda中发布到SNS。如果SNS发布失败,那么我现在在S3中有一个从未发布过的对象。我必须写一个不同的Lambda来处理修复和发布。不是世界末日-无论如何,我都有两个Lambda可供部署。我只是不确定哪种方式对AWS服务更有意义。

有人做过类似的事情并且有什么建议吗?我是否正在进入以后将难以管理的技术漏洞?如果我可以将其保持在基于消费的定价模型中,那么我也会开放其他途径。谢谢!

amazon-s3 microservices amazon-sns cqrs event-sourcing
1个回答
1
投票
事件源让应用程序将通知发布到平台上其他服务可以使用的事件流。
[您需要在这里稍加注意-至少有两种不同的“事件源”定义在运行。

[如果您关心事件源,通常是与CQRS结合使用的话(Greg Young等人),那么您的事件

是]您的记录簿。引入的重要复杂之处在于,您的服务在对其进行更改时必须能够

锁定“事件流”(如果没有该锁定,则会遇到“丢失的编辑”场景,并且必须清理混乱) 。因此,“指向您当前更改的指针”必须存在于具有事务性的事物中。 DynamoDB对此应该没问题(根据我对re:Invent 2017的事件采购突破空间的记忆)。在theory

中,您可以将锁锁定在dynamo中,该锁包含指向S3中存储的不可变文档的指针。我无法说服自己权衡取舍证明了复杂性,但最好的是,我可以说该架构中没有任何东西违反物理和因果关系。

如果您的运营团队对Dynamo不满意,则另一个合理的选择是RDS;选择您喜欢的关系数据引擎,向其部署事件存储架构,然后就可以使用了。

关于pub sub部分,我相信您在使用SNS时会走上正确的路。这是将消息从发布者“散布”到多个消费者的正确选择。是的,它不支持重播,但是很好-可以通过记录簿中的[[pulling事件来进行重播。请参阅格雷格·杨Polyglot Data talk的后续部分。是的,有时您会在推式通道和拉式通道上都收到消息,但这很好;当您确定分布式体系结构是一个好主意时,您已经注册了幂等消息处理。

编辑

为什么需要在DynamoDB中存储指针?

因为S3不为您提供任何锁定;这意味着在不愉快的道路上,如果逻辑的两个副本试图写入数据的不同版本,您最终会成为丢失编辑问题的受害者。

您可以使用乐观锁定来管理情况-类似于HTTP的条件PUT;但是S3(我上次检查)不支持条件修改。

可以

使用S3作为

不可变文档的对象存储,但是现在您需要某种机制来确定S3中的哪个文档是“当前”文档。如果尝试在S3中实现该功能,则会再次遇到相同的丢失编辑问题。

因此,您需要使用其他工具来处理那部分问题;一些适合“状态继承”的工具。因此DynamoDB适合安装在这里。

如果使用DynamoDB进行锁定,还可以将其用于事件存储吗?我没有足够的圈数来感到自信,因为我知道那里的答案。对于小问题,我最有信心答案是肯定的。对于大问题...?可能有用的讨论:

Ric Hickey; The Language of the System

肯尼思·特鲁伊斯; Git as a NoSql Database

© www.soinside.com 2019 - 2024. All rights reserved.