2014-09-05 102 views
0

我們在生產中有一個彈簧應用程序,看起來它正在泄漏線程。Spring集成:應用程序泄漏SimpleAsyncTaskExecutor線程?

當我做一個線程轉儲時,我看到以下線程似乎在等待。下面是下面的例子,但也有成千上萬的

"SimpleAsyncTaskExecutor-1801" prio=10 tid=0x00007fa668413800 nid=0x376c waiting on condition [0x00007fa4fbaff000] 
    java.lang.Thread.State: WAITING (parking) 
     at sun.misc.Unsafe.park(Native Method) 
     - parking to wait for <0x00000007777e2ba8> (a java.util.concurrent.CountDownLatch$Sync) 
     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:994) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1303) 
     at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:236) 
     at org.springframework.integration.core.MessagingTemplate$TemporaryReplyChannel.receive(MessagingTemplate.java:415) 
     at org.springframework.integration.core.MessagingTemplate$TemporaryReplyChannel.receive(MessagingTemplate.java:409) 
     at org.springframework.integration.core.MessagingTemplate.doReceive(MessagingTemplate.java:317) 
     at org.springframework.integration.core.MessagingTemplate.doSendAndReceive(MessagingTemplate.java:341) 
     at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:255) 
     at org.springframework.integration.core.MessagingTemplate.convertSendAndReceive(MessagingTemplate.java:290) 
     at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:224) 
     at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceive(MessagingGatewaySupport.java:203) 
     at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:306) 
     at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:269) 
     at org.springframework.integration.gateway.GatewayProxyFactoryBean.access$200(GatewayProxyFactoryBean.java:71) 
     at org.springframework.integration.gateway.GatewayProxyFactoryBean$AsyncInvocationTask.call(GatewayProxyFactoryBean.java:499) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
     at java.lang.Thread.run(Thread.java:745) 

最終達到一個地步,這將導致服務器無法響應,只有重啓會拿回來。

這似乎涉及到一個Spring集成網關,它發送一條消息,正在等待一些永不會得到的答案。在我們的應用程序,使用這個唯一的地方是發送(發佈)這些消息到RabbitMQ的交換,使用服務接口

這是服務接口代碼的通知通道:

@Component 
public interface INotificationSender { 

    Future<Void> sendNotification(@Payload Object notification, 
      @Header("routingKey") String routingKey, 
      @Header("notificationType") String type); 
} 

這是相關的Spring配置:

<!-- Spring Integration RabbitMQ adapter -->   
<rabbit:template 
    id="amqpTemplate" 
    connection-factory="notificationConnectionFactory" /> 

<rabbit:connection-factory 
    id="notificationConnectionFactory" 
    addresses="${notificationChannel.rabbitHost1}:${notificationChannel.rabbitPort}, ${notificationChannel.rabbitHost2}:${notificationChannel.rabbitPort}" 
    username="${notificationChannel.rabbitUsername}" 
    password="${notificationChannel.rabbitPassword}" 
    virtual-host="${notificationChannel.rabbitVirtualHost}"/> 

<rabbit:topic-exchange 
    name="notificationExchange"/> 


<!-- Spring Integration AMQP -->   
<int-amqp:outbound-channel-adapter 
    id="notificationChannelAdapter" 
    channel="notificationChannelEnc" 
    exchange-name="notificationExchange" 
    routing-key-expression="headers['routingKey']" 
    mapped-request-headers="STANDARD_REQUEST_HEADERS, notificationType"/> 


<!-- Spring Integration Core --> 
<int:channel 
    id="notificationChannelEnc"> 
    <int:interceptors> 
     <int:wire-tap channel="loggingChannel" /> 
    </int:interceptors> 
</int:channel> 

<int:channel id="notificationChannel"/> 

<int:object-to-json-transformer 
    id="NotificationEncoder" 
    content-type="text/x-json" 
    input-channel="notificationChannel" 
    output-channel="notificationChannelEnc"/>  

<int:gateway 
    id="notificationGateway" 
    default-request-channel="notificationChannel" 
    service-interface="com.ericsson.ericloud.commander.notification.sender.INotificationSender"/> 

我們使用Spring版本3.2.3.RELEASE和Spring集成版本3.0.0.M2

任何人有任何想法如何處理這個問題,讓這些線程正確終止?

謝謝, /塞巴斯蒂安

回答

0

Future<Void>是一個瓶頸。

我可以猜測你想異步發送通知,不要等待任何回覆。 但無論如何Gateway嘗試等待回覆,因爲它看到Future作爲啓動異步過程的提示。

爲了克服它,你必須改變返回到簡單的void和使用ExecutorChannel作爲網關的default-request-channel

查看更多的信息在Reference Manual