oracle - 为什么 OracleAQ 将死订户留在队列中?

标签 oracle jms oracle-aq subscriber orphaned-objects

这是 Oracle 11.2.0.3。

我们在使用 Oracle 的 JMS 而不是 OracleAQ 时遇到了问题。这工作正常,除了我们开始注意到队列被填满 1000 条消息,然后随着时间的推移数百万条消息。其中一些处于 PROCESSED 状态,但大多数处于就绪状态。我们将此行为追溯到该主题的“僵尸”或死亡订阅者。当一个 Java 进程终止并且没有机会注销自己时,它会将订阅者记录留在队列中,而 ORacle 似乎没有检测到它已经死亡。以至于 MONTHS 之后,发送到我们的多订阅者队列的新消息将乘以订阅者的数量,它认为这比实际要高得多。 (当我们达到最大订阅者限制时,我们首先注意到了这一点。)

我们已经运行了 qmon 进程——我什至尝试增加最小进程数以使其无效。只要队列中没有死订阅者,队列清理就会非常顺利。

任何人都看到过这个,并希望找到一个解决方案?

最佳答案

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

1) 使用名称创建您的订阅者并跟踪订阅者的姓名。

2)确保您有一个应用程序的关闭 Hook 来执行以下过程,这将取消订阅并注销订阅者。

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;

这将确保您的系统保持完整。

关于oracle - 为什么 OracleAQ 将死订户留在队列中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10038104/

相关文章:

Oracle 语法——我们应该在新旧之间做出选择吗?

oracle - "Test connection succeeded"但 "An unexpected error occurred in the ODP.NET, Managed Driver"

java - JMS TextMessage、JMS_BEA_SELECT 消息选择器、事务处理 session 和确认模式

ubuntu - IBM MQ 和 Kafka 连接器问题(提供的主机名无效)

ldap - LDAP:错误代码49-无法绑定(bind)PrincipalDn

database - 合并到比赛中

sql - 为 Oracle 生成 sql insert into

Spring如何限制消息监听器的重试次数

java - Oracle AQ 性能调优

java - Oracle 高级队列 : Change Queue Properties at Runtime