事件驱动是什么?

事件通知

当一个系统发送了事件消息通知其它系统在自身域中做改变时,会发生事件通知。事件通知的一个关键因素是源系统并不真正十分关心响应。通常源系统根本就不希望得到应答,或者如果有一个源系统关心的响应,这也是间接的。发送事件的逻辑流与响应该事件的某些反应的任何逻辑流之间会有明显的分离。

事件通知很好,因为它实现了一个低水平的耦合,并且很容易设置。然而,这会成为问题,如果真有一个逻辑流运行了各种事件通知。这个问题是很难看到这样一个流程,因为在任何程序文本中都没有明确。通常,发现此流程的唯一方式是监控实时系统。这样就很难去debug和修改这样的流程。危险在于使用事件通知非常容易实现了良好的系统解耦,而没有意识到你正在失去大规模的流程控制,因此这就给未来几年设置了麻烦。这个模式依然是非常有用的,但是你必须要小心这里的陷阱。

陷阱的一个简单例子是:当一个事件被作为一个被动攻击命令来使用。当源系统期望接收方执行一个动作,并且应该使用命令消息来表明这种意图,但将消息设置为事件的方式时会有问题发生。

一个事件不必携带过多的数据,通常仅仅携带一些id信息和一个返回到发送方的连接,这样可以查询到更多的信息。接收者知道事情已经发生了变化,可能会得到一些关于变化本质的最小信息,然后给发送者发出一个请求决定下一步该做什么。

事件状态转移

当你想更新系统的客户端,又不用通知源系统做进一步工作时,这种模式就出现了。 客户管理系统可能会在客户更改其详细信息(例如地址)时触发事件,事件包含已更改数据详细信息。 然后,接收方可以使用最新数据来更新自己的客户数据副本,这样就无需源客户系统通信,以便以后开展工作。

这种模式明显的缺点就是存在大量数据和副本。 但在海量存储的时代,这个问题也不大。 我们获得更大的弹性,因为如果客户系统出现问题,接收系统仍然可以正常工作。 由于访问客户信息不需要远程调用,这就降低了延时。 我们不必担心客户系统上的负载是否满足所有消费者系统的查询。 但接收方确实就更复杂了,因为它必须维持所有状态,简单点的方式就是在必要时通知发送方获取更多信息。

事件源

事件源主要讲的是,无论什么时候我们去改变一个系统的状态,我们将此做为一个事件来记录状态改变。同时我们确信在未来的任何时间通过重新处理事件能够重建系统状态。事件存储成为事实上的主要来源,系统的状态完全源于事件存储。对于程序员来说,最好的例子是版本控制系统。所有的提交日志是事件存储,源代码树的工作拷贝是这个系统的状态。

事件源介绍了很多议题,我不会在这里逐一介绍,但是我很想强调一些常见误解。事件处理用不着使用异步完成,想一想更新本地git版本库的场景-那是一个完全的同步操作,就像更新subversion这样的集中式版本控制系统一样。当然拥有所有这些提交允许您做各种有趣的行为,git是一个很好的例子,但核心功能提交从根本上说是一个简单的动作。

另一个常见错误就是,使用事件源系统的人都应该理解并访问事件日志来确定有用的数据。但是对事件日志的认识可能是有限的。我在一个编辑器中写这个,它不清楚源代码树中的所有提交,它认为磁盘上只有一个文件。事件源系统中的大部分处理可以基于有用的工作副本。只有真正需要事件日志中信息的那些元素才能处理副本。如果这样有效果的话,我们可以有多个具有不同模式的工作副本;但通常应该在域处理和派生工作副本之间有明确区分。

使用事件日志时,构建工作副本的快照通常很有用,这样你就不必在每次需要工作副本时都从头开始处理所有事件。实际上这里存在二元性,我们可以将事件日志视为变更列表,或者是状态列表。我们可以从另一个派生出一个。版本控制系统通常在事件日志中混合快照和增量,以获得最佳性能。

事件源有许多有趣的优点,在考虑版本控制系统的价值时很容易想到。事件日志提供强大的审计功能(会计事务是帐户余额的事件源)。我们可以通过将事件日志重播到某个点来重新创建历史状态。我们也可以在重播时注入假设事件来探索可代替的历史。事件源使得非持久性的工作副本成为可能,例如记忆图像。

事件源也确实存在一些问题。当结果取决于与外部系统的交互时,重播事件就会出现问题。我们必须弄清楚如何处理随着时间变化的事件模式。许多人发现事件处理为应用程序增加了很多复杂性(尽管我确实想知道这是否是由于派生工作副本的组件与执行域处理的组件之间的分离不良造成的)。

CQRS

命令查询责任隔离(CQRS)这一概念是指读取和写入信息具有单独的数据结构。 严格地说,CQRS 与事件无关,因为在没有任何事件的情况下,你可以在设计中使用 CQRS 。 但通常人们会将 CQRS 与之前的模式结合起来,所以他们会出现在峰会。

CQRS 的意义在于, 在复杂域中单个模型处理读取和写入的会过于复杂,我们可以通过分离模型来简化。 当你在访问模式上有所不同时(例如多读少写),这一点尤其具有吸引力。 但是,使用 CQRS 的收益必须与具有单独模型的额外复杂性相平衡。 我发现很多同事对使用 CQRS 非常警惕,经常被滥用。

弄懂这些模式

作为一名热衷于收集样本的软件植物学家,我发现这是一个棘手的领域。核心问题是混淆了不同的模式。在一个项目中,有能力和经验丰富的项目经理告诉我,事件溯源是一团糟 - 任何改动都需要双倍时间来更新读写模型。就在这句话中,我可以发现事件溯源和CQRS之间可能存在些混淆 - 那么我怎样才能找出哪个是罪魁祸首? 该项目的技术主管声称主要问题是大量的异步通信,当然它是一个已知的复杂性助推器,但并不是一个必须参与事件溯源或CQRS的部分。此外,我们必须要注意所有这些模式在正确的地方都很棒,而在错误的领域上则很糟糕。但是当我们混淆模式时,很难弄清楚正确的领域是什么。

猜你喜欢

转载自blog.csdn.net/hj7jay/article/details/84579750