如何在采用CQRS方法构建的系统中运行周期性任务



事实证明,我需要在我的系统中有一些定期任务,这是在Windows Azure worker角色下运行的。我想强调,它可以是任何平台Azure, Amazon,内部解决方案。就通常的系统而言,这不是一个如何完成任务的问题,但由于我们在云中,并且我的角色可能有几个实例,因此在某些时候可能会出现问题。

所以这里有两个我能想到的方法:

  1. 通常的计时器,它是同步的,通过azure存储,这样就不会多次运行任务。你可以自己实现它,或者从Lokad取一个。您可以在计时器事件上内联执行任务,也可以将命令发送到队列中。

    优点:

    • 常见的方法,每个人都知道计时器和如何烹饪它们
    • 不需要状态。实例启动后,计时器也启动并运行

    缺点:

    • 有额外的逻辑初始化定时器和执行它们旁边的主要部分,只负责处理命令和事件队列。

  2. 一旦我得到启动任务的命令,我发送命令StartTask(30秒)。一旦命令处理程序接收到它,它做需要做的事情,然后重新抛出相同的命令,延迟30秒。

    优点:

    • 完全符合CQRS设计
    • 没有与定时器相关的额外逻辑,纯反应器

    缺点:

    • 打破常规,CQRS本身从一开始就很难治疗和使用。人们倾向于使用已知的技术(通常的计时器),即使它不适合设计(cqrs方法),结果我们有混乱的融合。
    • 又一个被打破的范例。在系统重启时是无状态的还是有状态的?我认为存储在代理消息传递环境中的状态。您所需要做的就是遵循消息处理规则。

我的看法:

就我个人而言,我确实喜欢第二种方法,所有的缺点都应该移到优点部分。

问题:

这里的最佳实践是什么?我错过什么了吗?

我的建议是选择另一个组件来负责周期任务的执行。通过这种方式,您可以决定它应该如何表现,并将其与CQRS工作器分开进行缩放。

如果你更喜欢在Azure中使用一个实例来处理这些任务(周期性和CQRS),你可以将它们转换为Windows服务,并使用你的Worker角色作为安装程序和观察者。我在这里用我的解决方案构建了一个示例。

顺便说一句,如果你使用Lokad。Cqrs,那么你的第二个方法听起来不错,如果它与主组件分开。

使用Windows Mobile Services的调度器或Aditi的Windows Azure Store调度器应用程序怎么样?它们可以用来启动任何东西,你可以让它们向你的系统发送命令。

如果你选择了选项1,那么是的,你将不得不处理同步,但是那里有内置的冗余。如果您执行了选项2,并且处理该命令的实例出现了故障,那么请确保任务不会立即停止。这取决于您如何设置命令重试。

如果您使用azure servicebus作为代理,您可以使用它的延迟消息特性将命令的发送延迟到需要接收的时间。http://code.msdn.microsoft.com/windowsazure/Brokered-Messaging-ccc4f879

计划的时间流逝是一个事件-所以我有一个创建事件的过程,如"ScheduleElapsedEvent"。然后,如果需要,可以实现创建/分派命令的处理程序。

您可以将事件计划保存在支持某种原子更新的数据存储中。它可以是SQL,也可以是NoSQL,比如MongoDB。即使使用副本集和分片进行扩展,您仍然可以使用Mongo检查和更新记录。因此,每个工作进程都可以检查这个调度。

相关内容

最新更新