明らかに理由もなく停止するキューがあります。このキューに、位置メッセージ処理を実装しました。また、処理中に、毒メッセージを記録して破棄します。
それは止まることなく1年以上うまく機能しました。しかし最近(問題は4週間前に始まりました)、週に1、2回停止します。そして今週だけそれは二度止まった。
そして、新しい毒メッセージでテーブルをチェックすると、何もありません!! また、キューを有効にすると、処理が正常に再開され、「ポイズンメッセージ」の状況が再現されません。
キューのタスクについて:1日あたり約2〜3000のメッセージを受信します。トランザクションの外部でストアドプロシージャを実行するために使用されます。そして、各メッセージは処理されるまで少し続く可能性があります(多くの選択、挿入、更新を行います)。
この点を説明しましょう。データベースにはトランザクション内で起動されるトリガーがあり、トリガーはトリガーの外部でコードを実行するためのメッセージを送信します。非同期動作により、データベースのパフォーマンスが低下するのを防ぎます。
メッセージの処理中にデッドロックが発生した場合でも、キューはメッセージをポイズンとして処理することを検出しました。したがって、原則として、パフォーマンスの問題にはなりません。しかし、それは可能ですか?たぶん、データベースは成長していて、メッセージを処理するには長すぎますか?
しかし、それがposionedとして検出されない場合、どうすればそれを見つけることができますか?
キューが停止する他の理由はなぜですか?
キューが無効になったときとメッセージを保存するにはどうすればよいですか?
フォレンジック分析を行う方法を誰かが知っていますか?
何か案が?
疑似解決策を公開する更新:
Remusの投稿によると、私はイベント通知を使用して、キューが停止する正確な瞬間を取得しようとしました。
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
レムスありがとう!