در مطلب قبلی در مورد سه اصطلاح یک message broker صحبت کردیم و یک داستان ساده و سلیس و روان گفتم.
حالا توی این مقاله میخوایم در مورد exchange ها تو message broker با هم صحبت کنیم. در واقع میشه گفت که exchange کارش انتقال پیام به queue با استفاده از route key ها هستش و در اصل کاری که میکنه message هارو به queue ها bind میکنه.
توی rabbitmq یا بهتره بگم تو پروتکل AMQP 0.9.1 چهار نوع مختلف Exchange داریم که در زیر هر کدومش رو در حد دانش خودم توضیح میدم.
تو این نوع از exchange پیامها به صورت مستقیم به صف ارسال میشن یعنی یک مسیریابی مستقیم دارن که این مسیریابی با استفاده از route key انجام میشه. اینطور فرض کنید که اگر پیام با routeKey = X رو ارسال کنیم و یک صف داشته باشیم که پیامهای با routeKey = Y رو قبول میکنه، این exchange پیام رو ارسال نمیکنه چون routeKey پیام با routeKey مورد پذیرش تو صف متفاوت هستند.
و اما یک مثال :
در این مثال ما یک سری پیغام رو میخوایم از producer به consumer هامون ارسال کنیم که اسم exchangeای هم که داریم test_direct هست.
همونطور که روی عکس هم میبینید سه تا صف داریم که هر کدوم یک routeKey داره و اگر ما سه تا پیغام داشته باشیم میبینیم که هر پیغام فقط به صفی میره که اون routeKey رو داره. مثلا صفی که banana و apple رو به عنوان routeKey داره پیغامهای 2 و 3 که routeKey شون banana, apple هست رو قبول میکنن ( بهتره بگیم که exchange پیغامهارو bind میکنه).
نکته : exchange ها به طور پیشفرض از نوع Direct هستند مگه اینکه شما موقع تعریف بگید که میخواین نوع exchange تون چی باشه ولی اگر نوعش رو مشخص نکنید Direct میزنه براتون.
۲. دومیش : Fanout exchange
این exchange نگاه نمیکنه که اون صف چه routeKey داره و فقط مهم اینه که صف به exchange وصل باشه یا بهتره بگم که bind شده باشه. همین بهونه براش کافیه که هر پیغامی که به رسید رو بخواد روی همه صفها بذاره.
خب بریم یک مثال هم برای این ببینیم :
خب تو عکس بالا میبینید که producer یک پیام رو میده به exchangeای از نوع fanout و بعد اون exchange پیام رو برمیداره و روی سه تا صف میذاره و اینجا کاری به routekey و ... نداره و پیام رو به همه صفهایی که باهاشون در ارتباط هست میده.
۳. سومیش : Topic exchange
این exchange یک طورایی (البته نظر شخصیهها :) ) محصول مشترک direct و fanout هستش. به این علت اینو میگم که یک پترن به عنوان routeKey میگیره و پیام رو به صفهایی که routeKey شون اون پترن رو قبول کنه میده.
این نوع exchange یعنی topic خیلی خوبه و شما میتونید یه طورایی فقط از همین مورد تو اکثر معماریتون استفاده کنید. خالی از لطف هم نیست که بدونید توی kafka فقط topic وجود داره و مدلهای دیگه نیست.
و اما خب تا توی عکس نشون ندم نمیشه خوب منظور رو رسوند.
( منبع سایت RabbitMQ ) : تو این مثال، ما پیامهایی رو ارسال میکنیم که همگی یک سری حیوانات رو توصیف میکنن. پیام ها با یک کلید مسیریابی که از سه کلمه (دو نقطه) تشکیل شده ارسال میشن. اولین کلمه در کلید مسیریابی نوع سرعت حیوان، دوم یک رنگ و سوم یک گونه رو توصیف میکنه، به این صورت : "<celerity>.<colour>.<species>".
ما سه اتصال ایجاد کردیم: صف Q1 با کلید "*.orange.*" و صف Q2 با "*.*.rabbit" و "lazy.#" بایند شده است.
این اتصالات (Bindings) را میتونیم اینطور خلاصه کنیم:
یک پیام که با کلید مسیریابی "quick.orange.rabbit" تنظیم شده است به هر دو صف تحویل داده میشه. پیام "lazy.orange.elephant" نیز به هر دوی آنها خواهد رفت. از طرف دیگه "quick.orange.fox" فقط به صف اول و "lazy.brown.fox" فقط به صف دوم خواهد رفت. "lazy.pink.rabbit" تنها یک بار به صف دوم تحویل داده می شود، حتی اگر با دو حالت اتصال (binding) مطابقت داشته باشد. "quick.brown.fox" با هیچ نوع binding مطابقت ندارد، بنابراین دور انداخته میشه.
۳. چهارمیش : Headers exchange
و اما آخرین نوع exchange، در این نوع ما routeKey نداریم و پیامها رو با استفاده از header هایی که داریم مسیریابی میکنیم تا ببینیم به کدوم صف تحویل بدیم.
و اما عکس :
همونطور که در عکس بالا میبینید یک پیام با هدر {"key1", "value1"} ارسال شده و exchange اون رو به صف اول میده. شاید براتون سوال پیش بیاد که چرا پیام رو به صف اول داد ولی به صف آخر نداد، این به خاطر x-match هست. اگر x-match مقدار any داشته باشه header اگر با یک مقدار هم برابر بود پیام رو اون صف قرار میگیرده ولی اگر x-match مقدار all رو داشته باشه باید کل header پیام با صف یکی باشن تا پیام توی صف قرار بگیره.
میدونم خیلی خلاصه گفتم و کلی مطلب دیگه هست که میشه گفت ولی سعی کردم خلاصه باشه.
امیدوارم از خوندن این مطلب لذت برده باشید.
موفق باشید