2016-11-10 3 views
1

나는 아래비동기 및 공유 토끼 템플릿

@Bean 
    public ConnectionFactory connectionFactory() { 
    CachingConnectionFactory connectionFactory = new   CachingConnectionFactory(hostName); 
    connectionFactory.setUsername(mqUsername); 
    connectionFactory.setPassword(mqPassword); 
    connectionFactory.setVirtualHost(virtualHost); 
    return connectionFactory; 
    } 

    @Bean 
    RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) { 
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); 
    rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter()); 
    return rabbitTemplate; 
    } 

    @Bean 
    public AmqpAdmin amqpAdmin() { 
    RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory()); 
    return rabbitAdmin; 
    } 

같은 큐의 설정을 가지고 있고 나는 AMQP 관리자와 토끼 템플릿 콩을 사용하고

@EnableAsync 
@Configuration 
public class AsyncConfiguration implements AsyncConfigurer { 

    @Override 
    public Executor getAsyncExecutor() { 
     return taskExector(); 
    } 

    @Override 
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 
     return new SimpleAsyncUncaughtExceptionHandler(); 
    } 

    @Bean 
    public ThreadPoolTaskExecutor taskExector() { 
     ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 
     taskExecutor.setCorePoolSize(10); 
     taskExecutor.setMaxPoolSize(10); 
     taskExecutor.initialize(); 
     return taskExecutor; 
    } 

}  

처럼 그리고 내 비동기 방식의 비동기 설정을 가지고있다. 그래서 구성 당 최대 실행 작업에서 10 개의 스레드를 갖게 될 것입니다. 잠시 후에 응용 프로그램이 멈추고 액추에이터를 사용하여 덤프를 가져온 결과, 아래 정보를 찾으면 줄 번호에서 토끼 서식 파일/amqp admin bean을 사용할 때 교착 상태가됩니다. 이 방법에 문제가 있거나 여러 스레드가 해당 rabbit mq beans에 액세스 할 수 있는지 확인하는 방법이 잘못되었습니다.

버전 : 봄 부팅 1.4.0.RELEASE, 자바 8.

@Service 
public class QDispatcherService implements DispatcherService { 
    private final Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @Autowired 
    private AmqpAdmin amqpAdmin; 


    @Autowired 
    RabbitTemplate rabbitTemplate; 

    @Override 
    public void sendData(Data dataObject) throws Exception { 

     try { 
      //something on this properties , I have to check if queue exist or there are messages in it to decide to add message in other queue 
      Properties properties = amqpAdmin.getQueueProperties(queueName); 
      amqpAdmin.declareQueue(new Queue(queueName)); 
      logger.info("***********************DEBUG 4***********************"); 
      rabbitTemplate.convertAndSend(queueName, dataObject); 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

} 

{ 
    "threadName": "taskExector-10", 
    "threadId": 77, 
    "blockedTime": -1, 
    "blockedCount": 317, 
    "waitedTime": -1, 
    "waitedCount": 379, 
    "lockName": "[email protected]", 
    "lockOwnerId": -1, 
    "lockOwnerName": null, 
    "inNative": false, 
    "suspended": false, 
    "threadState": "WAITING", 
    "stackTrace": [ 
     { 
     "methodName": "wait", 
     "fileName": "Object.java", 
     "lineNumber": -2, 
     "className": "java.lang.Object", 
     "nativeMethod": true 
     }, 
     { 
     "methodName": "wait", 
     "fileName": "Object.java", 
     "lineNumber": 502, 
     "className": "java.lang.Object", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "get", 
     "fileName": "BlockingCell.java", 
     "lineNumber": 50, 
     "className": "com.rabbitmq.utility.BlockingCell", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "uninterruptibleGet", 
     "fileName": "BlockingCell.java", 
     "lineNumber": 89, 
     "className": "com.rabbitmq.utility.BlockingCell", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "uninterruptibleGetValue", 
     "fileName": "BlockingValueOrException.java", 
     "lineNumber": 33, 
     "className": "com.rabbitmq.utility.BlockingValueOrException", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "getReply", 
     "fileName": "AMQChannel.java", 
     "lineNumber": 361, 
     "className": "com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "privateRpc", 
     "fileName": "AMQChannel.java", 
     "lineNumber": 226, 
     "className": "com.rabbitmq.client.impl.AMQChannel", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "exnWrappingRpc", 
     "fileName": "AMQChannel.java", 
     "lineNumber": 118, 
     "className": "com.rabbitmq.client.impl.AMQChannel", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "queueDeclare", 
     "fileName": "ChannelN.java", 
     "lineNumber": 844, 
     "className": "com.rabbitmq.client.impl.ChannelN", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "queueDeclare", 
     "fileName": "ChannelN.java", 
     "lineNumber": 61, 
     "className": "com.rabbitmq.client.impl.ChannelN", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "invoke", 
     "fileName": null, 
     "lineNumber": -1, 
     "className": "sun.reflect.GeneratedMethodAccessor176", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "invoke", 
     "fileName": "DelegatingMethodAccessorImpl.java", 
     "lineNumber": 43, 
     "className": "sun.reflect.DelegatingMethodAccessorImpl", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "invoke", 
     "fileName": "Method.java", 
     "lineNumber": 498, 
     "className": "java.lang.reflect.Method", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "invoke", 
     "fileName": "CachingConnectionFactory.java", 
     "lineNumber": 916, 
     "className": "org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "queueDeclare", 
     "fileName": null, 
     "lineNumber": -1, 
     "className": "com.sun.proxy.$Proxy166", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "declareQueues", 
     "fileName": "RabbitAdmin.java", 
     "lineNumber": 577, 
     "className": "org.springframework.amqp.rabbit.core.RabbitAdmin", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "access$200", 
     "fileName": "RabbitAdmin.java", 
     "lineNumber": 67, 
     "className": "org.springframework.amqp.rabbit.core.RabbitAdmin", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "doInRabbit", 
     "fileName": "RabbitAdmin.java", 
     "lineNumber": 209, 
     "className": "org.springframework.amqp.rabbit.core.RabbitAdmin$3", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "doInRabbit", 
     "fileName": "RabbitAdmin.java", 
     "lineNumber": 206, 
     "className": "org.springframework.amqp.rabbit.core.RabbitAdmin$3", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "doExecute", 
     "fileName": "RabbitTemplate.java", 
     "lineNumber": 1394, 
     "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "execute", 
     "fileName": "RabbitTemplate.java", 
     "lineNumber": 1367, 
     "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "execute", 
     "fileName": "RabbitTemplate.java", 
     "lineNumber": 1343, 
     "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "declareQueue", 
     "fileName": "RabbitAdmin.java", 
     "lineNumber": 206, 
     "className": "org.springframework.amqp.rabbit.core.RabbitAdmin", 
     "nativeMethod": false 
     }, 
     { 
     "methodName": "sendData", 
     "fileName": "QDispatcherService.java", 
     "lineNumber": 59, 
     "className": "com.mycompany.QDispatcherService", 
     "nativeMethod": false 
     }, 

     .... 

     "lockedMonitors": [ 
     { 
     "className": "java.lang.Object", 
     "identityHashCode": 285810320, 
     "lockedStackFrame": { 
      "methodName": "invoke", 
      "fileName": "CachingConnectionFactory.java", 
      "lineNumber": 916, 
      "className": "org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler", 
      "nativeMethod": false 
     }, 
     "lockedStackDepth": 13 
     } 
    ], 
    "lockedSynchronizers": [ 
     { 
     "className": "java.util.concurrent.ThreadPoolExecutor$Worker", 
     "identityHashCode": 372417558 
     } 
    ], 
    "lockInfo": { 
     "className": "com.rabbitmq.utility.BlockingValueOrException", 
     "identityHashCode": 274673849 
    } 
    }, 

________________________________________________________________________-

새로운 추적

같은 내 서비스 뭔가
{ 
"threadName": "taskExector-10", 
"threadId": 77, 
"blockedTime": -1, 
"blockedCount": 37, 
"waitedTime": -1, 
"waitedCount": 1113, 
"lockName": "[email protected]", 
"lockOwnerId": 65, 
"lockOwnerName": "taskExector-8", 
"inNative": false, 
"suspended": false, 
"threadState": "BLOCKED", 
"stackTrace": [ 
    { 
    "methodName": "writeFrame", 
    "fileName": "SocketFrameHandler.java", 
    "lineNumber": 170, 
    "className": "com.rabbitmq.client.impl.SocketFrameHandler", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "writeFrame", 
    "fileName": "AMQConnection.java", 
    "lineNumber": 542, 
    "className": "com.rabbitmq.client.impl.AMQConnection", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "transmit", 
    "fileName": "AMQCommand.java", 
    "lineNumber": 104, 
    "className": "com.rabbitmq.client.impl.AMQCommand", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "quiescingTransmit", 
    "fileName": "AMQChannel.java", 
    "lineNumber": 337, 
    "className": "com.rabbitmq.client.impl.AMQChannel", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "transmit", 
    "fileName": "AMQChannel.java", 
    "lineNumber": 313, 
    "className": "com.rabbitmq.client.impl.AMQChannel", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "basicPublish", 
    "fileName": "ChannelN.java", 
    "lineNumber": 686, 
    "className": "com.rabbitmq.client.impl.ChannelN", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "basicPublish", 
    "fileName": "ChannelN.java", 
    "lineNumber": 668, 
    "className": "com.rabbitmq.client.impl.ChannelN", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "invoke", 
    "fileName": null, 
    "lineNumber": -1, 
    "className": "sun.reflect.GeneratedMethodAccessor176", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "invoke", 
    "fileName": "DelegatingMethodAccessorImpl.java", 
    "lineNumber": 43, 
    "className": "sun.reflect.DelegatingMethodAccessorImpl", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "invoke", 
    "fileName": "Method.java", 
    "lineNumber": 498, 
    "className": "java.lang.reflect.Method", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "invoke", 
    "fileName": "CachingConnectionFactory.java", 
    "lineNumber": 916, 
    "className": "org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "basicPublish", 
    "fileName": null, 
    "lineNumber": -1, 
    "className": "com.sun.proxy.$Proxy166", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "doSend", 
    "fileName": "RabbitTemplate.java", 
    "lineNumber": 1451, 
    "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "doInRabbit", 
    "fileName": "RabbitTemplate.java", 
    "lineNumber": 703, 
    "className": "org.springframework.amqp.rabbit.core.RabbitTemplate$3", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "doExecute", 
    "fileName": "RabbitTemplate.java", 
    "lineNumber": 1394, 
    "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "execute", 
    "fileName": "RabbitTemplate.java", 
    "lineNumber": 1367, 
    "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "send", 
    "fileName": "RabbitTemplate.java", 
    "lineNumber": 699, 
    "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "convertAndSend", 
    "fileName": "RabbitTemplate.java", 
    "lineNumber": 767, 
    "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
    "nativeMethod": false 
    }, 
    { 
    "methodName": "convertAndSend", 
    "fileName": "RabbitTemplate.java", 
    "lineNumber": 754, 
    "className": "org.springframework.amqp.rabbit.core.RabbitTemplate", 
    "nativeMethod": false 
    } 
+0

'RabbitTemplate'과'RabbitAdmin'을 어떻게 사용하는지 코드를 보여 주어야합니다. –

+0

주 질문에 추가했습니다. – user3444718

+0

좋습니다. 당신이 우리의 측면에서 재생할 간단한 부팅 응용 프로그램을 공유 할 수 있습니까? –

답변

0

모든 전송시에 대기열을 선언하는 것이 약간 이상합니다. 그것은 비효율적 인 것 말고는 효과가있다. 스택 추적은 우리가 대기열 선언에 대한 응답을 기다리는 토끼 클라이언트에 갇혀 있음을 나타냅니다. 나는 하나 이상의 쓰레드가 같은 채널을 사용할 때 이것을 보았으나, 현재 작업 (admin, template)이 완료되고 다중 쓰레드에 의해 사용될 수 없을 때 채널이 항상 캐시로 반환되기 때문에 결코 일어나지 않아야한다.

이제 새로운 4.0.0.RC1 amqp-client 항아리가 로깅을 추가 했으므로 (xx 클라이언트에서 사용할 수 없음) jar를 시도 할 수 있습니다. 상황을 추적하는 데 도움이 될 수 있습니다.

+0

새 버전을 사용하려고합니다. 사용하려고하는 다른 응용 프로그램이 있기 때문에 배제하고 싶습니다./대기열을 소멸 시키거나 대기열을 선언하려고 할 때 같은 시간에 대기열을 삭제하십시오 .UH가 토끼의 응답을 기다리고 있다고 말하면 비동기를위한 사용자 정의 스레드 풀 때문에 자원 잠금과 같은 것이 없다는 것을 의미합니까? 티 그것을 확증하는 것이 아니라 깨달으십시오. (초기 실험은 내 서비스의 비동기 특성을 제거하면 잘 작동하지만 더 많은 테스트를 수행해야합니다.) 그리고 토끼 조작을 위해 설정하는 방법과 시간을 맞추지 않는 이유는 무엇입니까 – user3444718

+0

나는 토끼 클라이언트의 내부 구조에 대해 충분히 잘 모릅니다.이 질문은 rabbitmq-users google 그룹에 문의해야합니다. 나는 누군가가 메시지를 보낸 메시지를 보내려고 할 때만 이것을 보았습니다 - 비슷한 교착 상태였습니다 - 그러나 여기서 당신은 필수적으로 사용하는 것을 보지 못합니다. –

+0

amqp lib를 직접 사용하고 있지 않습니다. spring-ampq는 1.6.1.RELEASE입니다. (spring-boot-starter-amqp spring boot ver 1.4.0.release) – user3444718