Почему OracleAQ оставляет мертвых подписчиков в очереди?
Это Oracle 11.2.0.3.
У нас есть проблема, когда мы используем Oracle JMS вместо OracleAQ. Это работает нормально, за исключением того, что мы начали замечать, что очередь заполняется тысячами, а затем миллионами сообщений со временем. Некоторые из них находятся в состоянии ОБРАБОТАНО, но большинство ГОТОВ. Мы проследили это поведение до "зомби" или дохлых подписчиков темы. Когда процесс Java завершается и не получает возможности отменить свою регистрацию, он оставляет запись подписчика в очереди, и ORacle, похоже, не обнаруживает, что он мертв. Настолько, что спустя МЕСЯЦЫ новое сообщение, отправленное в нашу многопользовательскую очередь, будет затем умножено на число подписчиков, которое, по его мнению, намного выше, чем есть на самом деле. (Мы впервые заметили это, когда достигли максимального лимита подписчика.)
У нас запущены процессы qmon - я даже пытался увеличить минимальное количество процессов безрезультатно. Очистка очереди происходит очень хорошо, если в очереди нет мертвых подписчиков.
Кто-нибудь видел это раньше и, надеюсь, нашел решение?
1 ответ
Итак, у меня не может быть лучшего решения, чем это:
1) Создайте своего подписчика с именем и отслеживайте имя подписчика.
2) Убедитесь, что у вас есть завершение подключения к приложению для выполнения описанной ниже процедуры, которая отменит подписку и отменит подписку.
3) В случае неожиданного завершения работы / сбоя, когда отмена подписки не может быть выполнена, должна быть задача очистки для выполнения нижеприведенного кода:
DECLARE
aqAgent SYS.AQ$_AGENT;
BEGIN
for idx in (select consumer_name from
DBA_QUEUE_SUBSCRIBERS a where a.queue_name = '<Your Oracle AQ Name>') loop
aqAgent := SYS.AQ$_AGENT(idx.consumer_name, NULL, NULL);
DBMS_AQADM.REMOVE_SUBSCRIBER('<Your Oracle AQ Name>', aqAgent);
end loop;
END;
Это обеспечит полную защиту вашей системы.