معرفی RabbitMQ: بخش دوم، آشنایی با Exchange ها، Routing Key ها و Binding ها

فهرست بخش های این آموزش:

در این بخش یاد میگیریم که Exchange و Binding و Routing Key چیست؟ اینکه Exchange ها و Queue ها چطور با هم ارتباط برقرار می کنند؟ تفاوت انواع Exchange ها و سناریو های استفاده از آن ها را در RabbitMQ یادمیگیریم

همانطور که در بخش قبلی ذکر شد، پیام ها مستقیما به سمت Queue ها منتشر نمی شوند. به جای آن، Producer پیام ها را برای Exchange ارسال می کند. Exchange ها در VHost موجود در RabbitMQ قرار دارند و مامور مسیریابی(Route) پیام هستند. Exchange ها پیام ها را از طرف اپلیکیشن های Producer دریافت می کنند و آن ها را با کمک Header Attribute ها و Binding ها و Routing Key ها به سمت Queue های مناسب هدایت می کند.

هر Binding یک اتصال کانفیگ شده برای برقراری ارتباط بین Queue و Exchange است. Routing Key یک Attribute در Message است. Exchange ممکن است زمانی که درحال تصمیم گیری درباره این باشد که چطور یک پیام را به سمت Queue مناسب هدایت کند بسته به Exchange Type نگاه متفاوتی نسبت به Routing key پیام و Binding key مشخص شده در Binding بین Queue و Exchange داشته باشد.

میتوان موقع ساخت Exchange ها، Connection ها و Queue ها کانفیگ هایی را بر روی آنها انجام داد؛ مثل، Durable یا Temprory یا Auto Delete. به طور خلاصه Durable Exchange ها پس ریستارت شدن سرور زنده می مانند تا زمانی که حذف شوند. Temporary Exchange ها تا قبل از خاموش شدن سرور وجود دارند. Auto-deleted exchange ها زمانی که هیچ Binding به آنها وجود نداشته باشد از بین می روند.

در RabbitMQ، چهار نوع مختلف از Exchange ها پیام ها را به روش های مختلف و با استفاده از پارامتر ها و Binding های مختلف هدایت میکنند. Client ها می توانند Exchange های منحصر به فرد خود را بسازند یا از Exchange های پیش فرض از پیش تعریف شده استفاده کنند.

معرفی Direct Exchange:

یک Direct Exchange پیام ها را براساس Routing key به Queue ها تحویل میدهد. Routing key یک Message Attribute است که توسط Producer به Message اضافه می شود. اینطور درنظر بگیرید که Routing key یک "آدرس" است که Exchange از آن استفاده میکند تا تصمیم بگیرد که چطور پیام را هدایت کند. یک پیام به سمت صف هایی میرود که Binding key آن ها دقیقا برابر با Routing Key پیام باشد. نوع Direct Exchange برای تمیز دادن پیام های منتشر شده به سمت Exchange مشابه با یک شناسه ساده مورد استفاده است

در عکس زیر(شکل 1) Queue با نام create_pdf_queue به یک Direct Exchenge به نام pdf_events با Binding key مشخص pdf_create مقید(Bind) شده است. هنگامی که یک Message جدید که مقدار Routing key آن برابر با pdf_create باشد به Direct Exchange می رسد، Exchange آن را به سمت Queue که binding_key=routing_key باشد هدایت می کند، در تصویر زیر به سمت صف A یعنی create_pdf_queue هدایت می شود

شکل 1 - یک پیام به سمت هر Queue هدایت می شود که Binding key آن دقیقا برابر با Routing key باشد.
شکل 1 - یک پیام به سمت هر Queue هدایت می شود که Binding key آن دقیقا برابر با Routing key باشد.

سناریو اول:

  • نام Exchange مورد استفاده: pdf_events
  • نام Queue مورد استفاده: create_pdf_queue
  • مقدار Binding key بین Exchange و Queue مورد استفاده: pdf_create

سناریو دوم:

  • نام Exchange مورد استفاده: pdf_events
  • نام Queue مورد استفاده: pdf_log_queue
  • مقدار Binding key بین Exchange و Queue مورد استفاده: pdf_log

یک پیام با Routing key مقدار pdf_log به سمت Exchange به نام pdf_events ارسال شده است(شکل 1). پیام به سمت create_log_queue هدایت می شود چون مقدار Routing key مطابق Binding key آن است.

نکته: اگر Routing key پیام با هیچ Binding key مطابقت نداشته باشد، پیام دور انداخته خواهد شد.

به طور پیش فرض AMQP broker ها برای Direct Exchange از "amq.direct" استفاده میکنند.

معرفی Exchange پیش فرض

این Exchange یک Direct Exchange از پیش تعریف شده است که هیچ نامی ندارد. زمانی که از Exchange پیش فرض استفاده می شود، پیام به سمت Queue با نامی برابر با Routing key پیام هدایت می شود. همه Queue ها به طور خودکار به Exchange پیش فرض با Binding key برابر با نام صف، Bind شده اند

معرفی Topic Exchange

این Exchange مقدار Binding key را به دید یک Pattern نگاه می کند و پیام های دریافتی را براساس انطباق Routing key و Binding key هدایت میکند. پیام ها می توانند به سمت هر Queue که به این Exchange type مقید شده باشند و Binding key آن ها منطبق با Routing key پیام باشد هدایت شوند.

مقدار Routing key باید لیستی از کلمات باشد که توسط نقطه (.) از هم جدا شده باشند. مثل agreements.us یا agreements.eu.stockholm. مقدار Routing key ها می تواند شامل ستاره (*) باشد که هر ستاره با فقط یک کلمه منطبق میشود(*.*.b.*). علامت هشتگ نشان دهنده هیچ یا چند کلمه است.

شکل 2 - پیام ها براساس انطباق بین Routing key و Binding key به سمت یک یا چند Queue هدایت میشوند.
شکل 2 - پیام ها براساس انطباق بین Routing key و Binding key به سمت یک یا چند Queue هدایت میشوند.


به طور پیش فرض AMQP broker ها برای Topic Exchange از "amq.topic" استفاده میکنند.

با درنظر گرفتن شکل 2، به مثال های زیر توجه کنید:

سناریو اول:

Routing key: agreements.eu.berlin.x

Reciever Queues: berlin_agreements, all_agreements

سناریو دوم:

Routing key: agreements.eu.x.y

Reciever Queues: all_agreements

سناریو سوم:

Routing key: agreements.x.y.store

Reciever Queues: store_agreements, all_agreements

سناریو چهارم:

Routing key: agreements.x.y.z

Reciever Queues: all_agreements

معرفی Fanout Exchange:

یک Fanout Exchange یک کپی از پیام دریافت شده را بدون درنظر گرفتن Routing Key برای همه Queue های Bind شده به این Exchange ارسال میکند.

این Exchange زمانی مورد استفاده است که می خواهیم Message های مشابه را به یک یا چند Queue با Consumer هایی که هر کدام پیام های مشابه را به روش های مختلف پردازش می کنند ارسال کنیم.

به طور پیش فرض AMQP broker ها برای Fanout Exchange از "amq.fanout" استفاده میکنند.

شکل 3 - دریافت پیام و Route کردن آن به سمت همه Queue هایی که به Exchange مشخص Bind شده باشند
شکل 3 - دریافت پیام و Route کردن آن به سمت همه Queue هایی که به Exchange مشخص Bind شده باشند

معرفی Header Exchange:

یک Header Exchange براساس آرگومان های Header هر Request و مقادیر اختیاری، پیام ها را Route میکند. مشابه Topic Exchenge ها، Header Exchenge موقع تصمیم گیری برای Route کردن پیام ها به جای درنظر گرفتن Routing key، مقادیر Header را درنظر میگیرد. برای انطباق بررسی میکند که مقادیر Header با مقادیر مشخص شده در Binding برابر باشند.

آرگومان "x-match" را می توان فقط یکبار در Binding بین Exchange و Queue استفاده کرد. به وسیله این آرگومان مشخص میکنیم که آیا باید همه آرگومان های Header منطبق باشند یا فقط یکی کافی است. آرگومان "x-match" دو مقدار مختلف را می پذیرد: "any" یا "all"، که "all" مقدار پیش فرض است. مقدار "all" به این معنی است که همه Header شامل جفت Key و Value ها باید منطبق باشند و مقدار "any" به این معنی است که حداقل یکی از آرگومان های Header باید منطبق بشه.

به طور پیش فرض AMQP broker ها برای Header Exchange از "amq.header" استفاده میکنند.

شکل 4 - Header Exchange پیام ها را براساس آرگومان های Header به Queue هایی که به آن Bind شده باشند ارسال می کند.
شکل 4 - Header Exchange پیام ها را براساس آرگومان های Header به Queue هایی که به آن Bind شده باشند ارسال می کند.

معرفی Dead Letter Exchange:

نرم افزار RabbitMQ یک AMQP Extension به نام Dead Letter Exchange را فراهم آورده. این Exchange پیام های مرده را دریافت می کند و به سمت Queue مناسب ارسال می کند. زمانی یک پیام می میرد که عمر آن به پیان رسیده باشد(درصورت تنظیم کردن x-message-ttl برای Queue) یا Queue پر شده باشد(درصورت تنظیم کردن x-max-length برای Queue) یا Consumer پس از دریافت پیام در پاسخ "nacked" را برای سرور ارسال کند.

یک Dead Letter Exchange وابسته به Exchange type خاصی نیست و به طور دستی باید کانفیگ شود.

برای پیاده سازی Dead Letter Exchange راه آسانی در پیش داریم برای این کار در زمان ساخت Queue دو آرگومان به آن اضافه می کنیم، x-dead-letter-exchange برای مشخص کردن اینکه پس از مرگ پیام، به سمت کدام Exchange فرستاده شود و x-dead-letter-routing-key برای مشخص کردن Routing key پیام پس از مرگ.


در بخش های بعدی مباحث پیشرفته تری را از RabbitMQ یاد میگیریم.

این مطالب در کانال تلگرام قرار گرفت. می توانید از تلگرام هم من را دنبال کنید.

https://t.me/Dev_EhsanHosseini