根据我对最终一致性的了解,所有这些服务(消费者)将同时接收事件并分别进行处理,在良好的情况下,这将导致数据保持一致。
不,不一定。正如我所评论的,我们无法撤消已发送的电子邮件,因此我们仍然需要某种“顺序”。IPC在事件驱动型数据管理不免除orchestation的1。
例如,除非先前的交易成功完成并且电子邮件服务得到证明,否则不应发送电子邮件。3
但是,如果服务无法处理事件怎么办?例如突然断开连接,数据库错误等...处理这些事务失败的好的模式/做法是什么?
向分布式计算的谬论问好。它们使事情变得复杂,并且像往常一样,没有处理问题的灵丹妙药。
在开始寻找失落的方舟之前,我们必须考虑首先询问组织。通常,解决方案是组织如何在现实世界中面对这些问题。
当某些数据丢失或不完整时,每个人(部门)会做什么?
我们将认识到,不同部门具有不同的解决方案,这些解决方案总共构成了要实施的解决方案。
无论如何,这里有一些实践可以帮助我们制定后续策略。
与其确保系统始终处于一致状态,不如说我们可以接受该系统将在将来的某个时刻得到它。这种方法对于长期的业务运营特别有用。
系统达到一致性的方式因系统而异。它可能涉及从自动化过程到某种人工干预。例如,典型的稍后再试或与客户服务联系。
中止所有操作
通过补偿交易使系统回到一致状态。但是,我们必须考虑到,这些事务也可能失败,这可能导致我们难以解决不一致问题。同样,我们无法撤消已发送的电子邮件。
对于少量事务,此方法是可行的,因为补偿事务的数量也很少。如果IPC中涉及几笔业务交易,那么为每笔交易处理一项补偿交易将是一个挑战。
如果我们进行补偿交易,我们会发现断路器设计模式非常有用- 而且我敢说强制性的 -
分布式交易
这个想法是通过一个称为“ 事务管理器”的总体管理流程,在单个事务中涵盖多个事务。处理分布式事务的常见算法是两阶段提交。
分布式事务的主要关注点在于它们依赖于在其生命周期内锁定资源,而且我们知道,事务管理器也会出错。
如果事务管理器遭到破坏,我们可能会在不同的有界上下文中最终得到几个锁,由于消息的排队而导致意外行为。2
分解操作。为什么?
如果要分解现有系统,并找到确实希望在单个事务边界内的概念集合,则可以将它们保留到最后。
山姆·纽曼
与上述论点一致,Sam在他的《Building Microservices》一书中指出,如果我们确实无法承担最终的一致性,那么我们现在应该避免拆分操作。
如果我们不能将某些操作分成两个或多个事务,则可能会说-可能-这些事务属于相同的有界上下文,或者至少-属于尚待建模的跨领域上下文。
例如,在我们的案例中,我们开始意识到事务#1和#2彼此紧密相关,并且很可能两者都可以属于同一有界上下文Accounts, Users,Register等等。
考虑将两个操作置于同一事务的边界内。这将使整个操作更容易处理。还可以衡量每个交易的关键程度。可能的是,如果事务#2失败,则不应损害整个操作。如有疑问,请向组织询问。
1:不是您想的那种业务流程。我不是在谈论ESB的编排。我说的是使服务对适当的事件做出反应。
2:您可能会发现Sam Newman关于分布式事务的有趣观点。
3:请查看David Parker关于此主题的答案。