JMS(Jboss Messaging)的一点使用心得(五)Spring扩展应用-可自动重连的JmsMessageListenerContainer

8 篇文章 0 订阅
Jboss为了保证运行效率,会对挂在它上面的JMSClient连接执行CallBack操作;如果发现该连接已经断掉(有个超时时间,可设置),则会回收该Client的JMS连接,以保证其他Client能及时地拿到JMS连接。

但是这样做会产生一个问题,如果在网络不稳定的情况下,Jboss错误的回收了一个有效的Client连接,而Client端
对此一无所知,只会傻傻的等待着一个再也不会到来的JMS消息......

以下是一个会自动重连的JmsMessageListenerContainer,实现原理就是在监听器中增加了一个线程,会定期Check连接的有效性,如果发现连接无效,则自动重连JMS服务器。以下是代码:
ExJmsMessageListenerContainer.java
package  jms.receiver;

import  javax.jms.Connection;
import  javax.jms.JMSException;
import  javax.jms.Session;

import  org.springframework.jms.listener.serversession.ServerSessionMessageListenerContainer;

/**
 * 
@see ServerSessionMessageListenerContainer
 
*/

public   class  ExJmsMessageListenerContainer  extends  ServerSessionMessageListenerContainer  {

    
/** sharedMonitor */
    
private final Object sharedMonitor = new Object();

    
/** interval */
    
private long interval = 300000;

    
/** sleepTime */
    
private boolean isConnectionCheck = false;

    
/** JMS Connection Check Thread */
    
private CheckConnectionThread checker;

    
/** resetFlg */
    
private boolean resetFlg = false;

    
public void setInterval(long interval) {
        
this.interval = 60000 * interval;
    }


    
public void setConnectionCheck(boolean isConnectionCheck) {
        
this.isConnectionCheck = isConnectionCheck;
    }


    @Override
    
protected void doStart() throws JMSException {
        
super.doStart();

        
if (this.isConnectionCheck) {

            
synchronized (this.sharedMonitor) {
                
if (!this.resetFlg) {
                    
if (this.checker != null{
                        
this.checker.stop();

                        
try {
                            Thread.sleep(
this.interval);
                        }
 catch (InterruptedException e) {
                            
this.logger.debug(e.getMessage(), e);
                        }

                    }


                    
this.checker = new CheckConnectionThread();
                    
new Thread(this.checker).start();
                }

            }

        }

    }


    @Override
    
protected void doShutdown() throws JMSException {
        
synchronized (this.sharedMonitor) {
            
if (!this.resetFlg && this.checker != null{
                
this.checker.stop();
            }

        }


        
super.doShutdown();
    }


    
private boolean checkConnect() {
        
try {
            Connection connection 
= this.getSharedConnection();
            Session session 
= createSession(connection);
            session.close();
            session 
= null;
        }
 catch (Exception e) {
            
this.logger.error("JMS Connection Error. [" + e.getMessage() + "]", e);
            
return false;
        }


        
return true;
    }


    
private boolean resetConnection() {
        
this.resetFlg = true;
        
try {
            
try {
                destroy();
            }
 catch (Exception e) {
                
this.logger.debug(e.getMessage(), e);
            }

            refreshSharedConnection();
            setAutoStartup(
true);
            initialize();
        }
 catch (Exception e) {
            
this.logger.error("Reset JMS Connection failed. [" + e.getMessage() + "]", e);
            
return false;
        }


        
this.resetFlg = false;

        
this.logger.info("Reset JMS Connection success.");
        
return true;
    }


    
private class CheckConnectionThread implements Runnable {

        
/** sleepTime */
        
private boolean checkRunFlg = true;

        
public void stop() {
            
this.checkRunFlg = false;
        }


        @Override
        
public void run() {
            
while (this.checkRunFlg) {
                
try {
                    Thread.sleep(ExJmsMessageListenerContainer.
this.interval);
                }
 catch (InterruptedException e) {
                    ExJmsMessageListenerContainer.
this.logger.debug(e.getMessage(), e);
                }

                
if (this.checkRunFlg && !checkConnect()) {
                    
for (int i = 0; i < 3; i++{
                        
if (!this.checkRunFlg || resetConnection()) {
                            
break;
                        }

                        
try {
                            Thread.sleep(
30000);
                        }
 catch (InterruptedException e) {
                            ExJmsMessageListenerContainer.
this.logger.debug(e.getMessage(), e);
                        }

                    }

                }

            }

        }


    }

}


在Spring的配置文件中可以这样配置
     < bean  id ="exListenerContainerQueue"  lazy-init ="true"  
        class
="jms.receiver.ExJmsMessageListenerContainer" >
        
< property  name ="connectionFactory"  ref ="myConnectionFactory"   />
        
< property  name ="destinationName"  value ="B"   />
        
< property  name ="messageListener"  ref ="messageListener"   />
        
< property  name ="exceptionListener"  ref ="exceptionListener"   />
        
< property  name ="sessionTransacted"  value ="true"   />
        
< property  name ="connectionCheck"  value ="true"   />
        
< property  name ="interval"  value ="3"   />
    
</ bean >
其中, connectionCheck是是否需要Check的Flag, interval是Check的时间间隔,单位为“分”。


还有另外一种实现方式,请参见
[ http://blog.csdn.net/supersue/archive/2008/04/02/2244727.aspx]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值