如何处理到远程jms服务器的Connection对象



我们使用的应用程序包含一个jboss@Service mbean,它封装了一个javax.jms.Connection对象。

在mbean启动期间,通过初始化远程InitialContext、从该上下文查找ConnectionFactory并从该工厂创建连接来创建连接:

@Service
public class JMSPublisher extends etcc.... {
   private Connection connection;
   protected void startService() {
      Context ctx = getRemoteInitialContext();
      ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
      connection = connectionFactory.createConnection();
   }
}

我的问题是:我们应该保持这种联系多久?在实践中,当我们在未定义的时间后尝试在连接上创建会话时,我们会看到连接抛出JMSException。

Connection的文档告诉我们,对象表示一个套接字,因此由于不活动而导致的超时可能是正常的。但是,如果不为每条消息创建新的连接,我们如何应对呢?

您的最佳选择是让JMSPublisher实现javax.jms.Exception侦听器。实现connect((方法,该方法可以安全地获取上的连接

  1. startService
  2. on异常

额外的几点:

  • 对于代码压缩,只需通过资源注入获取JMS连接工厂即可。连接工厂引用将在调用startService之前解析,并且还将充当隐式依赖项,使JMS连接工厂成为服务的依赖项。

  • JMSPublisher扩展org.jbos.system.ServiceMBean支持并实现一个扩展org.jboss.system.ServicesBean的令牌MBean接口(JMSPublish MBean(。这将确保在服务启动(和停止(时遵守依赖关系。

资源注入JMS连接工厂

@Resource(mappedName="ConnectionFactory") 
private javax.jms.ConnectionFactory connectionFactory;
private volatile javax.jms.Connection connection;

修改的startService((

public void startService() {
   connect();
}

连接异常处理程序

public void onException(JMSException je) {
   connect();
}

*安全连接初始化程序(添加conn.start(((*

private void synchronized connect() {
    log.info("Initializing Connection....");
    try {
        if(connection!=null) {
           try { connection.stop(); } catch (Exception e) {}
           try { connection.close(); } catch (Exception e) {}
        }
        connection = connectionFactory.createConnection();
        connection.setExceptionListener(this);
        connection.start();
    } catch (Exception e) {
        log.error("Failed to intialize JMS connection", e);
    }
}

这不会自动处理通过丢失的连接分配的其他JMS资源,但如果其他组件正在使用该组件所拥有的连接,则可以从JMSPublisher发布JMX通知,指示连接已丢失,并在收到通知时清理/重新获取。

最新更新