ActiveMQ 的session和Connection , 及报错 session is closed处理。

匿名 (未验证) 提交于 2019-12-02 23:56:01

在集成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  只会往PooledConnectionloanedSessions 中添加。 调用一次就添加一次。  源码如下
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的分析

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!