RabbitMQ ve kanal ve bağlantı arasındaki ilişki


176

RabbitMQ Java istemci aşağıdaki kavramlar vardır:

  • Connection - RabbitMQ sunucusu örneğine bağlantı
  • Channel - ???
  • Tüketici iş parçacığı havuzu - RabbitMQ sunucu kuyruklarından ileti tüketen bir iş parçacığı havuzu
  • Kuyruk - iletileri FIFO düzeninde tutan bir yapı

Ben ilişkiyi anlamaya çalışıyorum, çalışıyorum daha da önemlisi ve , dernek aralarında.

  1. Hala a'nın ne olduğundan emin değilim Channel, bunun yayınladığınız ve tükettiğiniz yapı olması ve açık bir bağlantıdan oluşturulması. Birisi bana "Kanal" ın neyi temsil ettiğini açıklayabilirse, birkaç şeyi temizlemenize yardımcı olabilir.
  2. Kanal ve Kuyruk arasındaki ilişki nedir? Aynı Kanal, çoklu Kuyruklarla iletişim kurmak için kullanılabilir mi, yoksa 1: 1 olması gerekir mi?
  3. Kuyruk ve Tüketici Havuzu arasındaki ilişki nedir? Birden fazla tüketici aynı kuyruğa abone olabilir mi? Aynı Tüketici tarafından birden fazla Kuyruk kullanılabilir mi? Yoksa ilişki 1: 1 mi?

Burada herhangi bir yardım için şimdiden teşekkürler!


Bu soruya cevap raporlama bana açtı bu konuyu golang müşteriyle ziyade burada soruyu soran.
Bruce Adams

Kanal, bir istemci ile bir düğüm arasındaki tek bir fiziksel TCP bağlantısını çoğaltmak için kullanılan mantıksal bir kavramdır. Kanal numarası AMQP çerçevesinin mesaj başlığına eklenir.
ymas

Yanıtlar:


196
  1. A Connection, Message Broker ile gerçek bir TCP bağlantısını temsil ederken Channel, a içindeki sanal bir bağlantıdır (AMQP bağlantısı). Bu şekilde, aracıyı TCP bağlantıları ile aşırı yüklemeden, uygulamanızın içinde istediğiniz sayıda (sanal) bağlantı kullanabilirsiniz.

  2. Her şey için bir tane kullanabilirsiniz Channel. Ancak, birden fazla Channeliş parçacığınız varsa, her iş parçacığı için farklı bir iş parçacığı kullanmanız önerilir .

    Java İstemci API Kılavuzu'nda kanal iş parçacığı güvenliği :

    Kanal örneklerinin birden çok iş parçacığı tarafından kullanılması güvenlidir. Bir Kanala yapılan istekler seri hale getirilir ve Kanalda aynı anda yalnızca bir iş parçacığı çalıştırılabilir. Yine de, uygulamalar aynı Kanalı birden çok iş parçacığında paylaşmak yerine iş parçacığı başına bir Kanal kullanmayı tercih etmelidir.

    Arasında doğrudan bir ilişki yoktur Channelve Queue. A Channel, aracıya AMQP komutları göndermek için kullanılır. Bu bir kuyruk veya benzeri bir şey olabilir, ancak bu kavramlar birbirine bağlı değildir.

  3. Her biri Consumer, tüketici iş parçacığı havuzundan ayrılan kendi iş parçacığında çalışır. Aynı Kuyruğa birden fazla Tüketici abone olursa aracı, iletileri aralarında eşit olarak dağıtmak için round-robin kullanır. İkinci eğiticiye bakın : "İş Kuyrukları" .

    Aynı Consumerşeyi birden fazla Kuyruğa eklemek de mümkündür . Tüketicileri geri arama olarak anlayabilirsiniz. Bunlar, Tüketicinin bağlı olduğu bir Kuyruğa her mesaj geldiğinde çağrılır. Java İstemcisi söz konusu olduğunda, her Tüketicinin handleDelivery(...)geri arama yöntemini temsil eden bir yöntemi vardır. Genelde yaptığınız şey, alt sınıf DefaultConsumerve geçersiz kılmadır handleDelivery(...). Not: Aynı Tüketici örneğini birden çok kuyruğa eklerseniz, bu yöntem farklı iş parçacıkları tarafından çağrılır. Bu yüzden gerekirse senkronizasyona dikkat edin.


4
Sadece dokümantasyondan eklemek için: Tüketicilere yapılan geri aramalar, Bağlantı tarafından yönetilen iş parçacığından ayrı bir iş parçacığına gönderilir. Bu, Tüketicilerin Bağlantı veya Kanaldaki queueDeclare, txCommit, basicCancel veya basicPublish gibi engelleme yöntemlerini güvenle çağırabileceği anlamına gelir. Her Kanalın kendi dağıtım iş parçacığı vardır. Kanal başına bir Tüketicinin en yaygın kullanım durumu için bu, Tüketicilerin diğer Tüketicileri tutmadığı anlamına gelir. Kanal başına birden fazla Tüketiciniz varsa, uzun süredir devam eden bir Tüketicinin söz konusu Kanaldaki diğer Tüketicilere geri arama gönderebileceğini unutmayın.
filip

1
Aynı Tüketici örneğini aynı Kanaldaki birden fazla Kuyruğa eklerseniz, geri çağrıların aynı iş parçacığında gönderileceği anlamına gelir. Bu durumda senkronizasyon gerekmez, değil mi?
filip

Bağlantı havuzu yerine yalnızca bir bağlantı kullanabilir ve kanal havuzu kullanabilir miyim? Bu mesaj yayınlama hacmini etkiler mi?
qeek

4
Java İstemci API'sine yapılan bu başvurunun artık eskimiş olduğunu ve aslında bugünkü referansın bu cevaptaki alıntıyla doğrudan çeliştiğini düşünüyorum. Bugünkü referans "Kanal örnekleri iş parçacıkları arasında paylaşılmamalıdır" diyor.
Edwin Dalorzo

1
@EdwinDalorzo - Görünüşe göre belgeleri kim yazdıysa kanal bağlantısı ikilemini tam olarak anlamadı. AMQP 0.9.1'in temel mimarisi gerçekten bir kanalı bir oturum olarak ele alır, bu nedenle bir oturumu paylaşan farklı iş parçacıkları gerçekten saçmadır. Benim tahminim bu değişikliğin sebebi.
theMayer

53

AMQP protokolünün "başlık altında" ne yaptığı konusunda iyi bir kavramsal anlayış burada yararlıdır. AMQP 0.9.1'in dağıtmayı seçtiği dokümantasyon ve API'nin bunu özellikle kafa karıştırıcı hale getirdiğini, bu yüzden sorunun kendisinin birçok insanın güreşmesi gereken bir şey olduğunu sunuyorum.

TL; DR

Bir bağlantı AMQP sunucusu ile fiziksel anlaşmalı TCP soket olduğunu. Düzgün uygulanmış istemciler, uygulama başına bunlardan birine sahip olacak, iş parçacığı açısından güvenli, iş parçacıkları arasında paylaşılabilir.

Bir kanal bağlantısı tek bir uygulama oturumu. Bir iş parçacığında bu oturumlardan biri veya daha fazlası bulunur. AMQP mimarisi 0.9.1, bunların iş parçacıkları arasında paylaşılmaması ve onu oluşturan iş parçacığı tamamlandığında kapatılması / imha edilmesi gerektiğidir. Ayrıca, çeşitli protokol ihlalleri meydana geldiğinde sunucu tarafından kapatılır.

Bir tüketici , belirli bir kanal üzerinde bir "posta kutusu" varlığını temsil eden bir sanal ve güvenilir olduğu bulunmuştur. Tüketicinin kullanımı, aracıya mesajları belirli bir kuyruktan o kanalın uç noktasına iletmesini söyler.

Bağlantı Gerçekleri

Diğerleri doğru belirttiğimiz gibi İlk olarak, bir bağlantı sunucusuna gerçek TCP bağlantısı temsil nesnesidir. Bağlantılar, AMQP'de protokol düzeyinde belirtilir ve aracıyla tüm iletişim bir veya daha fazla bağlantı üzerinden gerçekleşir.

  • Gerçek bir TCP bağlantısı olduğundan bir IP Adresi ve Port # vardır.
  • Protokol parametreleri, bağlantının kurulmasının bir parçası olarak ( el sıkışma olarak bilinen bir işlem) istemci başına görüşülür .
  • Uzun ömürlü olacak şekilde tasarlanmıştır ; bağlantı kapanmasının protokol tasarımının bir parçası olduğu birkaç durum vardır.
  • OSI açısından, muhtemelen Katman 6'nın etrafında bir yerde bulunur
  • TCP, kendi başına hiçbir şey içermediğinden kalp atışları bağlantı durumunu izleyecek şekilde ayarlanabilir.
  • Temel TCP soketine okuma ve yazma işlemlerini yönetmek için özel bir iş parçacığına sahip olmak en iyisidir. Hepsi olmasa da çoğu RabbitMQ istemcileri bunu yapar. Bu bağlamda, genel olarak diş açmaya karşı güvenlidirler.
  • Göreceli olarak, bağlantılar (tokalaşma nedeniyle) oluşturmak için "pahalı", ancak pratik olarak, bu gerçekten önemli değil. Çoğu işlem gerçekten sadece bir bağlantı nesnesine ihtiyaç duyacaktır. Ancak, tek bir iş parçacığının / soketin sağlayabileceğinden daha fazla iş hacmine ihtiyacınız olduğunu fark ederseniz, bir havuzdaki bağlantıları koruyabilirsiniz (mevcut bilgi işlem teknolojisiyle pek olası değildir).

Kanal Gerçekleri

Bir Kanal RabbitMQ komisyoncu ile iletişim kurmak için uygulamanın her parça için açılır uygulama oturumdur. Tek bir bağlantı üzerinden çalışır ve aracı ile bir oturumu temsil eder .

  • Uygulama mantığının mantıksal bir bölümünü temsil ettiğinden, her kanal genellikle kendi iş parçacığında bulunur.
  • Genellikle, uygulamanız tarafından açılan tüm kanallar tek bir bağlantıyı paylaşır (bunlar bağlantının üstünde çalışan hafif oturumlardır). Bağlantılar iş parçacığı için güvenlidir, bu yüzden sorun yok.
  • Çoğu AMQP işlemi kanallar üzerinden gerçekleşir.
  • OSI Katmanı perspektifinden bakıldığında, kanallar muhtemelen Katman 7 civarındadır .
  • Kanallar geçici olacak şekilde tasarlanmıştır ; AMQP tasarımının bir kısmı, kanalın bir hataya yanıt olarak tipik olarak kapalı olmasıdır (örneğin, mevcut kuyruğu silmeden önce farklı parametrelerle bir kuyruğun yeniden bildirilmesi).
  • Geçici oldukları için kanallar uygulamanız tarafından birleştirilmemelidir.
  • Sunucu, bir kanalı tanımlamak için bir tamsayı kullanır. Bağlantıyı yöneten iş parçacığı belirli bir kanal için bir paket aldığında, aracıya paketin hangi kanala / oturuma ait olduğunu söylemek için bu numarayı kullanır.
  • Kanallar genellikle evre için güvenli değildir, çünkü evreleri arasında paylaşmanın bir anlamı yoktur. Aracıyı kullanması gereken başka bir iş parçacığınız varsa, yeni bir kanal gereklidir.

Tüketici Gerçekleri

Tüketici, AMQP protokolü tarafından tanımlanan bir nesnedir. Ne bir kanal ne de bir bağlantıdır, bunun yerine özel uygulamanızın mesajları bırakmak için bir tür "posta kutusu" olarak kullandığı bir şeydir.

  • "Tüketici oluşturma", aracıya ( bağlantı yoluyla bir kanal kullanarak ) mesajların o kanal üzerinden size iletilmesini istediğinizi bildirir. Yanıt olarak, aracı kanalda bir tüketiciniz olduğunu kaydeder ve size mesaj göndermeye başlar.
  • Bağlantı üzerinden itilir Her mesaj bir iki referans olacak kanal numarasını ve bir tüketici sayısı . Bu şekilde, bağlantı yönetme iş parçacığı (bu durumda, Java API'sı içinde) ileti ile ne yapılacağını bilir; kanal işleme iş parçacığı da mesajla ne yapılacağını bilir.
  • Tüketici uygulaması tam anlamıyla uygulamaya özgü olduğu için en geniş çeşitliliğe sahiptir. Uygulamamda, tüketiciye her mesaj geldiğinde bir görevi kapatmayı seçtim; böylece, bağlantıyı yöneten bir iş parçacığı, kanalı yöneten bir iş parçacığı (ve ek olarak, tüketici) ve tüketici aracılığıyla teslim edilen her ileti için bir veya daha fazla görev iş parçacıkları vardı.
  • Bir bağlantının kapatılması bağlantıdaki tüm kanalları kapatır. Bir kanalın kapatılması kanaldaki tüm tüketicileri kapatır. Bir tüketiciyi iptal etmek de mümkündür (kanalı kapatmadan). Üç şeyden herhangi birini yapmanın mantıklı olduğu çeşitli durumlar vardır.
  • Tipik olarak, bir AMQP istemcisinde bir tüketicinin uygulanması, diğer iş parçacıklarının veya kodların (yayınlama dahil) faaliyetleriyle çakışmaları önlemek için tüketiciye özel bir kanal tahsis edecektir.

Tüketici iş parçacığı havuzu ile ne demek istediğim açısından, Java istemcisinin istemcimi yapması için programladığım şeye benzer bir şey yaptığını sanıyorum (benim .Net istemcisini temel alıyordu, ancak büyük ölçüde değiştirildi).


1
"kanallar havuzda
toplanmamalı

"Geçici oldukları için kanallar uygulamanız tarafından birleştirilmemelidir." - bu sonuca nasıl geldiğinizi açıklığa kavuşturabilirsiniz. "İş parçacığı başına bir kanal" uygulaması çok fazla kaynak kullanıyorsa dokümanlar kanal havuzlamayı önerir, buraya bakın: rabbitmq.com/channels.html#resource-usage
ymas

@ymas - Bahsettiğiniz belgeler spekülatif ve bence zayıf rehberlik. Kaynak kodu ve protokol spec okuyorum. Kanallar toplanamaz, nokta. Ayrıca, iplik başına bir kanal, bu aynı prensibe dayanan kılavuzdur. Sunucunun kaynak kısıtlı olduğu kadar çok açık kanalınız olduğunu fark ederseniz, mimarinizi yeniden değerlendirmeniz gerekir (örn. Yüksek kullanılabilirlik düzenine geçmeniz ve / veya eşzamanlılığı azaltmanız).
theMayer

21

AMQP modelinin kanalı olan tüm yönlerini açıklayan bu makaleyi buldum. Anlayışımı tamamlarken çok yararlı buldum

https://www.rabbitmq.com/tutorials/amqp-concepts.html

Bazı uygulamaların bir AMQP aracısına birden fazla bağlantıya ihtiyacı vardır. Ancak, birçok TCP bağlantısının aynı anda açık tutulması istenmez, çünkü bu sistem kaynaklarını tüketir ve güvenlik duvarlarını yapılandırmayı zorlaştırır. AMQP 0-9-1 bağlantıları, "tek bir TCP bağlantısını paylaşan hafif bağlantılar" olarak düşünülebilecek kanallarla çoklanır.

İşleme için birden çok iş parçacığı / işlem kullanan uygulamalar için, iş parçacığı / işlem başına yeni bir kanal açmak ve aralarında kanal paylaşmamak çok yaygındır.

Belirli bir kanaldaki iletişim, başka bir kanaldaki iletişimden tamamen ayrıdır, bu nedenle her AMQP yöntemi, istemcilerin yöntemin hangi kanal için olduğunu (ve dolayısıyla hangi olay işleyicinin çağrılması gerektiğini) bulmak için kullandıkları bir kanal numarası da taşır. .


4

Bir TCP bağlantısının birden fazla Kanala sahip olması gibi bir ilişki vardır .

Kanal : Bağlantının içindeki sanal bir bağlantıdır. Bir kuyruktan mesaj yayınlarken veya tüketirken - hepsi bir kanal üzerinden yapılır. Bağlantı : Uygulamanız ve RabbitMQ aracısı arasındaki bir TCP bağlantısıdır.

Çok iş parçacıklı mimaride, iş parçacığı başına ayrı bir bağlantıya ihtiyacınız olabilir. Bu, TCP bağlantısının gereğinden az kullanılmasına neden olabilir, ayrıca ağın en yoğun olduğu zamanlarda ihtiyaç duyduğu sayıda TCP bağlantısı kurmak için işletim sistemine ek yük getirir. Sistemin performansı büyük ölçüde düşebilir. Bu, kanalın kullanışlı olduğu yerdir, bir TCP bağlantısı içinde sanal bağlantılar oluşturur. Hemen işletim sisteminin ek yükünü azaltır, ayrıca eşzamansız işlemleri daha hızlı, güvenilir ve eşzamanlı olarak gerçekleştirmemizi sağlar. resim açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.