在我回答我的问题之前,让我勾勒出一组样本微服务来说明我的困境。
假设我有4个微服务:
激活服务,其中(de)激活了提供给客户的功能。 注册服务,可以添加和更改成员。 安全密钥服务,能够为与外部世界通信的成员生成安全密钥(在多步骤过程中)。还有通信服务,用于与外部供应商就我们的成员进行沟通。
安全密钥服务可能只会请求安全密钥(如果这是激活的功能)。此外,通信服务只能与具有安全密钥的成员进行通信,并且如果通信功能本身已激活,则可以进行通信。
因为它们是微服务,所以每个服务都拥有自己的数据存储,并且完全自给自足。也就是说,其他微服务所需的任何数据都在本地复制,并通过来自其他微服务的异步消息保持同步。
我实际上面临着两个主要的两难困境。第一个(很明显)是数据同步。当有多个数据存储需要保持同步时,您必须考虑丢失或无序处理的消息。但是有很多开箱即用的解决方案,当一切都失败时,你甚至可以回到某种ETL过程来保持同步。
然而,我面临的主要问题是需要执行的操作。在上面的示例中,安全密钥服务必须在
时执行操作在这两种情况下,这意味着来自外部系统的消息必须同时导致数据本地副本的更新以及需要处理的某些逻辑。
现在回答实际问题:)
在处理这些邮件时,建议采用哪种方式处理错误或新见解?假设激活服务的消息处理程序中存在错误。处理程序确实更新了内部数据结构,但它无法检测到已经注册的成员,因此从未启动安全密钥生成进程。或者可能是没有错误,但我们认为还有其他东西我们希望处理程序做。
系统没有理由重新提交或重新处理消息(因为消息没有失败),但我们没有真正的方法可以重新触发后面的行为。消息。
我希望我明白我要问的是什么(如果它应该发布在任何其他170个Stack ...网站上我真的很道歉,我真的知道StackOverflow)
答案 0 :(得分:1)
我不知道推荐方式是什么,我知道如何在DDD中完成此操作,也许这可以帮助您,因为DDD和microservices
是朋友。
您所拥有的是一个长期/多步骤的过程,涉及来自多个微服务的信息。在DDD中,这可以使用Saga/Process manager来实现。 Saga通过订阅来自registration service
和activation service
的事件来维持本地州。随着事件的发生,Saga通过提交CreateSecureKey
命令检查它是否具有生成安全密钥所需的所有信息。事件可能以任何顺序出现,甚至可以重复,但这不是问题,因为Saga可以弥补这一点。
如果出现错误或新功能,您可以创建特殊脚本或其他进程来搜索特定情况并通过提交特定补偿命令来处理它,而无需重新处理所有过去的事件。
如果是新功能,您甚至可能需要处理现在对您的业务流程感兴趣的旧事件。您可以通过查询新有趣的旧事件的事件源并将它们发送到新更新的Saga以相同的方式执行此操作。在导入过程之后,您将Saga订阅到这些新的有趣事件,并且Saga继续照常运行。