2013-10-30 9 views
13

Diğer kişilerin resmi RabbitMQ java istemci kitaplığını kullanarak hatalı bağlantıdan kurtarmanın nasıl işlediğini bilmek istiyorum. Uygulama sunucularımızı RabbitMQ kümemize bağlamak için kullanıyoruz ve bağlantı başarısızlığından kurtulmak için birkaç farklı yol uyguladık, ancak bunların hiçbiri tam olarak doğru değil.RabbitMQ java istemci kitaplığını kullanarak hatalı bir bağlantıdan kurtarmayı nasıl ele alırsınız?

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? 
     } 
    } 
} 

Gerçek dünyada tüketicilerin çeşitli yüzlerce:

bu sözde uygulamayı düşünün. Bağlantı kesilirse ne olur? Yukarıdaki örnekte, Tüketici1 kurtarılamaz, bağlantı kapandığında, Kanal da kapanır, kurtarılamayacağımız bir durum.

Çözüm A)

her tüketici kendi bağlantı atalım ve bağlantı öldüğünde tetikleyen olayları kaydetmek ve daha sonra yeniden bağlantı kolu: Yani bu çözmek için bazı yollar bakalım.

Artıları: Bu

Eksileri çalışır:

  • tüketiciyi çok şey var bu yana, muhtemelen birçok bağlantıları istemiyoruz.
  • Biz muhtemelen tavşana yeniden bağlanma için yinelenen kod bir sürü var ve

Çözüm B)

her tüketici aynı bağlantı kullanmak ve bağlantı hatası olayları var abone mı reconnecting işlemek olabilir.

Artıları: Bir

Cons Çözüm daha az bağlantıları: Bağlantı göre yeniden açmaya gerek kapalı olduğundan/değiştirin. Java istemci kütüphanesi bağlantıyı yeniden açmanın bir yolunu oluşturuyor gibi görünmüyor, bu yüzden yeni bir bağlantıyla değiştirmeliyiz ve bir şekilde tüm tüketicileri bu yeni bağlantıya bildirmeliyiz ve kanalları ve tüketicileri yeniden yaratmaları gerekiyordu. . Bir kez daha, tüketicide görmek istemediğim bir çok mantık orada bitiyor.

Çözüm C)

Wrap Connection ve Channel sınıflar yeniden bağlanma mantığını ele sınıflar ise, tüketici sadece WrappedChannel sınıfı hakkında bilmesi gerekir. Bağlantı arızasında WrappedConnection bağlantısı yeniden kurmaya başlayacak ve bir kez bağlandığında WrappedConnection otomatik olarak yeni Kanallar oluşturacak ve tüketicileri kaydedecektir.

Artıları: Çalışır - bu aslında bugün kullandığımız çözümdür.

Eksiler: Bir kesmek gibi geliyor, bence bu, temeldeki kütüphane tarafından daha zarif bir şekilde ele alınması gereken bir şey.

Belki daha iyi bir yolu var mı? API belgeleri hatalı bir bağlantıdan kurtarma hakkında çok fazla konuşmuyor.Herhangi bir girdi takdir edilir :)

cevap

6

RabbitMQ posta listesine bazı iyi yanıtlar aldım, temelde yukarıda listelediğim C çözümünü öneriyorum. Çözüm C)

Wrap Bağlantı ve Kanal sınıfları yeniden bağlanma mantığını ele sınıflar ise

, tüketici sadece WrappedChannel sınıfı hakkında bilmesi gerekir. Bağlantı başarısız olduğunda, WrappedConnection , bağlantıyı yeniden kurmayı ve WrappedConnection bağlantısını bağladıktan sonra otomatik olarak yeni Kanallar oluşturacak ve tüketicilerini kaydedecektir.

Artıları: Çalışır - bu aslında bugün kullandığımız çözümdür.

Eksiler: Bir kesmek gibi geliyor, bence bu, temeldeki kütüphane tarafından daha zarif bir şekilde ele alınması gereken bir şey.

Bu, Java istemcisinin üzerine inşa edilen iki istemcidir - Langohr ve March Hare - do. Bağlantı kurtarma şu anda Java istemci tarafından yapılmadığı için çevresiyle ilgili bir çalışma değil, gerekli bir iştir (bana sorarsanız bir çekirdek özellik olmalıdır). Yani bu uygulanabilir bir yaklaşımdır.

Lyra'ya da bir göz atın: https://github.com/jhalterman/lyra.

MK

Yazılım Mühendisi, Pivotal/RabbitMQ

Ve:

Merhaba Peter,

Çözüm C aslında oldukça makul. Ağ hataları veya küme bölümlerine karşı korumasına çalışıyorsanız, aynı sunucuya birden çok bağlantı kullanarak kazanmak için çok fazla bir şey yoktur. Bir bağlantısı ölürse, bunların hepsi büyük ihtimalle olacaktır. Sarma ve kurtarma bağlantıları/kanalları iyi çalışıyor ve Michael'ın belirttiği gibi, da sizin için kaynakların kurtarılmasıyla ilgili çeşitli köşe durumlarını ele aldığından dolayı Lyra'yı kontrol edebilirsiniz.

Alkış, Jonathan

burada tam okumak:

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

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

+0

sen bu kodu nasıl tam üzerinde ipucu verebilir. Tüm kanalları, sıraları ve bağları kurtaracağımız bir geri arama olmadığı anlaşılıyor. Bağlantıyı tam olarak nasıl sarmam gerektiğini söyleyebilir misin? – jeevs

+0

Sen Bağlantı ve Kanal sarmak zorunda kalacak, bu kesildi sonra yeni bir tane oluşturmak zorunda kalacak şekilde bir kanal kurtarmanın yolu yoktur. –

İlgili konular