我们正在使用一个包含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的文档告诉我们一个对象代表一个套接字,因此由于不活动而导致的超时可能是正常的。但是,如果不为每条消息创建新的连接,我们如何处理它呢?
答案 0 :(得分:3)
最好的办法是让 JMSPublisher 实施javax.jms.Exception监听器。实施 connect() 方法,该方法可以安全地获取连接:
一些额外的观点:
对于代码压缩,只需通过资源注入获取JMS连接工厂。连接工厂引用将在调用 startService 之前解析,并且还将充当隐式 depends ,从而使JMS连接工厂成为服务的依赖项。
< / LI>让 JMSPublisher 扩展org.jboss.system.ServiceMBeanSupport并实现扩展org.jboss.system.ServiceMBean的令牌MBean接口( JMSPublisherMBean )。这将确保在服务启动(和停止)时遵守依赖关系。
资源注入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通知,指示该连接已丢失并清理/重新获得通知收据。