DB down

时间:2017-03-06 06:19:19

标签: java multithreading ejb jms weblogic

应用程序概述:

在我的应用程序中,我们每天都会收到60000封邮件。它使用11个MDB和MessageListener来订阅来自不同OMB队列的消息并对其进行处理。使用weblogic服务器和JAP。我们每个MDB共有32个实例,因为我们有8个不同的节点,每个节点的max-beans-in-free-pool是4个。

当前问题:

当DB down时,在异常中捕获它并回滚事务上下文,以便将消息放回队列。我们检查JMSXDeliveryCount是否小于100它将重试否则它将丢弃该消息并发送带有消息引用的电子邮件。

问题: 消息正在丢失,在几秒内完成100次重试。但DB可能会在2小时后启动。

提议的方法:

在处理消息之前检查数据库连接,如果DB连接是 - 请在repoll之后将线程休眠5分钟以检查连接。 在这种情况下,每个MDB可以在应用程序级别保留32个消息(Tread),剩余消息将在队列中。我们有11个MDB,所以(11 * 32)线程可以在应用程序级别睡眠。

我觉得在初始级别检查所有消息的DB连接并在应用程序级别持有352消息(控制352线程,可能是weblogic崩溃)直到DB up,这是不好的。

在MDB级别或weblogic级别处理此问题的更好方法是什么?

2 个答案:

答案 0 :(得分:0)

我不熟悉Web Logic,但是以我对IBM MQ的知识做出回应。

您是否考虑过为应用程序接收邮件的队列设置Redelivery LimitError Destination属性?如果邮件的JMSXDeliveryCount属性超过Redelivery Limit,则该邮件将路由到Error Destination,基本上是队列或主题。您还可以为邮件设置Redelivery Delay Override属性。

您可以编写单独的逻辑,用于将消息从Error Destination移动到应用程序从中接收消息的队列。这样消息就不会丢失。

更多详情here

希望这会有所帮助。

答案 1 :(得分:0)

容器管理事务 - 而不是通过代码处理线程/消息重试,容器将处理它。

Container将根据下面提到的MDB配置重试该消息。

即在weblogic-ejb-jar.xml下:message-driven-descriptor

        <init-suspend-seconds>2</init-suspend-seconds> 

以2秒重试开始。每次重试间隔秒加倍,直到达到300秒的最大重试次数。即2,4,8 ...... 300

        <max-suspend-seconds>300</max-suspend-seconds> 

达到300秒后,容器每300秒重试一次,直到失败原因得到解决。解决后,问题容器将恢复MDB实例的正常处理。

<message-driven-descriptor>
<pool>
    <max-beans-in-free-pool>4</max-beans-in-free-pool>
    <initial-beans-in-free-pool>1</initial-beans-in-free-pool>
</pool>
<destination-jndi-name>XXX_FOREIGN_DEST_LOCAL@env_name@
</destination-jndi-name>
<connection-factory-jndi-name>XXX_FOREIGN_QCF_LOCAL@env_name@
</connection-factory-jndi-name>
<init-suspend-seconds>2</init-suspend-seconds>
<max-suspend-seconds>300</max-suspend-seconds>
</message-driven-descriptor>