在我的应用程序中,我们每天都会收到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级别处理此问题的更好方法是什么?
答案 0 :(得分:0)
我不熟悉Web Logic,但是以我对IBM MQ的知识做出回应。
您是否考虑过为应用程序接收邮件的队列设置Redelivery Limit
和Error 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>