Spring CachingConnectionFactory在Tibco EMS代理重启时挂起

时间:2018-06-15 10:39:37

标签: spring jms spring-jms tibco-ems

我们在JMS应用程序的发送方使用Spring的CachingConnectionFactory,它向Tibco EMS发送消息。

我们在重启EMS代理或存在容错交换机时遇到问题。

在CachingConnectionFactory中处理异常处理的调用会挂起并保持锁定,以防止将来客户端调用EMS。

这是堆栈跟踪

TIBCO EMS TCPLink Reader (Server-880629)" - Thread t@457
   java.lang.Thread.State: WAITING
        at java.lang.Object.wait(Native Method)
        - waiting on <20035387> (a com.tibco.tibjms.TibjmsxResponse)
        at java.lang.Object.wait(Object.java:502)
        at com.tibco.tibjms.TibjmsxLink.sendRequest(TibjmsxLink.java:359)
        at com.tibco.tibjms.TibjmsxLink.sendRequestMsg(TibjmsxLink.java:293)
        at com.tibco.tibjms.TibjmsxSessionImp._close(TibjmsxSessionImp.java:2836)
        at com.tibco.tibjms.TibjmsxSessionImp.close(TibjmsxSessionImp.java:4800)
        at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.physicalClose(CachingConnectionFactory.java:487)
        at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:317)
        at com.sun.proxy.$Proxy263.close(Unknown Source)
        at org.springframework.jms.connection.CachingConnectionFactory.resetConnection(CachingConnectionFactory.java:184)
        - locked <37550f2a> (a java.util.LinkedList)
        - locked <7e847e44> (a java.util.HashMap)
        at org.springframework.jms.connection.SingleConnectionFactory.onException(SingleConnectionFactory.java:360)
        at org.springframework.jms.connection.SingleConnectionFactory$AggregatedExceptionListener.onException(SingleConnectionFactory.java:716)
        at com.tibco.tibjms.TibjmsConnection._invokeOnExceptionCallback(TibjmsConnection.java:2029)
        at com.tibco.tibjms.TibjmsConnection._reconnect(TibjmsConnection.java:1902)
        at com.tibco.tibjms.TibjmsConnection$ServerLinkEventHandler.onEventReconnect(TibjmsConnection.java:364)
        at com.tibco.tibjms.TibjmsxLinkTcp._doReconnect(TibjmsxLinkTcp.java:602)
        at com.tibco.tibjms.TibjmsxLinkTcp$LinkReader.work(TibjmsxLinkTcp.java:319)
        - locked <405e282> (a java.lang.Object)
        at com.tibco.tibjms.TibjmsxLinkTcp$LinkReader.run(TibjmsxLinkTcp.java:259)

基本上有两个锁。第一个(在上面的堆栈跟踪中表示为锁定&lt; 405e282&gt;)与其他线程共享,并阻止任何线程发送新请求

synchronized (TibjmsxLinkTcp.this._sendLock)
/*      */           {
/*  315 */             if ((TibjmsxLinkTcp.this._state == 1) && 
/*      */ 
/*  317 */               (TibjmsxLinkTcp.this._doReconnect(false))) {
/*  318 */               break label0:
/*      */             }
/*      */           }

这似乎足够合理。问题出在另一个锁上,表示为 &LT; 20035387&GT;在堆栈跟踪中

try
/*     */         {
/* 335 */           send(paramObject, i, localTibjmsxResponse);
/*     */         }

…

synchronized (localTibjmsxResponse)
/*     */       {
/* 351 */         while (localTibjmsxResponse.status == 0)
/*     */ 
/*     */ 
/*     */         {
/*     */           try
/*     */           {
/* 357 */             if (paramLong < -1L)
/* 358 */               localTibjmsxResponse.wait(-paramLong);
/*     */             else localTibjmsxResponse.wait();
/*     */ 
/*     */           }
/*     */           catch (InterruptedException localInterruptedException)
/*     */           {
/* 364 */             ??? = Tibjmsx.buildException("InterruptedException has occurred while waiting for server response", null, localInterruptedException);
/*     */           }
/*     */ 
/*     */         }

localTibjmsxResponse上的标志永远不会更改,因此线程会挂起。

我认为将Spring的CachingConnectionFactory与EMS结合使用是相当普遍的,不知其他人是否遇到同样的问题并知道解决方案是什么?

以下是我们创建配置的方法

public ConnectionFactory jmsConnectionFactory() {
        if (logger.isInfoEnabled()) {
            logger.info(
                    new StringBuilder("Initialising JMSSender using providerUrl=").append(this.providerUrl)
                            .append(", username=").append(this.username)
                            .append(", pass=").append(this.password)
                            .append(", attemptCount=").append(this.attemptCount)
                            .append(", attemptTimeout=").append(this.attemptTimeout)
                            .append(", attemptDelay=").append(this.attemptDelay).toString());
        }
        Tibjms.setExceptionOnFTSwitch(true);

        TibjmsTopicConnectionFactory topicConnectionFactory = new TibjmsTopicConnectionFactory(providerUrl);
        topicConnectionFactory.setUserName(username);
        topicConnectionFactory.setUserPassword(password);

        topicConnectionFactory.setConnAttemptCount(attemptCount);
        topicConnectionFactory.setConnAttemptTimeout(attemptTimeout);
        topicConnectionFactory.setConnAttemptDelay(attemptDelay);

        topicConnectionFactory.setReconnAttemptCount(attemptCount);
        topicConnectionFactory.setReconnAttemptTimeout(attemptTimeout);
        topicConnectionFactory.setReconnAttemptDelay(attemptDelay);

        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(topicConnectionFactory);
        cachingConnectionFactory.setReconnectOnException(true);
        cachingConnectionFactory.setExceptionListener(new JMSExceptionListener());
        cachingConnectionFactory.setSessionCacheSize(10);

        TransactionAwareConnectionFactoryProxy transactionAwareConnectionFactoryProxy = new TransactionAwareConnectionFactoryProxy();
        transactionAwareConnectionFactoryProxy.setTargetConnectionFactory(cachingConnectionFactory);
        transactionAwareConnectionFactoryProxy.setSynchedLocalTransactionAllowed(true);

        return transactionAwareConnectionFactoryProxy;
}

谢谢, 尼克

0 个答案:

没有答案