3

我有这种情况,我真的不知道从哪里开始。假设在服务器上托管了一个类似 Web 服务的应用程序(可能是 API)。该应用程序接收到处理某些数据的请求(通过某种方法,我们将调用 processData(data theData))。

另一方面,有一个处理数据的机器人(可能安装在同一台服务器上)。因此,Web 服务将请求插入到一个公共数据库(两个程序都可以访问它),它应该等待该行更改并将结果发回。

机器人定期检查数据库中的新行,处理数据并为该行设置某种标志,表明数据已被处理。

所以这里的主要问题是,proccessData(..) 方法应该如何检查数据行的变化?

我知道一种方法:我可以构建一个迭代块,每 x 秒检查一次行。但我不想那样做。我想要做的是构建某种事件侦听器,当行更改时触发。我知道它可能涉及一些异步编程

我可能在做梦,但在网络环境中这是否可能。?

我一直在阅读有关 SqlDependency 类、Async 和 AWait 类等的信息。

4

2 回答 2

0

您指的是消息队列吗?.Net 框架已经提供了这种功能。我想说让 Web 服务管理应用程序级别的队列。机器人将请求相同的 Web 服务来完成任务。假设作业所需的数据很小,您可以将整个数据保存在内存中。如果您还没有数据库,我宁愿不涉及数据库。

于 2013-10-16T22:55:58.010 回答
0

根据您对该分布式系统设计的控制程度,如果您退后一步并尝试在您已将问题缩小到目前的解决方案领域之外进行思考,那么它的架构可能会更好。您已经确定“主要问题”是寻找分布式服务通过公共数据库相互通信的方法。也许这是你应该挑战的想法。

这些组件有许多潜在的通信方式,如果您的设计目标是减少延迟并因此避免轮询,实际上这可能是需要通知服务完成此工作项的正确方式马上。但是,如果将来该系统的吞吐量必须增加,则批量处理工作项并轮询信息可能成为唯一可行的选择。这也是为什么我选择更笼统地表达我的答案并更抽象地讨论这个分布式系统的设计的原因。

如果在此考虑之后您的答案保持不变并且您确实希望立即通知,请考虑让处理工作项的组件通知需要通知的组件。作为分布式系统的一般设计原则,最好让对给定数据集最权威的组件也成为回答有关该数据的请求的组件。在这种情况下,您拥有的数据是工作项的完成状态,因此对此采取行动的最佳组件将是完成工作项的组件。该组件最好通知调用客户端和组件该完成。在这里'

但是,我认为可能有正当的理由,为什么您不希望进行这样的调用,例如减少组件之间的耦合或无法以直接方式与其他组件通信。有许多允许此类通知的通信原语,例如 Windows 下的 MSMQ,或 Windows Azure 中的队列。还有一些反对它的原因,例如依赖于系统内通信的第三个组件,这可能会降低系统的可用性并导致中断。您可能想在这里问自己的问题是:“当周围的一切都发生故障时,我的组件可以做多少工作?” “在可靠性和可用性方面,我对该系统的设计优先级是什么?”

所以我认为你可能真正想要解决的主要问题是更抽象一点:这个分布式系统的组件通信的接口应该是什么样的?

如果在所有这些之后,您仍然设置这些组件之间的通信接口是 SQL 数据库,您可以探索在 SQL 中使用 INSERT 和 UPDATE 触发器。您可以轻松查找这些命令的语法并指定随后执行的存储过程。在这些存储过程中,您可能希望检查任何新行的完成标志,并可能限制您按日期检查的行数或具有最后处理的工作项的 ID。然后通知其他组件,您可以使用内置存储过程XP_cmdshell在 Windows 下执行命令行。您执行的命令可能是一个简单的工具,可以 ping 您的服务以完成任务。

很抱歉最初忽略了您使用 SQL 查询通知的建议。这也是一种可行的方式,通过 Service Broker 组件工作。您将定义一个SqlCommand,就像通常查询您的数据库一样,将其传递给一个实例,SqlDependency然后订阅名为 的事件OnChange。一旦你执行了SqlCommand,你应该会调用你添加到的事件处理程序OnChange

但是,我不确定如何从SqlNotificationEventArgs将传递给事件处理程序的对象中获取对数据库的确切更改,因此您的查询可能需要足够具体,以便应用程序随时告知工作项已完成查询更改,或者您可能必须在每次收到通知时从应用程序到数据库进行另一次往返,以便能够知道究竟发生了什么变化。

于 2013-10-16T22:05:34.830 回答