Message Queue

صف پیام یا Message Queuing یک ارتباط سرویس به سرویس غیرهمزمان است که در معماری‌های میکروسرویسی و بدون سرور استفاده می‌شود. به برنامه‌ها اجازه می‌دهد تا به جای اتصال مستقیم، با فرستادن پیام به یکدیگر به صورت غیرهمزمان، با هر سرعتی، در هر مکانی و مستقل از یکدیگر در ارتباط باشند. وقتی برنامه‌ی مقصد آفلاین باشد یا در حال حاضر مشغول باشد، Message Queue یک صف موقتی ذخیره‌ی پیام ایجاد می‌کند. Message Queue می‌تواند به شدت باعث برنامه‌نویسی ساده‌تر برنامه‌های decouple‌ شده در کنار افزایش کارآیی، اطمینان و مقیاس‌پذیری شود. می‌توان Message Queue بین برنامه‌ها را معادل ایمیل در بین انسان‌ها در نظر گرفت.صفصف لیستی از آیتم‌های داده، فرمان یا یک کار است که هر که زودتر وارد این لیست شود، زودتر هم خارج می‌شود. یک صف پیام شامل پیام‌هایی است که به یک برنامه ارسال شده‌اند. این پیام‌ها می‌توانند کارهایی باشند که در انتظار پردازش هستند.پیامپیام، داده‌ایست که بین برنامه‌های ارسال‌کننده و دریافت‌کننده منتقل می‌شود. یک آرایه‌ای از بایت‌هاست که چندین header هم دارد. این پیام معمولا کوچک است و می‌تواند در مورد یک کار که باید پردازش شود، کاری تمام شده، درخواست، پاسخ، پیام یک خطا و یا فقط یک پیام متنی باشد.معماری Message Queueمعماری Message Queue ساده است. یک برنامه‌ی کلاینت تحت عنوان تولیدکننده داریم که پیام‌ها را ایجاد می‌کند و به Message Queue تحویل می‌دهد. برنامه‌ی دیگری تحت عنوان مصرف‌کننده داریم که به صف وصل شده و پیام‌ها را برای پردازش کردنشان دریافت می‌کند. پیام‌ها تا زمانی‌که توسط یک مصرف‌کننده دریافت شوند ذخیره می‌شوند. چندین تولیدکننده و مصرف‌کننده می‌توانیم داشته باشیم ولی هر پیام یکبار و توسط یک مصرف‌کننده مصرف می‌شود. به همین دلیلی این الگوی پیام‌رسانی، ارتباط one-to-one یا point-to-point نامیده می‌شود. اگر لازم باشد یک پیام توسط بیش از یک مصرف‌کننده مصرف شود به آن پیام‌رسانی Pub/Sub می‌گویند. که در ادامه این دو نوع الگوی پیام‌رسانی را بیشتر شرح خواهیم داد.Message Queueدر فناوری، سیستمی که پیام‌ را در Message Queue قرار می‌دهد منتظر جواب آن نیست تا بتواند کار خود را ادامه دهد. در واقع Message Queuing یک پروتکل ارتباطی ناهمگام/غیرهمزمان ایجاد می‌کند. یک مثال خوب برای فهم بهتر ایمیل است. پس از ارسال ایمیل بلافاصله منتظر جواب آن نیستیم تا کار خود را ادامه دهیم. این باعث ایجاد جداسازی (decoupling) تولیدکننده از مصرف‌کننده می‌شود.می‌توان بیش از یک صف داشته باشیم. این صف‌ها توسط مدیر صف مدیریت می‌شوند. ماهیت فیزیکی یک صف به سیستم‌عاملی که مدیر صف توسط آن اجرا می‌شود بستگی دارد.جداسازی و مقیاس‌پذیریجداسازی یا decoupling یعنی دو سیستم از هم خبر نداشته و بهم وابسته نباشند. هر سیستمی بتواند بدون اتصال به سیستم دیگر به کار خود ادامه دهد. این سیستم، سیستم خوبی است و نگهداری از آن ساده‌تر است.اگر سیستمی نتواند پیام را دریافت کند پیام به صف اضافه می‌شود و تا زمانی‌که پیام را دریافت و مصرف کند دوباره ارسال می‌شود و زمانی‌که سیستم احیا شد می‌تواند آن را مصرف کند و پیام پس از پردازش حذف می‌شود. می‌توان پیام‌ها را طوری فرستاد که در زمان مشخصی توسط مصرف‌کننده مصرف شوند. پیام‌ها فقط توسط یک مصرف‌کننده می‌توانند مصرف شوند.به جای اینکه برنامه‌ی بزرگی توسعه دهید، بخش‌های مختلف برنامه را Message Queue بهم متصل کنید. در این‌صورت هر قسمت از برنامه جداگانه و به راحتی رشد می‌کند و می‌تواند به زبان‌های مختلف باشد و توسط تیم‌های متفاوتی نگهداری شوند. در معماری میکروسرویس عملکردهای مختلفی در سرویس‌های مختلف وجود دارد که عملکردهای متفاوتی را ارائه می‌دهند. این سرویس‌ها بهم وابسته هستند تا یک برنامه‌ی کامل را بسازند. بدین ترتیب سرویس‌ها بدون کمک هم نمی‌توانند کار کنند. به همین دلیل نیاز داریم تا سرویس‌ها بدون در انتظار هم بودن بهم متصل شوند. Message Queue این امکان را با فراهم ساختن یک صف پیام ایجاد می‌کند. برای این‌کار نیاز به یک message broker داریم (معادل پستچی!) که پیام‌ها را از فرستنده به مقصد درست منتقل می‌کند. با استفاده از این فناوری می‌توان روابط بین فرآیندها را هم کنترل کرد. فرآیندها یکدیگر را invoke نمی‌کنند و با قرار دادن پیام در صف باهم ارتباط برقرار می‌کنند. این روش کنترل پیام باعث نگهداری راحت از سیستم و مقیاس‌پذیری آن می‌شود.فناوری Message Queue‌ می‌تواند برای جداسازی پردازش‌های سنگین و بافر یا دسته‌ای کردن کارها استفاده شود.مثالفرض کنید که یک سیستم وب دارید که باید دسترس‌پذیری بالایی داشته باشد و به هر درخواست جدید پاسخ دهد. با داشتن یک صف سرویس پردازش و سرویس وب می‌توان این سیستم را به بهترین نحو پیاده‌سازی کرد. در این‌صورت این دو سرویس از هم خبر ندارند و سرویس وب پیام یا همان درخواست را در صف گذاشته و سرویس پردازش آن را برداشته و پردازش می‌کند. در این صورت اگر مقیاس کار گسترش پیدا کند کافیست گنجایش صف را افزایش دهیم.الگوهای پیام‌رسانی در Message Queueone-to-one / point-to-pointیک پیامدر صف قرار داده می‌شود و یک برنامه آن را دریافت کرده و مصرف می‌کند. برای این‌کار فرستنده باید تمام اطلاعات مقصد را داشته باشد.Publish/Subscribeیک کپی از پیام توسط برنامه‌ی منتشرکننده به همه‌ی برنامه‌های مرتبط ارسال می‌شود. در این صورت نیازی نیست که فرستنده اطلاعات مقصد را داشته باشد.مزایاارتباط بین برنامه‌ها بدون نیاز به کدهای اتصالبرنامه‌های دارای بخش‌های کوچک که با Message Queue بهم متصلندامکان باز استفاده از بخش‌های کوچک این برنامه‌هاامکان انتخاب ترتیب پردازش پیام‌هاایجاد تعادل بار روی یک سیستم با تنظیم کردن بیش از یک برنامه برای سرویس‌دهی به یک صف وقتی تعداد پیام‌ها بیشتر از مقدار ماکسیمم استافزایش در دسترس‌پذیری برنامه‌ها با تنظیم‌کردم سیستم جایگزین برای پاسخ‌دهی به پیام‌های صف به جای برنامه‌ی اصلی که در دسترس نیستعدم نیاز به پروتکل برای ارتباط برنامه‌ها/بخش‌های مختلفعدم نیاز به در حال اجرا بودن برنامه در هنگام ارسال پیام. به محض اجرا شدن برنامه مقصد می‌تواند پیام را دریافت کند و پیام تا آن زمان ذخیره می‌شودکاهش هزینه‌ها، زمان و مهارت لازم و افزایش سرعت توسعه به دلیل کوچکتر شدن برنامه‌هامعرفی ابزارها و فناوریهای متن‌بازRabbitMQیک message broker است. این فناوری متن‌باز Advanced Message Queuing Protocol (AMQP) را پیاده‌سازی می‌کند که فیچرهایی مانند صف‌بندی، مسیریابی، امنیت و غیره دارد. شامل تولیدکننده، مصرف‌کننده، صف و exchange (امکان مسیریابی برای فرستادن پیام‌ها به مقصد درست) است.RabbitMQApache KafkaApache Kafkaاین مطلب، بخشی از تمرینهای درس معماری نرم‌افزار در دانشگاه شهیدبهشتی است.مراجع[1] https://www.cloudamqp.com/blog/what-is-message-queuing.html[2] https://aws.amazon.com/message-queue/[3] https://medium.com/@mosesbasseyekwere/message-queue-what-it-is-how-it-works-and-when-to-use-it-2b7fb5dcef48[4] https://medium.com/must-know-computer-science/system-design-message-queues-245612428a22[5] https://www.ibm.com/docs/en/ibm-mq/8.0?topic=overview-introduction-message-queuing