在集成activemq 到web开发环境中遇到问题: 项目运行一段时间后 在调用produce 发送消息会报错 session is closed。
在查看PooledConnectionFactory, 结合网上查询的资料。
popl.setMaxConnections(2); 最大connection数
popl.setMaximumActiveSessionPerConnection(30); 设置最大session数量
1, PooledConnectionFactory.createConnection() 会将Connection缓存起来。
源码创建的代码如下
PooledConnectionFactory.java public synchronized Connection createConnection(String userName, String password) throws JMSException { if (this.stopped.get()) { LOG.debug("PooledConnectionFactory is stopped, skip create new connection."); return null; } else { ConnectionPool connection = null; ConnectionKey key = new ConnectionKey(userName, password); if (this.getConnectionsPool().getNumIdle(key) < this.getMaxConnections()) { try { this.connectionsPool.addObject(key); connection = (ConnectionPool)this.mostRecentlyCreated.getAndSet((Object)null); connection.incrementReferenceCount(); } catch (Exception var8) { throw this.createJmsException("Error while attempting to add new Connection to the pool", var8); } } else { try { while(connection == null) { connection = (ConnectionPool)this.connectionsPool.borrowObject(key); synchronized(connection) { if (connection.getConnection() != null) { connection.incrementReferenceCount(); break; } this.connectionsPool.returnObject(key, connection); connection = null; } } } catch (Exception var10) { throw this.createJmsException("Error while attempting to retrieve a connection from the pool", var10); } try { this.connectionsPool.returnObject(key, connection); } catch (Exception var7) { throw this.createJmsException("Error when returning connection to the pool", var7); } } return this.newPooledConnection(connection); } } 2, PooledConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); 不会缓存session。 只会往PooledConnection的loanedSessions 中添加。 调用一次就添加一次。 源码如下
PooledConnection.java private final List<PooledSession> loanedSessions = new CopyOnWriteArrayList(); public Session createSession(boolean transacted, int ackMode) throws JMSException { PooledSession result = (PooledSession)this.pool.createSession(transacted, ackMode); this.loanedSessions.add(result); result.addSessionEventListener(this); return result; } 3, 现在代码调整为 每次消费者都去 创建session, 发送完后就销毁。 (待测试是否还会出现 session is closed)
try { session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); producer = session.createProducer(....); }finally { if(producer != null){ producer.close(); } if(session != null){ session.close(); // 销毁 } } 4, JmsTemplate(spring整合activemq) 每次发送消息后都关闭了 producer 和 session
JmsTemplate.java
JmsUtils.closeSession(sessionToClose);
ConnectionFactoryUtils.releaseConnection(conToClose, this.getConnectionFactory(), startConnection);
https://www.jianshu.com/p/981b30ad9def session is closed 发生的原因
https://www.iteye.com/blog/cesymm-2003380 activemq对connection的管理
http://www.voidcn.com/article/p-rbmuatof-btp.html 对PooledConnectionFactory的分析

来源:51CTO
作者:殇城林
链接:https://blog.csdn.net/sinat_36454672/article/details/100156345