根据您对该分布式系统设计的控制程度,如果您退后一步并尝试在您已将问题缩小到目前的解决方案领域之外进行思考,那么它的架构可能会更好。您已经确定“主要问题”是寻找分布式服务通过公共数据库相互通信的方法。也许这是你应该挑战的想法。
这些组件有许多潜在的通信方式,如果您的设计目标是减少延迟并因此避免轮询,实际上这可能是需要通知服务完成此工作项的正确方式马上。但是,如果将来该系统的吞吐量必须增加,则批量处理工作项并轮询信息可能成为唯一可行的选择。这也是为什么我选择更笼统地表达我的答案并更抽象地讨论这个分布式系统的设计的原因。
如果在此考虑之后您的答案保持不变并且您确实希望立即通知,请考虑让处理工作项的组件通知需要通知的组件。作为分布式系统的一般设计原则,最好让对给定数据集最权威的组件也成为回答有关该数据的请求的组件。在这种情况下,您拥有的数据是工作项的完成状态,因此对此采取行动的最佳组件将是完成工作项的组件。该组件最好通知调用客户端和组件该完成。在这里'
但是,我认为可能有正当的理由,为什么您不希望进行这样的调用,例如减少组件之间的耦合或无法以直接方式与其他组件通信。有许多允许此类通知的通信原语,例如 Windows 下的 MSMQ,或 Windows Azure 中的队列。还有一些反对它的原因,例如依赖于系统内通信的第三个组件,这可能会降低系统的可用性并导致中断。您可能想在这里问自己的问题是:“当周围的一切都发生故障时,我的组件可以做多少工作?” “在可靠性和可用性方面,我对该系统的设计优先级是什么?”
所以我认为你可能真正想要解决的主要问题是更抽象一点:这个分布式系统的组件通信的接口应该是什么样的?
如果在所有这些之后,您仍然设置这些组件之间的通信接口是 SQL 数据库,您可以探索在 SQL 中使用 INSERT 和 UPDATE 触发器。您可以轻松查找这些命令的语法并指定随后执行的存储过程。在这些存储过程中,您可能希望检查任何新行的完成标志,并可能限制您按日期检查的行数或具有最后处理的工作项的 ID。然后通知其他组件,您可以使用内置存储过程XP_cmdshell
在 Windows 下执行命令行。您执行的命令可能是一个简单的工具,可以 ping 您的服务以完成任务。
很抱歉最初忽略了您使用 SQL 查询通知的建议。这也是一种可行的方式,通过 Service Broker 组件工作。您将定义一个SqlCommand
,就像通常查询您的数据库一样,将其传递给一个实例,SqlDependency
然后订阅名为 的事件OnChange
。一旦你执行了SqlCommand
,你应该会调用你添加到的事件处理程序OnChange
。
但是,我不确定如何从SqlNotificationEventArgs
将传递给事件处理程序的对象中获取对数据库的确切更改,因此您的查询可能需要足够具体,以便应用程序随时告知工作项已完成查询更改,或者您可能必须在每次收到通知时从应用程序到数据库进行另一次往返,以便能够知道究竟发生了什么变化。