6

我正在将 CQRS 用于我正在构建的应用程序(具有复杂业务逻辑的在线讨论系统),并且我在实现中遇到了让我担心的部分。

我应该如何处理综合浏览量?如果用户查看线程,我想跟踪它。因为我想跟踪它,所以我应该创建一个命令和一个事件,并将其绑定到负责我正在查看的对象的聚合根(例如,分别为 UserViewsThread 和 UserViewedThread)。但这似乎效率很低——除此之外,没有理由在讨论系统的许多用例(查看论坛/线程)中找到聚合根。现在我正在介绍这个,我将在页面的每个视图上都有一个额外的命令调度和事件发布,这反过来又负责“后台处理”线程聚合,序列化我的事件,并将其发送到我的事件出版商。

必须有更好的方法来做到这一点。我正在考虑也许让我的控制器对象能够调度事件 - 但是通过绕过我的聚合,我不能再将行为附加到页面浏览量。

另一种可能性是使用它作为验证我的用户的方式的想法。将允许 UserViewsThread 和 UserViewsForum 命令引发身份验证异常,让我的控制器知道用户无法执行此操作。但是,如果这些被翻译成事件,并存储在我的事件存储中,我们谈论的是在每个页面视图上创建的多个事件- 这很可能会破坏性能(每个页面视图都会导致数据库事务......呃)和资源管理。

你男朋友的想法是什么?

4

4 回答 4

2

使用 CQRS 并不意味着与应用程序的每一个微小交互——尤其是与基础设施相关的——都必须传递命令/事件链。跟踪页面浏览量是一个跨领域的关注点,可以很容易地单独实施。

每次调用时,只需让读取层中的查询为某个表中的各个视图模型增加一个计数器。

一旦你开始创建每次调用查询时改变状态的命令,你就会再次紧密耦合读取和写入,命令/查询分离的全部好处就会付诸东流。您首先使用 CQRS 来区分这两个问题。

于 2012-11-18T11:38:29.470 回答
1

我们所做的几乎与此相同。但是跟踪这样的所有内容感觉不对,您的读取应该很快并且不需要进行任何写入。

我们最终为所有事件添加了一个跟踪对象,但我认为我不会再这样做了。我会考虑编写一些javascript,就像谷歌分析一样,并从前端创建一个单独的命令。

此外,我会将您的跟踪队列和正常队列分开。

于 2012-11-18T10:06:12.507 回答
1

它似乎是一个网络应用程序,所以我会创建一个属性(asp.net mvc/WebApi)来处理页面视图。当然,该属性只会调用 INFRASTRUCTURE 服务(因为我认为跟踪统计信息不是域的一部分),它只会更新存储中的页面视图。简单地说,该服务调用一个更新持久性的 Dao(更新 Posts set pageviews=pageviews+1)。

当然,该属性可以只发送异步命令来更新将在后台执行的页面视图,因此“写入”实际上不会干扰读取。

如果您的应用程序有/将有大量流量,那么我建议采用以下持久性策略:有一个表 PageViews(PageId,ViewsNumber,TimeStamp),您只需为每个页面视图附加一行。然后每 X 分钟,有一个后台服务将执行 Sum(ViewsNumber) GroupBy(PageId) where TimeStamp> oldTimestamp。您不会在毫秒内获得统计信息,但它们会经常更新,并且应用程序将保持响应。

除了您正在构建分析系统的情况外,我不认为此问题属于任何领域的一部分,因此您不需要 AR、DDD 或事件溯源。对于您的情况,页面统计信息是附加到页面的信息,而不是页面的一部分。仅在您实际在同一视图中显示它们的读取模型中才将它们一起考虑。

于 2012-11-18T10:43:08.037 回答
1

您可以在会话中捕获跟踪信息并偶尔将其发送到服务器。

此外,为什么你认为你真的需要一个带有事件存储的 AR 来跟踪这些信息?我会在一些基于状态的存储中聚合这些信息。

于 2010-09-20T09:04:19.393 回答