【问题标题】:Can I use SqlDependency with multiple listeners / load balance我可以将 SqlDependency 与多个侦听器/负载平衡一起使用吗
【发布时间】:2015-10-19 17:09:39
【问题描述】:

我目前正在使用带有 SQL Server 2012 Service Broker 的 SqlDependency,并且我希望能够配置两台服务器,同时侦听服务代理并退出队列,但消息总共只能退出队列一次。每台机器都应该尽量减少它所能做的,但如果有太多的机器进来,它应该在尽可能多的拉动方面保持平衡。现在我启动了两个程序实例,并且都在监听。添加新消息后,它们都会从队列中取出相同的消息并运行代码。

SqlDependency 不是我想做的解决方案吗?这种情况有什么更好的解决方案?

【问题讨论】:

标签: c# sql-server-2012 service-broker sqldependency


【解决方案1】:

一旦添加了新消息,它们就会从队列中取出相同的消息并运行代码

您描述的行为是 SQLDependency 的设计方式。如果有多个侦听器,则通知所有侦听器。例如,您可以在SignalR SQL Backplane documentation

中看到这一点

注意所有 VM 如何从 SQL Server 接收通知,包括启动更新的 VM。

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

或者,您可以使用其他用于共享状态的工具来执行此操作,例如消息队列(例如 RabbitMQ)或分布式缓存(例如 Redis)

【讨论】:

  • 感谢您在这方面没有太多可用的文档...该表如何充当作业队列?我需要另一套逻辑来划分工作,或者不是吗?或者你是说避免使用消息代理,而只是不断地查询数据库以获取新数据,锁定标记它已被使用的行等。
【解决方案2】:

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

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

此命令将等待,使连接保持打开状态,直到有消息可用或发生超时。超时后您不会收到任何消息,因此请连接并重试。

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

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

【讨论】:

  • 谢谢!我将它与触发器结合起来,并将其设置为几乎无限循环并且它正在工作。我最终不必使用你的包装类,但我会研究它。
  • 该链接已损坏:新链接会是github.com/jdaigle/LightRail/blob/master/src/… 吗?
猜你喜欢
  • 2014-08-17
  • 2013-04-30
  • 2016-09-11
  • 2013-06-09
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-06
相关资源
最近更新 更多