CQRS可以用于像StackOverflow这样的网站吗?

时间:2010-09-04 11:02:54

标签: architecture cqrs

您是否可以使用CQRS(Command-Query Responsibility Segregation)架构模式来构建StackOverflow之类的网站?我对CQRS和DDD(领域驱动设计)相对较新,我正在探索这种模式,并试图对我熟悉的模式建模。虽然我可以看到CQRS对于像StackOverflow这样的网站的许多方面都很有用,但有一些方面我不确定是否可能(或者,至少,我无法立即弄清楚)。具体做法是:

  • 提出问题当我创建问题时,我会看到它 立即,可以编辑它。在 CQRS,我发出一个命令 'AskQuestion'和一个事件被创建 称为“QuestionAsked”。最终, 问题被推到了 非规范化数据存储。但是,这是 经验很快。这是 可能与CQRS?
  • 投票我的投票 立即反映出来。在CQRS中, 我会想象这些命令/事件 最终通过活动 巴士到读店。但SO给出了 我立即获得了这些信息。

我关注的是SO提供的即时反馈概念。 CQRS可以提供​​这个吗?如果是这样,怎么办呢?那里有很好的例子来说明如何处理这个问题吗?

如果有帮助,我的环境是VS2010 / C#/ SQL2008R2,但我愿意接受其他选项,如SQLite的,等我也期待在NCQRS和LOKAD的框架,与马克Nijhof的样品一起,并就准备下载Greg Young的样本。我没有找到其他CQRS样本的其他内容。

谢谢!

4 个答案:

答案 0 :(得分:6)

您实际谈论的是“最终一致性”,这与CQRS同时讨论,但您可以单独使用这两种技术。

最简单的方法是更新UI正在使用的模型,并使用此模型向用户显示问题以便进一步操作。然后,可以在不阻止UI的情况下继续进行各种工作以使其他用户可以看到更新。为此,您需要验证您的命令,以便在发送之前几乎肯定会成功(如果命令在执行期间失败,那么您将需要处理这种情况,例如将某种类型的回调纳入UI模型)

同样值得注意的是,通常这类事情的“最终结果”如此之快,以至于无论如何都会立即出现,甚至对其他用户也是如此。

答案 1 :(得分:5)

让我们看看这两个问题......

提出问题当我创建问题时,我立即看到它并可以编辑它。在CQRS中,我发出了一个像AskQuestion'并创建一个名为“QuestionAsked'”的事件。最终,问题被推送到非规范化数据存储。但是,SO的经验是即时的。这可能与CQRS有关吗?

这很容易实现。每个用户是否需要立即查看问题,还是只需要提问者?如果每个人看起来需要1-2秒,它会有所作为吗?通常在最终一致的系统中,发送请求的用户与其他每个用户之间存在差异。

投票我的投票立即反映出来。在CQRS中,我想这些命令/事件最终会通过事件总线移动到读取存储。但SO立即给了我信息。

SO会立即给出吗?让我们尝试另一个例子,Facebook。当你点击喜欢的东西时,这会立即出现在你的喜欢中吗?像竖起大拇指的UI技巧让你感觉像它一样。另一个例子,亚马逊。当您点击添加到购物车时它会立即进入您的购物车吗?像"等可视化表示添加到购物车"或者#34;竖起大拇指"让用户觉得它已经完成了。

有许多这样的技巧可以使最终一致的系统感觉像一个完全一致的系统。

作为旁注,许多人认为这些事情是为了扩展性而做的(有时候会这样)。更多时候,他们正在为可靠性而努力。如果XYZ停机,问题就会发生。您是否想要奇怪的随机本地故障,或者您是否希望面临广泛的中断风险?在这里看到的最好的例子之一就是亚马逊购买kindle,奇怪的是他们可以在100ms内处理你的信用卡,而其他人需要3-5秒:)如果他们的信用卡处理系统出现故障会怎样?

答案 2 :(得分:3)

当您提出问题时,您可以“伪造”UI中的数据。看起来它会立即更新给用户(您),但在其他用户看到您的问题之前需要一些时间。你需要做同样的事情来处理投票。

如果您需要立即反馈,可以考虑其他解决方案。但是,您可以采取一些技巧来在CQRS解决方案中提供即时反馈。例如,如果您需要验证用户名是否为uniqe,则可以查询读取数据库以查明用户名是否存在。如果没有,您可以使用它。但是,如果其他用户在此期间选择了相同的用户名,则会在命令端出现冲突。您需要在域模型中处理此问题,例如,为用户提供生成的用户名并通过电子邮件发送给他。他以后可以将其更改为其他内容。

答案 3 :(得分:1)

通过虚假或技巧,您可能会将事件视为“待处理事件”,这可能会在提交/发布阶段成功,但可能会失败。在初始提交提交之前,您执行客户端的验证越多,它就越有可能成功。因此,如果您打算依赖挂起的提交,请在验证和业务规则暴露方面规划更厚的客户端。

然后,可以通过在UI内标记或标记数据作为依赖于“待提交”来允许用户继续使用数据(用于进一步修改)。它将是对象或属性的元属性。当然,添加和使用该元属性会增加复杂性,但取决于应用程序可能是必要的用例。

客户端命令队列/历史记录可能是帮助处理后续事件依赖于最终失败的挂起提交的情况的一种方法。换句话说,依赖于挂起提交的任何内容都可以是历史记录的一部分,可以汇总,保存,同时对失败的挂起提交进行更正,展开并再次应用于已更改和重新提交的挂起事件,并且一旦通知挂起事件在提交中成功,所有后续客户端历史记录将开始展开,提交队列中的下一个项目,将其标记为现在挂起的事件。