我有一个情况,多个客户端应用程序通过 Service Broker 发送消息(利用存储的过程)。这些消息由另一个客户端应用程序获取,然后进行处理。获取消息的方式是应用发出以下 SQL 语句(伪代码):
LOOP {
WAITFOR (RECEIVE CONVERT(int, message_body) AS Message FROM SB_ReceiveQ)
ProcessMessage
}
所以基本上代码只是阻塞,直到收到消息。这一切都很好。
我的问题是关于发出WAITFOR (RECEIVE...
命令的含义,该命令基本上永远挂在某些基于服务代理的资源上。我应该知道与此模式相关的任何性能问题吗?
作为参考,这是 SQL Server 2005。
您正在阻止 SQL Server 中的工作人员,并且工作人员受到限制,受最大工作线程数的限制。这意味着不应有数千个请求被阻止,
WAITFOR(RECEIVE...)
否则您将饿死服务器的工作人员。但首先想到的问题是为什么没有杠杆服务代理激活?这样您就不会一直等待,而只会在激活时等待,因为有消息要接收。
在 SQL Server 2005 中,我们每天有 50 多台机器每天都在做这件事。已经做了 3 年多没有问题。
我所知道的不确定的最大问题
WAITFOR
是日志文件扩展。这在此处进行了描述。当您启动事务时,SQL Server 会挂接到它的日志。在该事务开始之后发生的所有事务事件,例如UPDATE
对其他表的 s,都将在“之后”记录在日志中。可以想象 SQL Server 以循环方式写入日志文件:当它到达末尾时,它会转到开头并继续。但是,一旦日志充满了不可回收的“活动事务”,它必须开始扩展日志(如果启用)。扩展日志文件很昂贵。如果服务器在响应客户端之前需要记录一些东西,那么这些响应将不得不等待日志扩展。此外,如果事务永远持续,则日志将扩展,直到它使用所有可用的可用空间。
只要您
RECEIVE
需要运行,它就会阻止回收日志。您可以通过确保您RECEIVE
有足够短的超时来缓解这种情况,以防止日志无限增长并处理未及时出现超时的事件的错误情况。