我是否需要服务总线来进行简单的异步命令处理?

时间:2012-07-27 21:51:57

标签: c#-4.0 domain-driven-design cqrs message-bus

我的系统使用命令模式和单独的处理程序。我的命令在CommandService上执行,CommandService当前处理所有正在进行的命令。

我有一些命令可以执行至少其中一项操作缓慢的操作:

  1. 发送电子邮件
  2. 生成PDF
  3. 发送传真
  4. 与第三方网络服务进行互动
  5. 我希望所有这些命令都在进程外处理,以便UI更加流畅。

    我应该仅为这些命令使用消息传递总线,还是应该让进程内命令处理程序调用{​​{1}}?

    编辑 - 附加信息

    系统拥有少量用户(忙碌的一天可能会有100个用户),因此队列可能永远不会很长。这里的主要内容是减少发送带有附加PDF(相关命令)的电子邮件时UI被阻止的时间。员工必须在一天内多次执行该命令。

    考虑到整个情况,我认为我现在要使用BeginInvoke(),原因如下:

    1. 必须触摸所有UI交互以确保它们的行为就像命令成功一样。 “您需要发送此文档”的提醒位于用户界面的多个位置,并在报告发送后进行整页刷新。
    2. 这是我客户忙碌季节的中间(他们在夏天他们每年的业务占50%以上),所以我此时似乎并不明智地介绍我所用的全新基础设施不熟悉管理。
    3. 但是知道我现在所知道的,在一个新系统上,我会从一开始就使用服务总线来执行任何慢速命令(几乎每个系统都需要发送电子邮件)并设计UI以便命令可以更容易地从同步切换到异步处理。在实现中,这基本上意味着每个POST都是AJAX,并在UI中执行操作,就像它成功一样。 (有关此示例,请查看Facebook如何处理评论。)

2 个答案:

答案 0 :(得分:2)

这两种解决方案各有利弊。

  • BeginInvoke是致命的简单解决方案,它的语义与直接通过命令调用处理程序相同。但是这个解决方案依赖于线程基础设施:最大线程数,由于并发访问IO资源而冻结的线程等。
  • MessageBus是一个非常灵活和强大的解决方案,您可以在其中控制命令处理过程的各个方面。但它为您的应用程序引入了另一个抽象层,如果更简单意味着更好的话,那将是一个过度工程

我建议您估算系统负载要求,这些后台任务的数量,增长因素等,并依赖于此来做出决定。

但我个人认为,引入适合@ 80%案例的总线解决方案。您可以引入一个天真的总线实现,如果需要,可以在下一次迭代中进行扩展。

答案 1 :(得分:2)

这可能是一个可靠性问题,可以推动你走向消息总线。你看,如果你的原始事务(执行BeginInvoke的事务)成功,然后在你的调用中途服务器崩溃,你的系统将没有内存,它仍然需要发送电子邮件或生成PDF

消息总线可以将第二个事务回滚到队列,这样当服务器再次启动时,它将再次发送电子邮件。