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

发布于 2024-09-17 08:23:44 字数 677 浏览 3 评论 0原文

你能使用CQRS(命令-查询职责分离)架构模式来构建像StackOverflow这样的网站吗?我对 CQRS 和 DDD(领域驱动设计)相对较新,正在探索该模式并尝试对我熟悉的该模式的网站进行建模。虽然我认为 CQRS 对于像 StackOverflow 这样的网站来说在很多方面都很有用,但有一些领域我不确定是否可行(或者至少我无法立即弄清楚)。具体来说:

  • 提出问题当我创建问题时,我会看到它 立即并可以编辑它。在 CQRS,我发出如下命令 “AskQuestion”并创建一个事件 称为“提问”。最终, 这个问题被推到了 非规范化数据存储。但SO的 体验是即时的。这是 可以用CQRS吗?
  • 投票 我的投票 立即得到反映。在 CQRS 中, 我会想象这些命令/事件 最终完成事件 乘巴士前往阅读商店。但SO给出 立即向我提供信息。

我真正关心的是 SO 提供的即时反馈的概念。 CQRS可以提供​​这个吗?如果是这样,这将如何完成?有没有很好的例子来说明如何处理这个问题?

如果有帮助的话,我的环境是 VS2010/C#/SQL2008R2,但我对 SQLite 等其他选项持开放态度。我还在研究 NCQRS 和 LOKAD 的框架,以及 Mark Nijhof 的示例,并计划下载 Greg Young 的示例。我没有找到太多其他 CQRS 示例。

谢谢!

Can you use the CQRS (Command-Query Responsibility Segregation) architectural pattern to build a site like StackOverflow? I'm relatively new to CQRS and DDD (Domain Driven Design) and am exploring the pattern and trying to model sites that I'm familiar with to the pattern. While I can see CQRS being useful for many aspects for a site like StackOverflow, there are a few areas that I'm not sure are possible (or, at least, I can't figure out immediately). Specifically:

  • Asking questions When I create a question, I see it
    immediately and can edit it. In
    CQRS, I issue a command like
    'AskQuestion' and an event is created
    called 'QuestionAsked'. Eventually,
    the question gets pushed to the
    denormalized data store. But SO's
    experience is immediate. Is this
    possible with CQRS?
  • Voting My votes
    are reflected immediately. In CQRS,
    I would imagine these commands/events
    eventually moving through the event
    bus to the read store. But SO gives
    me the information immediately.

My concerns are really around the concept of immediate feedback that SO provides. Can CQRS provide this? If so, how would this be done? Are there good examples out there that illustrate how to handle this?

If it helps, my environment is VS2010/C#/SQL2008R2, but I'm open to other options like SQLite, etc. I'm also looking at NCQRS and LOKAD's frameworks, along with Mark Nijhof's sample and am planning on downloading Greg Young's sample. I didn't find much else out there for CQRS samples.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

故人如初 2024-09-24 08:23:45

当您提出问题时,您可以“伪造”UI 中的数据。对于用户(您)来说,它看起来像是立即更新的,但其他用户需要一段时间才能看到您的问题。您需要做同样的事情来处理投票。

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

When you ask a question, you can "fake" the data in the UI. It will look like it was updated immediately to the user (you), but it will take some time before the other users will see your question. You need to do the same thing to handle voting.

If you need immediate feedback, you might consider other solutions. But, there are some tricks you can do to give immediate feedback in a CQRS solution. If you, for example, need to validate that a username is uniqe, you can query the read database(s) to find out if the username exists. If it doesn't, you can use it. But, if a other user have choosen the same username in the meantime, you will get a conflict on the command side. You need to handle this in your domain model, and, for example, give the user a generated username and send it to him by e-mail. He can later change it to something else.

江城子 2024-09-24 08:23:45

通过伪造或欺骗,您可能会将该事件视为“待处理事件”,该事件可能在提交/发布阶段成功,但也可能失败。在初始提交之前,您在客户端执行的验证越多,成功的可能性就越大。因此,如果您打算依赖待处理的提交,请在验证和业务规则公开方面规划更厚的客户端。

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

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

By fake or trick, you might think of the event as a "pending event", something that is likely to succeed in the commit/publish phase, but could fail. The more validation you perform clientside, prior to initial submit for commit, the more likely it will succeed. So if you intend to rely on a pending commit, plan for a thicker client in terms of validation and business rule exposure.

One could then allow the user to continue to use the data (for further modification) by marking or tagging the data within the UI as relying on "pending commit". It would be a meta attribute of the object or attribute. Of course adding and using that meta attribute will increase the complexity, but depending on application might be a necessary use-case.

Client-side command queues/histories might be one way to help handle situations where subsequent events relied on an ultimately failed pending commit. In other words, anything that relies on a pending commit could be part of a history that could be rolled up, saved while corrections are made to the failed pending commit, unrolled and reapplied to the changed and resubmitted pending event again, and once notification that the pending event was successful in commit, all subsequent client side history would start to unwind, submitted the next item in the queue, marking it as the now pending event.

薄荷梦 2024-09-24 08:23:44

让我们看一下两个问题...

提出问题 当我创建问题时,我会立即看到它并可以对其进行编辑。在 CQRS 中,我发出“AskQuestion”之类的命令,并创建一个名为“QuestionAsked”的事件。最终,问题被推送到非规范化数据存储。但SO的经验是立竿见影的。这可以通过 CQRS 实现吗?

这很容易实现。是每个用户都需要立即看到问题,还是只需要看到提出问题的人?如果它需要 1-2 秒的时间才能出现在每个人面前,会有什么不同吗?最常见的是,在最终一致的系统中,发送请求的用户与其他用户之间存在差异。

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

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

有很多类似的技巧可以使最终一致的系统感觉像一个完全一致的系统。

顺便说一句,许多人认为此类事情是为了可扩展性而完成的(有时确实如此)。更多时候,这样做是为了可靠性。如果 XYZ 宕机,就会出现这个问题。您想要奇怪的随机局部故障还是想要冒大范围中断的风险。这里看到的最好的例子之一是在亚马逊上购买 Kindle,奇怪的是他们可以在 100 毫秒内处理你的信用卡,而其他人只需要 3-5 秒:) 如果他们的信用卡处理系统出现故障会发生什么?

Let's look at the two questions...

Asking questions When I create a question, I see it immediately and can edit it. In CQRS, I issue a command like 'AskQuestion' and an event is created called 'QuestionAsked'. Eventually, the question gets pushed to the denormalized data store. But SO's experience is immediate. Is this possible with CQRS?

This can be easily achieved. Does every user need to see the question immediately or just the person asking it? If it takes 1-2 seconds for it to appear to everyone would it make a difference? Most often in eventually consistent systems there is a difference between the user sending a request vs every other user.

Voting My votes are reflected immediately. In CQRS, I would imagine these commands/events eventually moving through the event bus to the read store. But SO gives me the information immediately.

Does SO give it immediately? Let's try another example, Facebook. When you click like on something does this immediately show up in your likes? UI tricks like putting a thumbs up make you feel like it does. Another example, amazon. When you click add to cart does it immediately go into your cart? Visual representations like "added to cart" or a "thumbs up" make you as a user feel like its been done.

There are many tricks like these that can make an eventually consistent system feel like a fully consistent system.

As a side note many people think these kinds of thing are done for scalability (which is sometimes the case). More often they are being done for reliability. The question becomes happens if XYZ is down. Do you want weird randomized local failures or do you want to risk a wide spread outage. One of the best examples to see here is checking out on amazon for a kindle purchase, its weird that they can process your credit card in like 100ms while everyone else takes 3-5 seconds :) What happens if their credit card processing system is down?

极致的悲 2024-09-24 08:23:44

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

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

还值得记住的是,通常此类事情的“最终发生”是如此之快,以至于所有内容都会立即出现,即使对于其他用户也是如此。

What you're actually talking about is 'eventual consistency' which is frequently talked about at the same time as CQRS, but you can use either technique independently.

The simplest thing to do is to update the model which the UI is using immediately and use this to show the question back to the user for further manipulation. The various bits of work to be done so that the other users can see the update can then proceed without blocking the UI. For this to work you need to validate your command so that is almost certain to succeed before sending it off (if the command fails during execution then you'll need to handle the situation, e.g. incorporate some sort of call back to the UI model).

It's also worth bearing in mind that usually the 'eventuallness' of this sort of thing is so quick that everything will have appeared immediately anyway, even to other users.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文