JMS 4.2.2 DLQ 机制

项目中MDB处理异常后,调mdc.setRollbackOnly()方法后,发现JMS又发了6条消息过来。查了些资料,特此记下来。
由于mdc在项目中是注入的,整个JMS是CMT(Container Managed Transaction), mdc.setRollbackOnly()方法表示要回滚事务,但实际上的操作是通知producer重发一下。
在JBOSS的配置文件中有
 <MDBConfig>
          <ReconnectIntervalSec>10</ReconnectIntervalSec>
          <DLQConfig>
            <DestinationQueue>queue/DLQ</DestinationQueue>
            <MaxTimesRedelivered>10</MaxTimesRedelivered>
            <TimeToLive>0</TimeToLive>
          </DLQConfig>
</MDBConfig>
  


这里配置了重发时间和DLQ的配置。具体参数定义猛击 这里
DLQ全称是Dead Letter Queue,JBoss的官方网站是这样定义的:A dead letter queue stores requests that could not be processed due to some failure in the system, application or configuration.就是说,如果自己发的message被rollback了,会被重发,重发次数达到上限(MaxTimesRedelivered定义),queue中消息就会发到DLQ中。(详见http://krinsiman.blogbus.com/logs/8166898.html)

后来发现,更改上面的配置无法达到预计效果,因为Jboss使用JCA来handle JMS,DLQ是JCA的实现,而JCA默认配置里面配的参数与这里不同。 这里可以找到所有参数。
由于是在找不到如何自定义JCA的重发时间,而用 reconnectInterval属性来设置也不生效,最后找到了如下方法:
 

In JBoss 4.x the JMS configuration (in jms/jbossmq-destinations-service.xml) is like this:

<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=MyQueue">
<attribute name="JNDIName">queue/MyQueue</attribute>
<attribute name="RedeliveryDelay">10000</attribute>
<attribute name="RedeliveryLimit">3</attribute>
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>

 

In JBoss 5.x we should do this (in messaging/destinations-service.xml):

<mbean code="org.jboss.jms.server.destination.QueueService"
name="jboss.messaging.destination:service=Queue,name=MyQueue"
 xmbean-dd="xmdesc/Queue-xmbean.xml">
 <depends optional-attribute-name="ServerPeer">
jboss.messaging:service=ServerPeer
</depends>
 <depends>jboss.messaging:service=PostOffice</depends>
 <attribute name="JNDIName">queue/MyQueue</attribute>
 <attribute name="RedeliveryDelay">10000</attribute>
 <attribute name="MaxDeliveryAttempts">3</attribute>
</mbean>
  
在这里设置
RedeliveryDelay就有效了。

再次更新!
本来项目需要是等消息rollback后等若干时间后重新尝试,结果事实是jboss默认jms重新发6次,然后就扔到DLQ不管了。
终于找到真正修改可以起作用的地方了,以上仅供参考做研究,尝试结果是失败……
在jmx console里面,找到

jboss.mq.destination

在下面找到自己的queue,点开,有RedeliveryDelay和RedeliveryLimit。RedeliveryDelay默认为0,这是为什么rollback后,jms不停的重发。这里可以给其设一个较大的值。RedeliveryLimit默认值是-1,但实际上正如之上看到,默认是5.这里需要把它改成>=0的值,否则提交修改时会报错。

再次更新,最终研究结果显示,jboss4.2.2的queue有漏洞。当mdb rollback一个message的时候,jboss会检查是否要redelivery。如果不需要或者超过redeliverylimit,就会扔到Dlq。Dlq有一个恢复次数的参数,参见上面redelivery页面。该参数仅当这个queue被刷新,即jboss重启或者该包被重新load时,才会启动。换言之,这个message在runtime的时候就被丢掉了!囧。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值