如何基于外部事件可靠地创建工作流实例?

时间:2020-03-05 18:39:39  来源:igfitidea点击:

Windows工作流程的一些新知识,轻松点:)

我希望设计一个具有高可用性的工作流主机环境,在单独的硬件上至少有2个WF运行时主机都指向相同的持久性或者跟踪SQL数据库。

我正在寻找一种模式,可以根据某个外部事件异步创建新的工作流实例(即,某些数据由其他应用程序在DB中更新)。对于每个事件,我只需要创建一个工作流实例,而与创建该实例的主机无关。关于事件与实际创建工作流实例之间的持续时间,还存在一些灵活性。

我正在考虑的一种解决方案是在WF主机上具有WCF接口,并将它们放置在某种负载均衡器之后。然后取决于触发"事件"进行WCF调用的系统的任何部分。

我对此并不满意,因为如果两个\所有WF主机都关闭,或者由于其他原因而无法使用,则该事件可能会"丢失"。另外,我将无法以自己想要的方式管理负载。我设想在短时间内可能会发生许多事件的情况,但是稍后再处理这些事件是完全可以接受的。

因此,我认为我需要以某种方式保留事件并将事件创建与事件处理分离。

将这些事件放入MSMQ或者SQL Server中的简单事件表,并让WF主机只是定期轮询队列是一种可行的解决方案吗?轮询似乎是一个很肮脏的词...

NServiceBus和持久消息传递在这里有用吗?

任何见解将不胜感激。

附录

该数据库将与共享光纤通道存储一起群集。网络也将是冗余的。为了使WF运行时实例具有故障转移功能,它们必须指向公共持久性服务,在这种情况下,该服务是SQL后端。它的高可用性,而不是总可用性:)

有关WF可靠性和高可用性的MSDN文章

而且,WF运行时的每个实例必须运行完全相同的位,因此升级将需要同时将它们全部清除。我喜欢在不需要关闭整个系统的情况下能够做到这一点的想法。

解决方案

回答

我将使用MSMQ /事件表。仅当我们做错了时,轮询才是肮脏的。

要记住的一件事:我们说要使用多个WF服务器以实现高可用性,但是它们都使用相同的SQL后端?高可用性仅在删除所有单个故障点(而不仅仅是其中一些故障)时才起作用。

回答

如果将WCF服务与netMsmqBinding一起使用,则无需轮询即可接收排队的消息。如果没有正在运行的服务来接听消息,则消息将等待。我们可能要确保使用群集队列来提高可靠性,以防主排队机出现故障。

另外,在升级时请注意,我们无法从旧版本的服务中恢复实例。因此,要升级长期运行的工作流程,我们需要使它们停止接收新请求,并等到所有实例完成后再更改位,否则旧实例将永远停留在持久性存储中。

回答

这就是我解决的方法。

我正在使用NServiceBus,并且每个WF运行时主机都指向同一消息总线(使用MSMQ作为传输)。 NServiceBus支持事务性读取消息总线和回滚。如果从总线上删除了一条消息,但是该过程在消息得到完全处理之前终止,则该消息将保留在队列中,并且其他运行时主机将提取该消息。

为了使WF运行时主机在单独的计算机上运行,​​由于早期版本的MSMQ不支持远程事务读取,因此messagebus \ queue必须驻留在Windows 2008服务器(MSMQ 4.0)或者更高版本上。另请注意,为了执行远程事务读取,执行读取的计算机还需要安装MSMQ 4.0(即Windows Server 2008)。