2012-11-04 34 views
2

只是审查我正在计划,看看它是否可以工作。cqrs没有事件采购和LMAX风格单线程设计审查

我正在使用RDBMS并计划在没有事件源的情况下使用CQRS。我认为事件采购对于第一次尝试有点高级,我不得不使用RDBMS。

基于任务的UI由许多命令组成,其中大多数命令不需要响应。

架构基本上是

  /---- RDBMS (EF) 
    IO ops     \ 
      |     \ 
    Single threaded Domains Fascade(DTO) Queries 
      |    /
    Event/Command Dispatcher/
      \   /
       MVC client 

单线程域不相互交谈,他们通过干扰(基本上环形缓冲器)聊到了外面的世界。

命令调度程序将外部事件和命令复制到磁盘并在崩溃时重新加载它们。完成显式标记(由IO Ops)。

命令基本上会被持久化(使用命令的事务范围),IO Ops层将获取所有事件并处理它们并在1个事务中标记命令完成。 (请注意,该命令通过日志服务持续存在,而不是域,但它与IO opps进行通信,使其与命令的工作匹配)。如果命令失败并且其标记持续(不是全部),则可以重播。 (它只在命令有命令并且已收到DoTransation消息时才持续执行命令。)

命令调度程序通过disruptor连接到域。

问题

  1. 我应该加载整个域到内存?(约300 - 500 MEG)和该运行显然域只会数据库更新后更新。

  2. 可以将外部事件重新混合到命令调度程序中(所以它会被单线程处理并处理)。例如事件变成命令。

  3. 看起来很简单的代码域和用户代码(我得到一个很好的丰富的域),至少从我正在工作的原型。是吗?

  4. 当域做IO他们将消息发送到一个破坏者,并可以

    • 指定命令GUID和命令被匹配了一个 交易
    • 承担完成(拍摄和祈祷)
    • 提供回调命令,将其传递给命令调度程序,然后再出现在域中。创建IO消息后,系统可以继续使用当前命令或完成当前命令并接收下一个命令。
      这够好吗?
  5. 系统运行在一个进程和共享内存中,但域资源只能由自己和1个线程访问。这个可以吗?

这是一个实验性的微米网格。有什么想法吗?

回答

3

首先,这个架构相当复杂。仔细检查一下,项目的预计寿命是否值得在体系结构中进行初始投资。底线:这个项目是否会在5年或10年内支付账单?客户是否会允许您花费数月的时间在架构上而不提供业务价值?

问题

你没有提到什么承载您的命令调度。无论这件作品是什么,它很可能是您的应用程序的瓶颈。除非它将消息从一个非常高性能的队列中取出(例如ZeroMQ),否则我不认为你需要一个环缓冲区。队列在大多数情况下都会很好,而且更简单。

您的问题

我假设IO行动意味着事件/事件处理程序。可能还有其他的细节我没有抓到。

  1. 我怀疑这对web应用程序是否真的有意义。如果您的数据库是性能瓶颈,那么将该域载入内存是有益的。根据您的应用程序的性能配置文件,可能不会,并且管理所有这些线程的努力可能会浪费开发人员的时间。 (主要是因为您必须确保在应用程序关闭时停止线程,否则应用程序将永远不会关闭。)在更新数据库之后更新域的部分对我来说没有意义。您只想在启动时加载域。保存域的状态更改只能在下次启动时重新加载。我认为你需要改变域的状态,然后才能坚持下去。另外,如果数据库有那么多瓶颈,我可能会异步保存状态。

  2. 我想你错过了这里的一些步骤。您可能想要参加一个活动并将其作为一个命令发送,听起来就像流程管理器(或者,如果您喜欢佐贺)应该去的地方。很少有业务流程像总是将事件转换为命令一样简单。例如。后续命令无法完成时会发生什么?或者在发布命令之前需要发生多个事件。 (例如,OrderPlaced和PaymentReceived必须在发送ShipOrder之前发生)

  3. 域的难题通常是找出建模它们最合适的方法。如果您的域模型不适合实际的域,那么代码会变得更加尴尬和复杂。除此之外,这真的取决于你的域名。如果你编写一个微积分求解器,你可能会为此付出代价。但是,一旦理解,业务逻辑通常可以合理编好。

  4. 我真的不知道你想用交易位做什么。你是否想将多个命令包装到一个事务中?这可能表示域可以更好地建模,或者您正在进行批处理。因为希望没有那么多命令被批量处理,似乎总是使用一个命令是浪费。如果您的所有操作都是批处理的,并且批处理中的每个操作都只是设置单个字段,那么您确实错过了使用DDD和基于任务的UI的要点。

  5. 另请参阅#1。如果需要这种级别的性能,这应该没问题。您的域很可能会在接收命令的MVC应用程序中作为单身存储在内存中。我假设你在访问共享内存时使用了正确的锁定技术。请注意0​​是这些主题的一个很好的资源。特别是,不要被volatile关键字愚弄!

只记得一切都是取舍。不要浪费大量时间开发并不能真正为您的应用带来好处的架构。