2013-11-28 4 views
0

먼저이 질문을 다른 곳에서 처리 한 경우 사과 드리며 내 문제는 해결하지 못했습니다.RabbitMQ java.lang.OutOfMemoryError

외부에 msg를받는 게이트웨이 서버가 있습니다. 주문 처리 서버가 대기중인 대기열에 넣습니다. 주문 처리 서버는 2 개의 대기열 (스레드)에서 수신 대기합니다. 대기열 1 - 게이트웨이 서버, 대기열 2 - 지우기 서버.

그래서 내 주문 프로세서에는 작업자 스레드가 있습니다. ExecutorService를 사용하여 스레드를 관리하고 있습니다. 문제는 작업자 스레드에 있습니다.

작업자 스레드에서 삭제 서버 또는 게이트웨이 서버에 메시지를 게시하는 데 사용하는 두 개의 MQ 인스턴스를 만듭니다. 기본적으로 일부 처리를 수행 한 다음 해당 대기열에 해당 메시지를 게시해야합니다.

내가 알고 싶은 것은 메시지를 처리 ​​할 때마다 작업자 스레드에서 채널과 연결을 닫아야한다는 것입니다.

내가 8-900 메시지를 처리 ​​한 후 다음 메시지를 처리 ​​한 후 모든 작업자 스레드에서 MQ 연결을 닫지 않으면, 나는 간헐적으로 다음과 같은 예외를 받기 시작 : I가 연결을 종료 할 경우

java.lang.OutOfMemoryError: unable to create new native thread 
    at java.lang.Thread.start0(Native Method) 
    at java.lang.Thread.start(Unknown Source) 
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:307) 
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:516) 
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:533) 
    at interfaces.MQ.<init>(MQ.java:41) 
    at orderProcessor.ProcessOrders.<init>(ProcessOrders.java:109) 
    at orderProcessor.ProcessIncomingCSThread.spawnThread(ProcessIncomingCSThread.java:52) 
    at orderProcessor.ProcessIncomingCSThread.spawnThread(ProcessIncomingCSThread.java:70) 
    at orderProcessor.ProcessIncomingCSThread.spawnThread(ProcessIncomingCSThread.java:70) 
    at orderProcessor.ProcessIncomingCSThread.spawnThread(ProcessIncomingCSThread.java:70) 
    at orderProcessor.ProcessIncomingCSThread.spawnThread(ProcessIncomingCSThread.java:70) 
    at orderProcessor.ProcessIncomingCSThread.spawnThread(ProcessIncomingCSThread.java:70) 
    at orderProcessor.ProcessIncomingCSThread.routeIncoming(ProcessIncomingCSThread.java:45) 
    at interfaces.ProcessIncomingThread.run(ProcessIncomingThread.java:47) 

간헐적으로 잠시 내가 다음받을 예외 후 다음 MSG를 처리 한 후 모든 작업자 스레드 :]

Exception in thread "AMQP Connection 127.0.0.1:5672" java.lang.OutOfMemoryError: unable to create new native thread 
    at java.lang.Thread.start0(Native Method) 
    at java.lang.Thread.start(Unknown Source) 
    at com.rabbitmq.client.impl.ChannelManager.scheduleShutdownProcessing(ChannelManager.java:108) 
    at com.rabbitmq.client.impl.ChannelManager.handleSignal(ChannelManager.java:94) 
    at com.rabbitmq.client.impl.AMQConnection.finishShutdown(AMQConnection.java:696) 
    at com.rabbitmq.client.impl.AMQConnection.shutdown(AMQConnection.java:669) 
    at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:550) 

나는 합리적인 RabbitMQ의 내부 큐를 유지하기 위해 소비를위한 MQ 연결을 만들 때이 basicQos를 사용하고 . 이보고에 대한

_channel.queueDeclare(this._mqName.toString(), true, false, false, null); 
_channel.basicConsume(this._mqName.toString(), true, _consumer); 
_channel.basicQos(50); 

감사 및 제안이나 도움이 많이 주시면 감사하겠습니다 :

나는 다음과 같은 방식으로 소비를 위해 내 MQ 연결을 만들 수 있습니다. 내 컨텍스트에서 제대로 작동하지 않을 가능성이 많습니다.

+0

메시지를 보낼 때마다 연결과 채널을 닫을 필요가 없습니다. 또한, 우리는 여기서 어떤 하중을 말하고 있습니까? 전송할 때 서버가 흐름 상태로 들어 있습니까? – hveiga

+0

흐름 상태는 무엇을 의미합니까? 닫는 방법과 큐를 닫지 않는 방법을 모두 시도했습니다. 내 게이트웨이 서버가 2k 더미 주문을 생성하고 Order Processor가 처리하는 대기열로 밀어 넣습니다.작업자 스레드가 이후에 메시지를 큐에 푸시 할 필요가 없다면 작업자 스레드에서 게시하기 위해 MQ 연결을 피할 수있게되면 훨씬 쉬워졌습니다. – OriginalCliche

+0

브로커가 메시지를 교환기에서 대기열로 충분히 빠르게 라우팅 할 수없는 경우 RabbitMQ에서 플로우 상태가 발생합니다. 이런 일이 발생하면 생산자가 쓰러지고 브로커가로드를 처리 할 수있을 때까지 내부적으로 메시지가 누적되기 시작합니다. 메시지를 계속 보내려고하지만 브로커가 흐름 상태에있는 경우 메시지는 JVM 메모리에 저장되므로 어느 시점에서 메모리가 부족합니다. 흐름 상태가되는지 확인하려면 메시지를 보낼 때 브로커의 연결을 확인하여 흐름 또는 차단 상태를 확인해야합니다. – hveiga

답변

0

감사합니다. 나는이 문제를 해결했다.

모든 작업 스레드에서 연결을 만들고있었습니다. 이제 주 스레드에서 연결을 만들고 해당 연결에서 채널을 만드는 작업자 스레드로 전달합니다. 이것은 대우를 작동하는 것을 보인다.

그러나이 워크 플로를 처리하기 위해 MQ 클래스를 다시 설계해야합니다.

0

메모리 누수가있는 것 같습니다. 프로파일 러를 사용하십시오.

0

저는 RabbitMQ에 익숙하지 않지만, 귀하 또는 RabbitMQ가 OS가 처리하도록 구성된 스레드를 더 많이 생성하려고합니다. 어쩌면이 두 개의 링크는 당신을 도울 수 있습니다 : 입력들에 대한

- http://stackoverflow.com/questions/16789288/java-lang-outofmemoryerror-unable-to-create-new-native-thread 
- http://javaeesupportpatterns.blogspot.de/2012/09/outofmemoryerror-unable-to-create-new.html