CQRS - 如何处理查看页面或查询的用户

时间:2010-09-14 02:06:53

标签: c# design-patterns cqrs event-sourcing

我正在将CQRS用于我正在构建的应用程序(具有复杂业务逻辑的在线讨论系统),并且我已经参与了实施工作,让我担心。

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

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

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

你的家伙有什么想法?

4 个答案:

答案 0 :(得分:2)

使用CQRS并不意味着与应用程序的每次微小交互 - 特别是如果我的基础设施相关 - 必须通过命令/事件链。跟踪综合浏览量是一个跨领域的问题,可以很容易地单独实施。

只要在每次调用某些表时,读取层中的查询都会为相应的视图模型增加一个计数器

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

我们做的几乎和此一样。但是跟踪这样的一切感觉不对,你的读取应该很快而且不需要做任何写入。

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

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

答案 3 :(得分:0)

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

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

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

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