2013-10-30 33 views
13

我很想知道其他人如何使用官方RabbitMQ java客户端库来处理从错误连接中恢复的问题。我们正在使用它将我们的应用程序服务器连接到我们的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无法恢复,当连接关闭时,Channel也关闭,我们无法恢复的状态。所以,让我们看看一些方法来解决这个问题:

解决方案A)

让每一个消费者都有自己的连接,并登记在连接死亡触发的事件,然后重新连接处理。

优点:它的工作原理

缺点:

  • 因为我们有很多的消费者,我们可能不希望很多 连接。
  • 我们有可能会拥有 重新连接到兔子大量的重复的代码和处理重新连接

溶液B)

让每个消费者使用相同的连接,并订阅它的连接故障事件。

优点:比解决方案A

缺点更少的连接:由于连接被关闭,我们需要重新打开/替换它。 java客户端库似乎没有提供重新打开连接的方式,所以我们必须用新连接来替换它,然后以某种方式通知所有消费者关于这个新连接,并且他们将不得不重新创建渠道和消费者。再一次,我不想在消费者身上看到很多逻辑。

解决方案C)

ConnectionChannel类是处理重新连接逻辑类,消费者只需要了解WrappedChannel类。在连接失败时,WrappedConnection将处理重新建立的连接,一旦连接,WrappedConnection将自动创建新的通道并注册使用者。

优点:它的工作原理 - 这实际上是我们今天使用的解决方案。

缺点:这感觉就像是黑客,我认为这是应该由底层库更优雅地处理的东西。

也许有更好的方法? API文档没有涉及从错误连接恢复的问题。任何输入赞赏:)

回答

6

在RabbitMQ邮件列表上得到了一些很好的答案,基本上推荐了解决方案C,如上所列。

解决方案C)

绕接和通道类是处理重新连接逻辑类,消费者只需要了解 WrappedChannel类。在连接失败时,WrappedConnection 处理重新建立连接,并且一旦连接 WrappedConnection将自动创建新的通道并注册消费者。

优点:它的工作原理 - 这实际上是我们今天使用的解决方案。

缺点:这感觉就像是黑客,我认为这是应该由底层库更优雅地处理的东西。

这就是两个客户端建立在Java之上的一个 - Langohr 和March Hare - do。这不是黑客攻击,而是围绕 进行必要的工作,因为连接恢复目前不由Java 客户端执行(如果你问我,它应该是一个核心功能)。

所以这是一个可行的方法。

看看莱拉也是:https://github.com/jhalterman/lyra

MK

软件工程师,枢纽/ RabbitMQ的

和:

喜彼得,

C液实际上是非常合理的。如果您想要防止网络故障或集群分区,那么获得 就不需要使用多个连接到同一台服务器。如果一个连接死亡,他们都可能会。包装和恢复 连接/通道正常工作,正如迈克尔提到的那样,您可能还会检查出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

您必须包装连接和频道,一旦它断开连接,无法恢复频道,因此您必须创建一个新频道。 –