活动海报

2005年12月30日

这是一种我遇到过几次的应用程序风格。该应用程序主要是一个报告应用程序,为用户提供有关某事物状态的实时信息。它是一个主动应用程序,因为用户对他们查看的内容类型有很大控制权,他们能够深入特定领域并通常操纵他们的显示;但是,它仍然,至少主要是一个只读应用程序。

这种应用程序的另一个特点是它是一个事件溯源应用程序,即对显示状态的所有更新都是通过可以存储和排队的事件对象进行的。这些事件可以是为应用程序定制的,也可以是外部消息流。克里斯·史蒂文森告诉我一个事件海报的例子:Inkblot,它使用了一个为另一个应用程序编写的数据库表,其中行被插入为事件。

将这两个特点结合起来,您就会发现,没有必要使用数据库来保存显示的内存状态。通常会有一些初始状态加载到系统中,例如一天开始时的世界,之后所有更改都是通过事件流进入事件海报的内存状态进行的。如果应用程序出现故障,它只需重新加载初始状态并重放队列中的所有事件。

不持久化应用程序状态有两个主要优势:首先,应用程序非常快,因为在人们操作系统时不涉及磁盘访问。马塞尔·魏赫告诉我,BBC 的一个新闻提要应用程序,其以前版本在生产环境中处理一个请求需要几秒钟,而替换的事件海报应用程序在他的笔记本电脑上轻松地每秒处理数百个请求。

其次,消除了内存与数据库之间映射的所有复杂性,这使人们能够构建一个面向显示需求的良好领域模型,而无需担心持久化它。(如果显示行为恰好与关系行为匹配,这可能不是一个很大的优势,因为在这种情况下,SQL 更有优势。)

显然,这种应用程序有一些限制。您受到内存中可以容纳的数据量的限制,尽管如今主内存可以容纳大量数据,但不久前,千兆字节数据库被认为非常大。您还会遇到事件溯源的其他限制。

这种系统很容易集群。您只需确保将事件广播到所有副本。如果一个副本出现故障,很容易用另一个副本替换它,因为状态始终会保持同步。

我说这些应用程序是只读的,但这并不完全正确。要进行更新,海报只需捕获信息并将其发送到作为事件源的后端应用程序。它不会直接更新自己的数据,而是等待来自源应用程序的流中出现相应的事件。这确保了多个海报显示相同的数据,并且源应用程序可以对更改进行任何必要的处理。

我们一直在努力为这种应用程序找到一个好名字。有几个重要的特点,如果名字能唤起这些特点就好了:事件流、瞬态数据、仅显示。我认为“海报”很好,因为它让我想起了那些每天早上被撕下并更换的带有当天新闻的公告板。

对于使用CQRS 和事件协作的系统,事件海报是一个自然的选择。