2015-10-19 62 views
4

我目前在SQL Server 2012 Service Broker中使用SqlDependency,我希望能够配置两个服务器,既监听服务代理,也提供消息队列一次只能从队列中拉出。每台机器都应该尝试并尽可能减少它的成本,但是如果有太多的机器进来,它应该分享一个平衡点来提供它所能做的。现在我启动了该程序的两个实例,并且都在监听。一旦添加新消息,他们都会从队列中取出相同的消息并运行代码。我可以在多个监听器/负载均衡中使用SqlDependency

SqlDependency不是我想要做的解决方案吗?什么是这样的更好的解决方案?

+0

你是[自己配置队列并告诉SqlDependency它](https://msdn.microsoft.com/en-us/library/ms224871%28v=vs.110%29.aspx),或者只是[调用SqlDependency与连接字符串,并让它创建队列](https://msdn.microsoft.com/en-us/library/ms224872%28v=vs.110%29.aspx)? (该文档说:“如果没有指定队列名称,SqlDependency会在用于整个进程的服务器中创建一个临时队列和服务,即使该进程涉及多个AppDomain。队列和服务在应用程序关闭时自动删除。“) – stuartd

+0

我自己配置​​了队列,并且告诉SqlDependency使用该队列。 – Smeiff

回答

1

您不需要SQL通知或SQLDependency。每个实例都可以执行:

WAITFOR(
    RECEIVE TOP(1) * FROM {NameOfQueue} 
), TIMEOUT @timeoutvalue; 

此命令将等待,使连接保持打开状态,直到消息可用或发生超时。在超时你没有收到消息,所以只需连接,然后再试一次。

每条消息只能由单个进程接收。服务器代理队列中的行在内部处于锁定状态,其他读取器将锁定的行数为READPAST

因为SQL可能有点棘手,所以我写了我认为有用的wrapper class that you are free to use

+0

谢谢!我将它与一个触发器结合起来,并将其设置为一个无限循环,并且它正在工作。我最终不必使用包装类,但我会研究它。 – Smeiff

+1

该链接已损坏:新链接是https://github.com/jdaigle/LightRail/blob/master/src/LightRail.ServiceBus/SqlServer/ServiceBrokerWrapper.cs? – Richard

2

一旦增加新的消息他们都决绝相同的消息从队列和运行代码

您所描述的行为的SqlDependency是如何设计工作。如果有多个侦听器,则通知所有侦听器。例如,你可以看到在SignalR SQL Backplane documentation

SQL Pub/Sub

通知所有虚拟机如何接收从SQL Server的通知,其中包括发起更新VM此描述。

如果要跨工作虚拟机池分布SQL通知,则需要一种共享状态的方法。请注意,SQL通知只是的一个指示,即发生了某些变化,并不表示更改了什么。一种方法是向数据库添加一个表格,以充当一个作业或操作的队列。订阅者可以在每个通知中查询此队列,并通过从此表中更新或删除来声明该操作。 (适当的锁必须被放在桌子上配置的)

或者,也可以这样使用共享状态的其他工具,执行诸如消息队列(例如RabbitMQ的),或分布式缓存(例如Redis的)

+0

谢谢你在这方面没有太多可用的文件...表格如何充当一个工作队列?我需要另外一套逻辑来划分工作或者不是我?或者你是说要避免使用消息代理,只是不断查询数据库中的新数据,将锁定在标记它已被消耗的行等。 – Smeiff