1.背景
我们正在评估Spring JMS并针对各种场景测试JMSTemplate - 队列,主题(持久,非持久) .
我们经历了 message loss for non-durable topic subscribers ,并希望在此处寻求澄清 .
2.问题陈述
a)我们编写了一个独立的java程序,它每隔n秒调用JMSTemplate.receive方法,从非持久主题**同步接收消息 .
b)我们注意到总是 message loss after the 1st invocation of the JMSTemplate.receive method . 这是由于JMSTemplate.receive方法 stopping the connection 到达ConnectionFactoryUtils.releaseConnection(...)时 .
JmsTemplate的:
public <T> T execute(SessionCallback<T> action, boolean startConnection) throws JmsException
{
Assert.notNull(action, "Callback object must not be null");
Connection conToClose = null;
Session sessionToClose = null;
try {
Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(
getConnectionFactory(), this.transactionalResourceFactory, startConnection);
if (sessionToUse == null) {
conToClose = createConnection();
sessionToClose = createSession(conToClose);
if (startConnection) {
conToClose.start();
}
sessionToUse = sessionToClose;
}
if (logger.isDebugEnabled()) {
logger.debug("Executing callback on JMS Session: " + sessionToUse);
}
return action.doInJms(sessionToUse);
}
catch (JMSException ex) {
throw convertJmsAccessException(ex);
}
finally {
JmsUtils.closeSession(sessionToClose);
ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection); // the connection is stopped here
}
}
ConnectionFactoryUtils.releaseConnection(...):
public static void releaseConnection(Connection con, ConnectionFactory cf, boolean started) {
if (con == null) {
return;
}
if (started && cf instanceof SmartConnectionFactory && ((SmartConnectionFactory) cf).shouldStop(con)) {
try {
con.stop(); // connection was stopped here
}
catch (Throwable ex) {
logger.debug("Could not stop JMS Connection before closing it", ex);
}
}
try {
con.close();
}
catch (Throwable ex) {
logger.debug("Could not close JMS Connection", ex);
}
3.使用Spring文档验证
Spring JMS文档建议使用池化连接,因此我们确保完成了 .
我们的java程序是从WLS JMS和MQ JMS(LDAP)提供程序获取JMS连接工厂,并在各自的测试用例中使用SingleConnectionFactory和CachingConnectionFactory进行修饰 .
这是我们在测试过程中观察到的:
a)SingleConnectionFactory - 连接已停止(消费者/会话也已关闭) .
b)CachingConnectionFactory - 连接也已停止(尽管Consumer / Session已缓存且未关闭)
4.问题:
a)有人和我们一样遇到过同样的问题吗?
b)您是否认为这是针对非持久性订阅用例的Spring JMS的缺陷?
c)我们正在考虑定制一个不会停止连接的CachingConnectionFactory . 有任何缺点吗?
注意:我们知道使用JMSTemplate的Async MessageListeners(如DMLC / SMLC和Sync Durable Topic Subscribers)不会出现此问题 . 我们只想澄清使用JMSTemplate的Sync Non-Durable主题订阅者 .
非常感谢任何评论和想法 .
谢谢!
胜利者