محمد اژدری
محمد اژدری
خواندن ۵ دقیقه·۴ سال پیش

ارتباط بین میکروسرویس‌ها

قسمت دوم

اگر قسمت اول را خوانده‌ باشید، درمورد تعریف و معرفی معماری میکروسرویس‌ها حرف‌ زده‌ام.

در این قسمت به نحوه ارتباط بین میکروسرویس‌ها می‌پردازیم.

این موضوع که سرویس‌هایی که در یک سیستم کار می‌کنند باید باهم در ارتباط باشند، امری بدیهی است. اما به طور کلی این ارتباط انواع و الگوهای خودش را دارد و لزوما هیچ‌کدام بر دیگری برتری نداشته و هر کدام بدی‌ها و خوبی‌های خود را دارند. نهایتا با تشخیص معمار نرم‌افزار که برحسب نیاز سیستم است، انتخاب و پیاده سازی می‌شوند.

به طور کلی ارتباط بین میکروسرویس‌ها از دو جنبه مختلف تقسیم‌بندی می‌شوند:

تقسیم‌بندی اول:

  • ارتباط‌های همگام (Synchronous)

در حالت همگام، نحوه ارتباط به صورت request/response می‌باشد. سرویس‌ها براساس پروتکل‌هایی که توسعه داده شده‌اند، با هم ارتباط میگیرند. مثلا REST, Grpc, Graphql, ...

بدین صورت که یک سرویس در نقش کلاینت و سرویس دیگر در نقش سرور عمل می‌کنند. نکته مهم در این حالت این است که کلاینت منتظر جواب درخواستی که به سرور زده است می‌ماند و دیتایی که در جواب است، برایش مهم است. بنابراین در هنگام درخواست بلاک می‌شود.

  • ارتباط‌های ناهمگام (Asynchronous)

در این حالت نحوه ارتباط دو گونه است:

  • به صورت request/response: که در این صورت کلاینت بازهم به همان روش‌های گفته شده در حالت قبل درخواست خود را به سرور ارسال می‌کند، ولیکن منتظر پاسخ نمی‌ماند و ادامه روندش را دارد. مثال‌های ضمنی این حالت اجرای یک دستور یا نوتیفیکیش در سرویس مقصد است که موفقیت یا عدم آن برای کلاینت اهمیتی ندارد.
  • به صورت Publish/subscribe: در این حالت یک Message Broker بین کلاینت و سرور قرار می‌گیرد و کلاینت پیام‌ها یا ایونت‌های خود را در آن publish کرده و سرور که روی آن subscribe کرده است، آن‌ها را خوانده و پردازش موردنظر خود را روی‌شان انجام می‌دهد. در این حالت نیز کلاینت بلاک نشده و پیام خود را انتشار داده و به کار خود ادامه می‌دهد.

تقسیم‌بندی دوم:

  • ارتباط‌های یک به یک (one-to-one)

در این حالت یک سرویس با یک سرویس ارتباط می‌گیرد و می‌تواند هم همگام و به صورت request/response باشد و هم ناهمگام که باز هم یا request/response یا به صورت Publish/subscribe باشد.

ارتباط یک به یک در حالت ناهمگام
ارتباط یک به یک در حالت ناهمگام


  • ارتباط‌های یک به چند (one-to-many)

در این نوع از ارتباط، دیگر مرسوم نیست که از حالت همگام و request/response استفاده شود. چرا که یک سرویس می‌خواهد با چند سرویس همزمان ارتباط برقرار کند. در این حالت، روش Publish/subscribe مناسب می‌باشد. به این صورت که سرویس مبدا، پیام خود را در Message Broker انتشار می‌دهد و سرویس‌های مقصد، هر کدام برحسب نیازشان پیام‌ها را خوانده و استفاده می‌کنند. توجه داشته باشید که این ارتباط هم می‌تواند به با یک Message Broker و هم میتواند با چند Message Channel صورت بگیرد. که هر کدام مزایا و معایب خودشان را دارند.

دو نوع ارتباط یک به چند
دو نوع ارتباط یک به چند


حالا برخی (نه همه) مزایا و معایب انواع ارتباطات گفته شده به صورت نکته‌وار می‌پردازیم.

  • به صورت کلی برای دردسترس بودن (availability) بیشتر سیستم توصیه به استفاده از حالت ناهمگام در نحوه ارتباط‌ها توصیه ‌می‌شود. چرا که در حالت همگام اگر یک سرویس از دسترس خارج شود، عملا کار سرویس کلاینت که منتظر جواب درخواستش است مختل شده و از دسترس خارج می‌شود. ولی در حالت ناهمگام این اتفاق نیوفتد و یک سرویس در درسترس نباشد و سرویس دیگر کار خودش را انجام دهد.
  • یکی از معایب ارتباط یک به چند در حالتی که از Message Broker استفاده می‌شود، این است که ممکن است این MB به یک گلوگاه تبدیل بشود و از دسترس خارج شدن آن باعث مختل شدن کار همه سرویس‌هایی که به آن وابسته هستند بشود.
  • در حالتی که شما از Message Broker استفاده می‌کنید، پیام‌هایی که در آن انتشار داده می‌شوند، تا زمانی که خوانده نشوند. (این قوانین در MBهای مختلف متفاوت است.) حفظ می‌شود و عملا اگر سرویس استفاده کننده پیام‌ها از دسترس خارج شود و دوباره برگردد دیتایی را از دست نداده است. ولیکن اگر همین اتفاق برای حالت همگام اتفاق بیوفتد، یعنی درخواست از کلاینت ارسال شود و با ارور مواجه شود، یا سرور اصلا در درسترس نباشد، دیگر دیتا از بین رفته و قابلیت برگشت وجود ندارد. مگر اینکه در کلاینت نگه‌داری شود که اصلا توصیه به این کار نمی‌شود.
  • در حالت Messaging شما از انعطاف‌پذیری خوبی برخوردار هستید. چون پیام‌ها ساختارهای متنوعی می‌توانند داشته باشند و حتی یک پیام می‌تواند توسط چند سرویس خوانده شده و استفاده شود.
  • یکی از چالش‌های اصلی مطرح شده در حالت Messaging و ناهمگام وجود دارد، مدیریت خطاها و تراکنش‌هایی هست که اتفاق می‌افتد. مثلا رایت‌های دیتابیس و تغییراتی که ممکن است در یک سرویس اتفاق بیوفتد ولی در سرویس بعدی ادامه این کار انجام نشود و این سرویس متوجه آن نمی‌شود. برای این قضیه پترن‌هایی مانند Saga طراحی و مطرح شده است که انشالله در یک پست مجزا بررسی می‌شود.


امیدوارم برایتان کاملا مفید بوده باشد. و این نکته که این مقاله‌ها کاملا جنبه معرفی اجمالی دارند و اگر دوست دارید بیشتر عمیق شوید حتما کتاب‌هایی من جمله Microservices Patterns که نوشته‌های من هم اقتباس شخصی‌ام از این است را مطالعه نمایید.

معماری نرم‌افزارمیکروسرویس‌ها
مهندس پایداری سایت در یکتانت
شاید از این پست‌ها خوشتان بیاید