2013-10-30 4 views
13

다른 사람들이 공식 RabbitMQ 자바 클라이언트 라이브러리를 사용하여 잘못된 연결을 복구하는 방법을 알고 싶습니다. 우리는 그것을 우리의 RabbitMQ 클러스터에 우리의 응용 프로그램 서버를 연결하는 데 사용하고 우리는 연결 실패로부터 복구하는 몇 가지 다른 방법을 구현했지만 그 중 누구도 옳지 않다고 느낍니다.RabbitMQ Java 클라이언트 라이브러리를 사용하여 잘못된 연결 복구를 어떻게 처리합니까?

public class OurClassThatStartsConsumers { 
    Connection conn; 

    public void start() { 
     ConnectionFactory factory = new ConnectionFactory(); 
     factory.setUsername("someusername"); 
     factory.setPassword("somepassword"); 
     factory.setHost("somehost"); 
     conn = factory.newConnection(); 

     new Thread(new Consumer(conn.createChannel())).start(); 
    } 
    } 

class Consumer1 implements Runnable { 
    public Consumer1(Channel channel) { 
     this.channel = channel; 
    } 

    @Override 
    public void run() { 
     while (true) { 
      ... consume incoming messages on the channel... 
      // How do we handle that the connection dies? 
     } 
    } 
} 

현실 세계에서 우리가 소비자의 수백이 있습니다

이 의사 응용 프로그램을 상상해보십시오. 연결이 끊어지면 어떻게됩니까? 위의 예에서 Consumer1은 복구 할 수 없습니다. 연결이 닫히면 채널도 닫히고 복구 할 수없는 상태가됩니다.

솔루션 A)

는 모든 소비자가 자신의 연결을하자 연결이 죽을 때 트리거 이벤트를 등록한 다음 다시 연결 핸들을 : 그래서이 문제를 해결하는 몇 가지 방법 볼 수 있습니다.

장점 : 그것은

단점을 작품 :

  • 우리는 소비자를 많이 가지고 있기 때문에, 우리는 아마 많은 연결을 원하지 않는다.
  • 우리는 아마도 토끼에 다시 연결에 대한 중복 코드를 많이 가지고

솔루션 B)

는 각 소비자가 동일한 연결을 사용하고 연결 실패 이벤트의 구독 가지고 다시 연결 처리 할 수 ​​있습니다.

장점 :

단점 솔루션보다 적은 연결 : 연결이 우리가 다시 할 필요가 폐쇄되기 때문에/교체하십시오. Java 클라이언트 라이브러리는 연결을 다시 열 수있는 방법을 제공하지 않는 것 같습니다. 따라서 새 연결로 바꾸고 모든 소비자에게이 새로운 연결에 대해 알리고 고객과 채널을 다시 만들어야합니다. . 다시 한번, 소비자가보고 싶지 않은 많은 논리가 거기에서 끝납니다.

솔루션 C)

ConnectionChannel 클래스가 재 연결 로직을 처리하는 클래스이며, 소비자는 단지 WrappedChannel 클래스에 대해 알 필요가있다. 연결이 실패하면 WrappedConnection은 연결을 다시 설정하고 일단 연결하면 WrappedConnection은 자동으로 새 채널을 만들고 사용자를 등록합니다.

장점 : 실제로 작동합니다. 실제로 이것은 현재 우리가 사용하고있는 솔루션입니다.

단점 : 해킹 된 것처럼 느껴질 수 있습니다. 이는 기본 라이브러리에서보다 우아하게 처리해야한다고 생각합니다.

아마도 더 좋은 방법이 있을까요? API 문서는 잘못된 연결에서 복구하는 것에 관해 그다지 이야기하지 않습니다.모든 입력을 주시면 감사하겠습니다 :)

답변

6

RabbitMQ 메일 링리스트에서 좋은 답변을 얻었습니다. 기본적으로 위에 열거 된 해결책 C가 나와 있습니다. 솔루션 C)

랩 연결 및 채널 클래스가 재 연결 로직을 처리하는 클래스이다

는, 소비자는 단지 WrappedChannel 클래스에 대해 알 필요가있다. 연결 실패시 WrappedConnection 은 연결을 다시 설정하고 일단 연결되면 WrappedConnection은 자동으로 새 채널을 만들고 소비자를 등록합니다.

장점 : 실제로 작동합니다. 현재 실제로 사용하고있는 솔루션입니다.

단점 : 해킹 된 것처럼 느껴질 수 있습니다. 이는 기본 라이브러리에서보다 우아하게 처리해야한다고 생각합니다.

두 클라이언트가 Java one-Langohr 및 March Hare-do 위에 구축 한 것입니다. Java의 클라이언트가 연결 복구를 현재 수행하지 않기 때문에 해킹이 아니지만 주위에 필요한 작업이 필요합니다 (사용자가 저에게 묻는다면 핵심 기능이어야합니다).

이렇게 가능한 실행 방법입니다.

라이라 (Lyra)도보십시오 : https://github.com/jhalterman/lyra.

MK

소프트웨어 엔지니어, 중추/RabbitMQ

그리고 :

안녕 피터,

솔루션 C는 실제로 매우 합리적이다. 네트워크 장애 또는 클러스터 파티션으로부터 보호하려는 경우 을 얻지 않아도 동일한 서버에 여러 개의 연결을 사용할 수 있습니다. 하나의 연결이 끊어지면 모두 가능합니다. 연결/채널을 감싸고 복구하는 것이 좋습니다. Michael이 언급했듯이 도 자원 회수에 관련된 다양한 코너 케이스 을 처리하기 때문에 Lyra를 체크 아웃 할 수도 있습니다.

건배, 조나단

여기에 전체 스레드를 읽기 :

http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2013-October/031564.html

http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2013-November/031573.html

+0

정확하게 코딩하는 방법에 대한 힌트를 줄 수 있습니까? 우리가 모든 채널, 대기열 및 바인딩을 복구 할 수있는 콜백이없는 것처럼 보입니다. 정확히 내가 연결을 어떻게 포장해야하는지 말해 줄 수 있니? – jeevs

+0

연결 및 채널을 래핑해야하므로 연결이 끊긴 채널을 복구 할 방법이 없으므로 새 채널을 만들어야합니다. –

10

버전이의 새로운 기능으로 자동 복구를 사용할 수 있습니다 3.3.0 이후 자바 클라이언트. Java API 가이드 (http://www.rabbitmq.com/api-guide.html#recovery)

자동 연결 복구를 사용하려면 팩토리를 사용하십시오.setAutomaticRecovery (true) :

관련 문제