Очередь останавливается (отключается) без каких-либо ядовитых сообщений
У меня есть очередь, которая останавливается без какой-либо видимой причины, в этой очереди я реализовал обработку почтовых сообщений. И во время обработки, он записывает и удаляет любые ядовитые сообщения.
Он работал нормально более года без остановки. Но в последнее время (проблема началась четыре недели назад), она останавливается один или два раза в неделю. И только на этой неделе остановился дважды.
И когда я проверяю таблицу с новыми отравленными сообщениями, их нет!! И когда я включаю очередь, обработка возобновляется успешно, а ситуация с "ядовитым сообщением" не воспроизводится.
О задании из очереди: Получает около 2-3000 сообщений в день. Он используется для запуска хранимых процедур вне транзакции. И каждое сообщение может длиться немного, чтобы быть обработанным (делая много выборок, вставок, обновлений).
Позвольте мне объяснить этот момент: в базе данных есть триггеры, которые запускаются внутри транзакции, триггер отправляет сообщение для запуска некоторого кода вне триггера. Асинхронное поведение предотвращает снижение производительности базы данных.
Я обнаружил, что даже при возникновении взаимоблокировки при обработке сообщений очередь обрабатывает сообщение как отравленное. Так что в принципе это не должно быть проблемой производительности. Но может ли это быть? Может быть, база данных растет и длится слишком долго, чтобы обрабатывать сообщения?
Но как я могу узнать это, если он не обнаружен как положенный?
Почему по другой причине очередь останавливается?
Как сохранить, когда и с каким сообщением очередь отключена?
Кто-нибудь знает, как я могу провести какой-либо судебный анализ?
Любая идея?
ОБНОВЛЕНИЕ ОБСЛУЖИВАНИЯ ПСЕВДО-РЕШЕНИЯ:
Согласно сообщению Ремуса, я пытался использовать уведомление о событии, чтобы получить точный момент, когда очередь останавливается.
CREATE EVENT NOTIFICATION [QueueDisabledEN]
ON QUEUE [dbo].[ProcessQueue]
FOR BROKER_QUEUE_DISABLED
TO SERVICE 'Queue Watch Service', 'current database';
А затем проверяем журнал событий:
select * from sys.event_notificiation
Но так как трудно узнать среду, в которой произошло событие (что еще происходило в момент?), Криминалистический анализ на этом заканчивается. К счастью, моя реализация службы брокера хранит сообщения с датой отгрузки, датой получения, датой обработки... Это помогло мне обнаружить, что в течение 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
Спасибо, Ремус!
1 ответ
Когда вы находите очередь в отключенном состоянии и включаете ее обратно, я предполагаю, что обработка возобновляется успешно и ситуация с "ядовитым сообщением" не воспроизводится. Это указывает на то, что причина является временной или временной. Это может быть задание агента SQL, которое выполняется и вызывает взаимоблокировки при обработке очереди, что приводит к откату обработки очереди. По моему опыту, тупики являются наиболее типичной причиной сообщения об отравлении. Ваш лучший инструмент для анализа - это журнал системных событий, так как активированная процедура выводит ошибки в ERRORLOG и, следовательно, в системный журнал событий.
Всякий раз, когда очередь отключается триггером подозрительного сообщения (5 последовательных откатов), генерируется уведомление о событии типа QUEUE_DISABLED. Вы можете получить больше криминалистической информации при обработке этого события, так как оно будет запущено вскоре после того, как очередь была отключена.
Как примечание, у вас никогда не будет настоящей "обработки ядовитых сообщений". Всякий раз, когда вы улучшаете обработку для обработки некоторых случаев ошибок, определение "ядовитого сообщения" изменяется на сообщение, способное отключить новую обработку ошибок.