قسمت چهارم میکروسرویس‌ها: تکنولوژی‌های ارتباطی

در اولین قسمت از این مجموعه در مورد معماری میکرسرویس‌ها و مقایسه آن‌ها با معماری Monolithic و مزایا و معایب آن صحبت کردیم. در ادامه و در قسمت دوم از این مجموعه به بررسی API Gatewayها پرداختیم و دیدیم چگونه به کمک یک واسط خوب می‌توانیم مشکلات بسیاری را در راه توسعه نرم افزار حذف کنیم. اما در قسمت سوم نوبت به بررسی انواع روش‌‌های ارتباط بین میکروسرویس‌ها رسید و بعد از آشنایی با این زیرساخت‌ها در چهارمین قسمت به سراغ پروتکل‌ها و تکنولوژی‌های ارتباطی می‌رویم.مقدمه:وقتی در مورد ارتباط صحبت می‌کنیم دو گروه از عناصر اصلی قابل شناسایی هستند. شرکت کنندگان در یک رابطه و پیام‌های ارتباطی دو عنصر اصلی هر ارتباطی هستند که در این بخش قصد داریم در مورد این دو مورد صحبت کنیم.در یک ارتباط IPC تکنولوژی‌های مختلفی قابل انتخاب است. برای مثال برای یک ارتباط از نوع Request/Response و به روش Sync می‌توان Rest APIهایی بر اساس پروتکل HTTP توسعه داد یا برای توسعه سرویس‌های خود از Thrift استفاده کنید. در مقابل اگر نیاز به برقراری ارتباط Async داشته باشیم می‌توانیم به سراغ AMQP یا STOMP برویم. برای فرمت‌ پیام‌های ارسالی و دریافتی نیز گزینه‌های زیادی وجود دارد. یکی از معمول‌ترین انتخاب‌ها قالب‌های محبوب JSON و XML است که قابلیت خوانایی بالایی نیز دارد. اگر خوانایی برای انسان اهمیت نداشته باشد یا نیاز به بهره‌وری بالایی داشته باشیم Avro یا Protocol Buffer انتخاب‌های مناسبی به نظر می‌رسند.ارسال پیام به صورت Async:هنگامی‌که از روال‌های Messaging استفاده می‌کنیم یک ارتباط Async برقرار خواهیم کرد. کلاینت یک پیام را برای سرویس‌دهنده ارسال می‌کند. در صورتی که نیاز باشد برای پیام دریافت شده پاسخی ارسال شود، این پاسخ در قالب پیامی جداگانه از طرف سرویس دهنده برای سرویس‌گیرنده ارسال می‌گردد. از آنجایی که این یک ارتباط Async است لزومی به منتظر ماندن کلاینت برای دریافت پاسخ وجود ندارد، در عوض هنگام توسعه کلاینت به گونه‌ای توسعه داده می‌شود که عدم دریافت پاسخ فوری از طرف سرویس‌دهنده اختلالی در عملکرد کلی کلاینت ایجاد نکند. هر message در این روش ارسال پیام شامل یک Header است که متادیتاهای مرتبط با پیام را نگهداری می‌کند و هدف اصلی در بدنه پیام جایگذاری می‌شود. در این روش پیام‌ها از طریق Chanelها منتقل می‌شوند. ارسال‌کننده‌های مختلف این امکان را دارند که پیام‌های خود را از طریق یک کانال ارتباطی خاص جابجا کنند. در مقابل دریافت کننده‌های متفاوتی‌ نیز این امکان را دارند که پیام‌های یک کانال را دریافت کنند. به طور کلی دو نوع کانال ارتباطی Point-to-Point و Publish-Subscribe قابل تصور است.ارتباط Point-to-Point: نوعی ارتباط یک به یک است که ارسال کننده پیام، هدف خاصی برای ارسال پیام دارد و پیام به یک دریافت کننده خاص می‌رسد.ارتباط Publish-Subscribe: در این روش کانال ارتباطی پیام را از ارسال کننده دریافت می‌کند و این احتمال وجود دارد که به صفر تا بی‌نهایت دریافت کننده پیام را برساند. یکی از راه‌های ارتباطی One-To-Many استفاده از این روش است. در تصویر زیر استفاده از کانال ارتباطی Publish-Subscribe را مشاهده می‌نمایید.ارتباط Publish/Subscribeهنگامی که یک سفر جدید ایجاد می‌شود، سرویس Trip Management یک پیام ایجاد شدن سفر را ارسال می‌کند و هر سرویسی که علاقه‌مند به اطلاع از این واقعه در سیستم باشد، می‌تواند در کانال ارتباطی ثبت‌نام کند. برای مثال در سیستم بالا سرویس‌های Dispatcher در مورد ایجاد یک سفر جدید حساسیت دارد و بعد از وقوع این واقعه در سیستم عملیات خاصی را شروع می‌کند.سیستم‌های مختلفی برای انتخاب به عنوان زیرساخت ارسال و دریافت پیام وجود دارد که بهتر است سیستمی را انتخاب کنید که از زبان‌های برنامه‌نویسی مختلف پشتبانی کند.برخی از سیستم‌های موجود پروتکل‌های استانداردی را برای انتقال پیام انتخاب و استفاده کرده اند و در مقابل سیستم‌هایی هم وجود دارند که روش‌های ابداعی و اختصاصی خود را برای انتقال پیام پیاده سازی کرده اند.تعداد زیادی سیستم Open Source برای انتخاب وجود دارد مثل RabbitMQ, Apache Kafka, Apache ActiveMQ و NSQ. هرچند تفاوت‌های قابل تشخیص و بررسی بین این سیستم‌‌ها وجود دارد اما تمامی این سیستم‌ها از ساختار‌هایی برای ارسال پیام و ایجاد و مدیریت کانال پشتیبانی می‌کنند و تلاش می‌کنند ویژگی‌هایی مثل قابلیت اطمینان، بهره‌وری بالا و توزیع شدگی را داشته باشند.مزایای بسیاری را می‌توان برای استفاده از سیستم‌های Messaging برشمرد که در ادامه برخی از این مزایا را با هم بررسی می‌کنیم.جداسازی کامل کلاینت از سرویس: در این روش کلاینت پیامی را با فرمت خاص برای یک کانال ارتباطی ارسال می‌کند. در این روش کلاینت کاملا از روش ارسال پیام و سرویسی که پیام را دریافت می‌کند بی اطلاع است. نکته قابل توجه در این روش ارتباطی عدم نیاز کلاینت به دانستن موقعیت سرویس است و نیازی به روال‌های Discovery ندارد.عدم نیاز به صحت همزمان سرویس و کلاینت: هنگامی که از روشی مبتنی بر درخواست و پاسخ استفاده می‌کنید مثل HTTP در لحظه برقرای ارتباط کلاینت و سرور هردو باید همزمان اجرا باشند و به درستی خدمات خود را ارائه دهند. اما در این روش این احتمال وجود دارد هنگام ارسال پیام از طرف کلاینت، سرویس قابل دسترسی نباشد و پیام در سیستم باقی‌می‌ماند تا زمانی که سرویس خدمات رسانی خود را شروع کند و پیام به سرویس تحویل داده می‌شود.مشهود بودن ویژگی‌های IPC: هنگامی که از IPC استفاده می‌کنیم، در حال استفاده از سرویسی خارج از برنامه جاری هستیم. برخی از روش‌های برقراری ارتباط به گونه ای طراحی شده اند که این حس جدا بودن به برنامه نویس منتقل نشده و بابت همین موضوع هم مواردی مانند احتمال خرابی شبکه یا ... از چشم برنامه نویس پنهان می‌ماند. اما ماهیت برقراری ارتباط به روش Messaging کاملا این جدا بدون را نمایان می‌سازد.با تمام مزایایی که می‌توان برای این روش ارتباطی قائل شد معایبی نیز وجود دارد که هنگام انتخاب روش برقراری ارتباط باید به آن دقت کرد.پیچیدگی‌‌های عملیاتی و زیرساختی: هر‌چند این روزها با پیشرفت‌هایی که سیستم‌های نرم افزاری داشته اند کار نصب و راه اندازی آن‌ها به شدت ساده شده است و با وجود ابزارهایی مثل داکر این پیچیدگی به صفر میل می‌کند، اما کماکان برای استفاده از این روش نیاز به افزودن جز جدیدی به سیستم داریم که جدای از مسائل نصب و راه اندازی نیاز به نگهداری و مانیتورینگ دارد.پیچیدگی‌های پیاده سازی: هنگامی که از این روش ارتباطی استفاده می‌کنیم در صورتی که نیاز داشته باشیم به ازای یک درخواست پاسخی نیز دریافت کنیم باید کانالی برای دریافت پاسخ تخصیص دهیم و شناسه‌ای باید به درخواست تخصیص دهیم تا هنگام دریافت پاسخ بتوانیم پاسخ دریافتی را به یک درخواست متصل کنیم. حال که با عملکرد کلی سیستم‌های Messaging آشنا شدیم به سراغ یکی دیگر از روش‌‌های ارتباطی یعنی Request/Response می‌رویم.ارتباط Sync و Request/Response:هنگام استفاده از ارتباط متقارن و روش Request/Response کلاینت درخواستی را برای سرویس ارسال نمونده و منتظر پاسخ می‌ماند، سرویس دهنده نیز با دریافت یک درخواست شروع به پردازش آن نموده و نتیجه نهایی را به درخواست کننده باز می‌گرداند. تفاوت اصلی بین این روش و روش قبلی در این است که کلاینت فرض می‌کند که سرویس در بازه زمانی معقولی پاسخی به وی خواهد داد.پروتکل‌های زیادی برای پیاده سازی این روش ارتباطی وجود دارند که دوتا از مشهور ترین این پروتکل‌ها Rest و Thrift است.سرویس‌های REST:یکی از متداول ترین روش‌‌های پیاده سازی IPC که این روز‌ها بسیار مورد توجه توسعه دهندگان قرارداد REST است که با توجه به تعریف‌های داخلی آن معمولا از پروتکل HTTP استفاده می‌کند.سرویس‌های REST اساسا بر مبنای Resourceها طراحی و پیاده سازی می‌شوند که هر Resource یک شی خاص در کسب و کار است، مثل مشتری، محصولات و ... این روش‌ ارتباطی از ترکیب Verbها و آدرس برای دست‌یابی صحیح به یک Resource استفاده می‌کند. برای مثال دسترسی به آدرس nikamooz.com/api/courseبا توجه به نوع درخواست که می‌تواند GET یا POST باشد قابلیت دریافت یک مجموعه اموزشی یا به روزرسانی آن را انجام می‌دهد. در این روش ارتباطی این امکان وجود دارد که استفاده کننده با توجه به شرایط، درخواست دریافت نتیجه بافرمتی خاص مثل XML یا JSON را داشته باشد.ارتباطات REST در سیستم‌هابسیاری از برنامه نویسان ادعا می‌کنند که APIهایی که بر مبنای پروتکل HTTP توسعه داده اند REST Full است، کما اینکه با مطالعه مقاله REST APIs must be hypertext-driven به وضوح قابل مشاهده است که صرفا ادعای REST Full بودن نتیجه دلخواه را نمی‌دهد و باید اصولی نیز رعایت شود. در صورتی که تمایل دارید بدانید چگونه می‌توانید APIهایی بالغ داشته باشید پیشنهاد می‌کنم در مورد مدل بلوغ ریچاردسون بررسی کنید که توضیحات خوب و کاملی را در مطلب آقای مارتین فاولر می‌توانید مطالعه کنید.مثل هر روش و ابزار دیگری استفاده از HTTP به عنوان بستر ارتباطی مزایا و معایبی دارد که در ادامه به بررسی مزایا و معایب این روش می‌پردازیم.مزایای HTTP:بسیار ساده و آشناسادگی در تست و عملیاتی سازی و وجود ابزارهای بسیار زیاد برای تست مثل PostManبه صورت توکار از روش Request/Response پشتیبانی می‌کند.همخوانی بسیار مناسب با بسترهای سخت افزاری و امنیتی مثل فایروال‌هاعدم نیاز به واسط ارتباطیمعایب HTTP:به صورت توکار فقط از Request/Response پشتیبانی می‌کند حتی اگر Response نیاز نداشته باشیم به عنوان جزئی لا‌ینفک از پروتکل پاسخی نیز ارسال می‌شود.با توجه به ماهیت ارتباط مستقیم کلاینت و سرویس، هر دو باید همزمان قابلیت ارسال و دریافت پیام را داشته باشند و در صورت عدم دسترسی به یکی از این دوسر ارتباط درچار اختلال خواهیم شد.کلاینت‌ها نیاز دارند تا آدرس دقیق سرویس‌ها را بدانند.ساختار پیام‌ها:بعد از بررسی راهکار‌های ارتباطی نوبت به بررسی خود پیام‌ها می‌رسد. در بین روش‌های مختلف ارتباطی REST و Messaging این قابلیت را به برنامه‌نویس می‌دهند که از بین فرمت‌های مختلف مورد دلخواه خود را انتخاب کنند اما برخی روش‌ها مثل Thrift این قابلیت را ندارند. پس در مواردی که نیاز به فرمت‌های مختلف داری قاعدتا استفاده از روش‌هایی مثل REST بسیار خوب و پذیرفته است. یکی از ساختار‌های کلی ارسال پیام استفاده از ساختار متنی است. فرمت‌هایی مثل JSON و XML در توسعه نرم افزار بسیار کاربرد دارند. نکته منفی استفاده از این دو روش‌، خوانایی بالای پیام‌های جابجا شده به این روش است. جدای از قابلیت خوانایی بالا، بهروه وری پایینی نیز برای استفاده از این روش وجود دارد. در طرف مقابل می‌توانید از فرمت‌هایی که به صورت باینری کار تبادل داده‌ها را انجام می‌دهند استفاده نمایید.جمع بندی:در ادامه قسمت 3 که در مورد ارتباط سرویس‌ها بود، در این قسمت سعی کردیم کمی در مورد تکنولوژی‌های موجود برای پیاده این ارتباطات صحبت کنیم.ادامه مطلب: http://vrgl.ir/uqq7k http://vrgl.ir/sWRjx http://vrgl.ir/8cRfJ