У меня есть очередь, которая останавливается без видимой причины, в этой очереди я реализовал обработку позиционных сообщений. И во время обработки он записывает и отбрасывает любые вредоносные сообщения.
Работает нормально уже больше года без остановки. Но в последнее время (проблема началась четыре недели назад) останавливается раз-два в неделю. И только за эту неделю он остановился дважды.
И когда я проверяю таблицу с новыми отравленными сообщениями, их нет!! И когда я включаю очередь, обработка успешно возобновляется и ситуация с «ядовитым сообщением» не воспроизводится.
О задаче очереди: Получает около 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
Спасибо Ремус!