为什么Oracleq会在队列中留下死订户?

为什么Oracleq会在队列中留下死订户?,oracle,jms,oracle-aq,subscriber,orphaned-objects,Oracle,Jms,Oracle Aq,Subscriber,Orphaned Objects,这是Oracle 11.2.0.3 我们在Oracleq上使用Oracle的JMS时遇到了一个问题。这很好,但我们开始注意到队列中充满了1000条消息,然后随着时间的推移会有数百万条消息。其中一些处于已处理状态,但大多数已准备就绪。我们将这种行为追溯到该主题的僵尸或死亡订户。当Java进程终止并且没有机会注销自己时,它会将订户记录留在队列中,ORacle似乎不会检测到它已死亡。几个月后,发送到我们的多订户队列中的新消息将乘以订户数量,它认为这比实际情况要高得多。我们第一次注意到这一点是在我们达到

这是Oracle 11.2.0.3

我们在Oracleq上使用Oracle的JMS时遇到了一个问题。这很好,但我们开始注意到队列中充满了1000条消息,然后随着时间的推移会有数百万条消息。其中一些处于已处理状态,但大多数已准备就绪。我们将这种行为追溯到该主题的僵尸或死亡订户。当Java进程终止并且没有机会注销自己时,它会将订户记录留在队列中,ORacle似乎不会检测到它已死亡。几个月后,发送到我们的多订户队列中的新消息将乘以订户数量,它认为这比实际情况要高得多。我们第一次注意到这一点是在我们达到最大用户限制时

我们已经运行了qmon进程——我甚至尝试增加最小进程数,但没有效果。只要队列中没有死掉的订户,队列清理就会非常顺利


以前有人看到过这一点,并希望找到解决方案吗?

好的,所以我没有比这更好的解决方案了:

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;

这将确保您的系统仍然是完全可靠的。

我面临同样的问题,并试图解决它。如果我找到了解决方案,我会把它贴在这里供其他用户参考。