Architecture 无事件源和LMAX风格单线程设计审查的CQR

Architecture 无事件源和LMAX风格单线程设计审查的CQR,architecture,cqrs,Architecture,Cqrs,只是回顾一下我的计划,看看是否可行 Im正在使用RDBMS,并计划在没有事件来源的情况下使用CQR。我认为事件源对于第一次尝试来说有点高级,我不得不使用RDBMS 基于任务的UI由许多命令组成,其中大多数命令不需要响应 建筑基本上是 /---- RDBMS ( EF ) IO ops \ | \ Single threaded Domains Fascade(DT

只是回顾一下我的计划,看看是否可行

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

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

建筑基本上是

            /---- RDBMS ( EF ) 
     IO  ops                 \
            |                 \
  Single threaded Domains   Fascade(DTO) Queries
            |                /
  Event/Command Dispatcher  /
             \             /
                MVC client 
单线程域彼此不通信,它们通过中断器(基本上是环形缓冲区)与外部世界通信

命令调度器将外部事件和命令复制到磁盘,并在崩溃时重新加载它们。已明确标记完成(通过IO Ops)

命令基本上是持久化的(具有命令的事务范围),IO Ops层将捕获所有事件并处理它们,并在一个事务中标记命令完成。(请注意,该命令通过日志服务(而不是域)持久化,但它与IO opps对话,后者将其与该命令的工作相匹配)。如果命令失败,并且其标记为persist(不是全部),则可以重放该命令。(仅当它拥有该命令并接收到DoTransation消息时,才会持久化该命令。)

命令调度器通过中断器连接到域

问题

  • 我应该将整个域加载到内存中(大约300-500兆)并运行它吗?显然,域只有在数据库更新后才会更新

  • 是否可以将外部事件混合回命令分派器中(因此它由单个线程拾取并处理)。事件变成命令

  • 编写域和用户代码看起来很简单(我得到了一个很丰富的域),至少从我正在开发的原型中是这样。是吗

  • 当域执行IO时,它们会向干扰器发送消息,并且可以

    • 指定命令guid,该命令将与 交易
    • 假设完成(射击和祈祷)
    • 提供一个回调命令,该命令传递给命令调度器,然后在域中重新出现。创建IO消息后,系统可以继续 当前命令或完成它并接收下一个命令。
      这够好吗
  • 系统在一个进程和共享内存中运行,但域资源仅由它们自己和一个线程访问。这样行吗


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

    首先,这个架构相当复杂。仔细检查项目的预期寿命是否值得在建筑方面的所有初始投资。一句话:在5年或10年内,这个项目还会付账吗?客户是否会允许您在不提供业务价值的情况下在体系结构上花费数月的时间

    问题

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

    您的问题

    我假设IO操作意味着事件/事件处理程序。可能还有其他细微差别我没有领会

  • 我怀疑这对于web应用程序是否有意义。如果数据库存在性能瓶颈,则在内存中加载域是有益的。根据应用程序的性能配置文件,可能不是这样,管理所有这些线程的工作可能会浪费开发人员的时间。(主要是因为你必须确保在应用程序关闭时停止线程,否则应用程序将永远不会关闭。)DB更新后更新域的部分对我来说没有意义。您只想在启动时加载域。保存域的状态更改只是为了在下次启动时重新加载。我认为您需要先更改域的状态,然后才能将其持久化。此外,如果数据库是一个瓶颈,我可能会异步保存状态

  • 我认为你在这里遗漏了一些步骤。您可能希望获取事件并将其作为命令发送的位置听起来像是流程管理器(如果您愿意,也可以是传奇)应该去的地方。业务流程很少像将事件转换为命令那样简单。例如,当后续命令无法完成时会发生什么情况?或者在发出命令之前需要发生多个事件。(例如,在发送ShipOrder之前,必须发出OrderPlaced和PaymentReceived)

  • 领域中最困难的部分通常是找出最合适的方法对其进行建模。如果您的域模型不适合实际的域,那么代码就会变得更加笨拙和复杂。除此之外,这真的取决于你的领域。如果你的编程是一个微积分解算器,你很可能会喜欢它。但通常业务逻辑一旦被理解,就可以很好地进行编码

  • 我真的不知道你想用事务位做什么。您正在尝试将多个命令包装到一个事务中吗?这可能表示可以更好地对域进行建模,或者您正在进行批处理。由于希望不是很多命令都是成批处理的,所以总是使用一个命令似乎是一种浪费。如果您的所有操作都是批处理的,并且批处理中的每个操作都只是设置单个字段,那么您就真的错过了使用DDD和基于任务的UI的要点

  • 另见#1。如果需要这种级别的性能,这应该很好。您的域很可能作为接收命令的MVC应用程序上的单例托管在内存中。我假设您在访问共享内存时使用了正确的锁定技术。请注意,这是此类主题的一个很好的资源。尤其是,不要被这些错误所愚弄<