2011-01-26 82 views
1

我有一个队列,没有任何原因的停止,在这个队列中,我已经实现了一个位置消息处理。在处理过程中,它会记录并丢弃任何有毒消息。队列停止(禁用)没有任何有害消息

它一直很好了一年多的时间没有停止。但最近(问题在四周前开始),它每周停止一次或两次。只在本周它停了两次。

当我用新的中毒信息检查表时,没有!当我启用队列时,处理将成功恢复,并且“毒讯”情况不会再现。

关于队列的任务:每天接收约2-3000条消息。它用于在事务外运行存储过程。每条消息都可以持续处理一段时间(进行大量选择,插入和更新)。

让我解释一下这一点:数据库具有在事务内触发的触发器,触发器会发送消息在触发器外运行一些代码。异步行为可防止丢弃数据库的性能。

我发现即使在进行消息时发生死锁,队列也会将消息视为中毒。所以原则上它不应该是一个性能问题。但是,它可以吗?也许数据库正在增长,处理消息的时间太长了?

但是,如果找不到它,我该如何找到它?
为什么其他原因队列停止?
如何节约时间和与消息队列中得到了禁用?
是否有人有任何想法,我该怎么办任何取证分析?
有什么想法?


UPDATE揭露伪解决方案:
根据莱姆斯后,我试图用事件通知得到确切时刻队列停止时。

CREATE EVENT NOTIFICATION [QueueDisabledEN] 
    ON QUEUE [dbo].[ProcessQueue] 
    FOR BROKER_QUEUE_DISABLED 
    TO SERVICE 'Queue Watch Service', 'current database'; 

,然后检查事件日志:

select * from sys.event_notificiation 

但因为它是很难知道的事件发生,(还有什么是在momment运行?)环境,法医分析在那里结束。幸好我的经纪人服务实现存储与运输,收到的日期,日期处理日期的消息,...这帮助我检测到3秒内的队列上充斥着数百封邮件是需要很长时间来处理。

虽然我找到真正的解决方案只是暂时的解决办法是用代理的工作就是检查队列中的每x分钟的状态,并启用它:

IF (EXISTS(SELECT * FROM sys.service_queues WHERE name like 'ProcessQueue' AND (is_receive_enabled = 0 OR is_enqueue_enabled = 0))) BEGIN 
    PRINT convert(nvarchar, getdate(), 121)+ ': Activando la cola ProcessQueue' 
    ALTER QUEUE ProcessQueue WITH STATUS = ON 
END 

感谢莱姆斯!

回答

4

当您找到处于禁用状态的队列并且您启用了回队列时,我认为处理成功恢复并且“有毒消息”情况不会再现。这将表明原因是短暂的或与时间有关。它可能是一个正在运行的SQL代理作业,并导致队列处理发生死锁,迫使队列处理回滚。根据我的经验,死锁是最典型的毒药讯息原因。您的最佳取证工具是系统事件日志,因为激活的过程确实将错误输出到ERRORLOG中,并因此输入到系统事件日志中。

每当有毒消息触发器(5次连续回滚)禁用队列时,就会触发类型为QUEUE_DISABLED的event notification。您可以在处理此事件时捕获更多的取证信息,因为它会在禁用队列后立即运行。

作为一个方面说明,你永远不可能有真正的'毒讯息处理'。每当您增强处理以处理某些错误情况时,“有害消息”的定义更改为该消息能够禁用新的错误处理

+0

Hi @Remus Rusanu,关于毒药信息处理:当然不是真正的和明确的'毒药信息处理',但我认为它是最接近我可以发现一个非常简单的解决方案:如果3检测到回滚,在接下来的“recibe-action”中,该消息将被直接解散以用于以后的分析。 任何可以避免队列停止并达到5个连续回滚的地方。 ...但是当毒害信息被保存以供日后分析时,它可能会产生一个错误(由死锁或瞬时问题引起)并达到第五次回退。 一种偏执,不是吗? – Alex 2011-01-27 15:34:22