ارتباطات در معماری میکروسرویس

در یک برنامه یکپارچه که روی یک فرآیند اجرا می شود، اجزا با استفاده از روش سطح زبان یا فراخوانی تابع، یکدیگر را فراخوانی می کنند. اگر شما در حال ایجاد اشیاء با کد هستید (برای مثال، ClassName) ، می‌توان آنها را قویاً جفت کرد، یا اگر از تزریق وابستگی با ارجاع به انتزاعات به جای نمونه‌های شی مشخص استفاده می‌کنید، می‌توان آنها را به صورت جداشده فراخوانی کرد. در هر صورت، اشیاء در همان فرآیند در حال اجرا هستند. بزرگترین چالش هنگام تغییر از یک برنامه یکپارچه به یک برنامه کاربردی مبتنی بر ریزسرویس، تغییر مکانیسم ارتباطی است. تبدیل مستقیم از فراخوانی‌های روش درون‌فرایند به تماس‌های RPC به سرویس‌ها باعث ایجاد یک ارتباط پرحرف و ناکارآمد می‌شود که در محیط‌های توزیع‌شده به خوبی عمل نمی‌کند. چالش‌های طراحی سیستم توزیع‌شده به‌خوبی به‌خوبی شناخته شده‌اند که حتی قانونی به نام مغالطه‌های محاسبات توزیع‌شده وجود دارد که مفروضاتی را فهرست می‌کند که توسعه‌دهندگان معمولاً هنگام حرکت از طرح‌های یکپارچه به طرح‌های توزیع شده انجام می‌دهند.یک راه حل وجود ندارد، بلکه چندین راه حل وجود دارد. یک راه حل شامل جداسازی ریز سرویس های تجاری تا حد امکان است. سپس از ارتباط ناهمزمان بین میکروسرویس‌های داخلی استفاده می‌کنید و ارتباطات ریزدانه را که در ارتباطات درون فرآیندی بین اشیاء با ارتباطات درشت‌تر است، جایگزین می‌کنید. می‌توانید این کار را با گروه‌بندی تماس‌ها و با برگرداندن داده‌هایی که نتایج چند تماس داخلی را جمع‌آوری می‌کند، به مشتری انجام دهید.یک برنامه کاربردی مبتنی بر میکروسرویس یک سیستم توزیع شده است که بر روی چندین فرآیند یا سرویس اجرا می شود، معمولاً حتی در چندین سرور یا میزبان. هر نمونه سرویس معمولاً یک فرآیند است. بنابراین، خدمات باید با استفاده از یک پروتکل ارتباطی بین فرآیندی مانند HTTP، AMQP یا یک پروتکل باینری مانند TCP، بسته به ماهیت هر سرویس، تعامل داشته باشند.جامعه میکروسرویس فلسفه «نقاط پایانی هوشمند و لوله‌های گنگ» را ترویج می‌کند. این شعار طرحی را تشویق می‌کند که تا حد امکان بین میکروسرویس‌ها جدا شده و تا حد ممکن در یک میکروسرویس منسجم باشد. همانطور که قبلا توضیح داده شد، هر میکروسرویس دارای داده های خود و منطق دامنه خود است. اما ریزسرویس‌هایی که یک برنامه کاربردی سرتاسر را ایجاد می‌کنند، معمولاً به سادگی با استفاده از ارتباطات REST به جای پروتکل‌های پیچیده مانند WS-* و ارتباطات رویداد محور انعطاف‌پذیر به جای هماهنگ‌کننده‌های متمرکز فرآیندهای تجاری طراحی می‌شوند.دو پروتکل رایج مورد استفاده عبارتند از درخواست/پاسخ HTTP با APIهای منبع (بیشتر از همه، هنگام پرس و جو)، و پیام‌رسانی ناهمزمان سبک هنگام برقراری ارتباط به‌روزرسانی‌ها در چندین میکروسرویس. این موارد در بخش های بعدی با جزئیات بیشتر توضیح داده شده است.انواع ارتباطاتمشتری و خدمات می توانند از طریق انواع مختلفی از ارتباطات ارتباط برقرار کنند که هر کدام سناریو و اهداف متفاوتی را هدف قرار می دهند. در ابتدا می توان آن نوع ارتباطات را در دو محور طبقه بندی کرد.محور اول مشخص می کند که پروتکل همزمان یا ناهمزمان باشد:پروتکل سنکرون HTTP یک پروتکل همزمان است. مشتری یک درخواست ارسال می کند و منتظر پاسخ از طرف سرویس است. این مستقل از اجرای کد کلاینت است که می تواند همزمان (رشته مسدود شده است) یا ناهمزمان (رشته مسدود نشده است، و پاسخ در نهایت به یک تماس پاسخ می رسد). نکته مهم در اینجا این است که پروتکل (HTTP/HTTPS) همزمان است و کد کلاینت تنها زمانی می تواند کار خود را ادامه دهد که پاسخ سرور HTTP را دریافت کند.پروتکل ناهمزمان پروتکل های دیگری مانند AMQP (پروتکلی که توسط بسیاری از سیستم عامل ها و محیط های ابری پشتیبانی می شود) از پیام های ناهمزمان استفاده می کنند. کد مشتری یا فرستنده پیام معمولاً منتظر پاسخ نمی ماند. این فقط پیام را مانند هنگام ارسال پیام به صف RabbitMQ یا هر واسطه پیام دیگری ارسال می کند.محور دوم مشخص می کند که آیا ارتباط یک گیرنده یا چندین گیرنده دارد:گیرنده تک. هر درخواست باید دقیقاً توسط یک گیرنده یا سرویس پردازش شود. نمونه ای از این ارتباط الگوی Command است.گیرنده های متعدد هر درخواست را می توان از صفر تا چند گیرنده پردازش کرد. این نوع ارتباط باید ناهمزمان باشد. یک مثال مکانیسم انتشار/اشتراک مورد استفاده در الگوهایی مانند معماری رویداد محور است. این بر اساس یک رابط رویداد-باس یا کارگزار پیام هنگام انتشار به روز رسانی داده ها بین چندین میکروسرویس از طریق رویدادها است. معمولاً از طریق یک سرویس باس یا مصنوع مشابه مانند Azure Service Bus با استفاده از موضوعات و اشتراک ها پیاده سازی می شود.یک برنامه کاربردی مبتنی بر میکروسرویس اغلب از ترکیبی از این سبک های ارتباطی استفاده می کند. رایج ترین نوع ارتباط تک گیرنده با یک پروتکل همزمان مانند HTTP/HTTPS هنگام فراخوانی یک سرویس HTTP Web API معمولی است. میکروسرویس ها نیز معمولاً از پروتکل های پیام رسانی برای ارتباط ناهمزمان بین میکروسرویس ها استفاده می کنند.دانستن این محورها خوب است، بنابراین مکانیسم‌های ارتباطی احتمالی را شفاف می‌سازید، اما در هنگام ساخت میکروسرویس‌ها نگرانی مهمی نیستند. نه ماهیت ناهمزمان اجرای نخ کلاینت و نه ماهیت ناهمزمان پروتکل انتخاب شده نکات مهمی در هنگام ادغام میکروسرویس ها نیستند. آنچه مهم است این است که بتوانید میکروسرویس های خود را به صورت ناهمزمان ادغام کنید و در عین حال استقلال میکروسرویس ها را حفظ کنید، همانطور که در بخش زیر توضیح داده شد.ادغام میکروسرویس ناهمزمان استقلال میکروسرویس را تقویت می کندهمانطور که گفته شد، نکته مهم هنگام ساخت یک اپلیکیشن مبتنی بر میکروسرویس، نحوه ادغام میکروسرویس های خود است. در حالت ایده آل، باید سعی کنید ارتباط بین میکروسرویس های داخلی را به حداقل برسانید. هرچه ارتباطات بین میکروسرویس ها کمتر باشد، بهتر است. اما در بسیاری از موارد، باید به نحوی میکروسرویس ها را ادغام کنید. هنگامی که شما نیاز به انجام آن دارید، قانون اساسی در اینجا این است که ارتباط بین میکروسرویس ها باید ناهمزمان باشد. این بدان معنا نیست که باید از پروتکل خاصی استفاده کنید (مثلاً پیام رسانی ناهمزمان در مقابل HTTP همزمان). فقط به این معنی است که ارتباط بین میکروسرویس ها باید فقط با انتشار داده ها به صورت ناهمزمان انجام شود، اما سعی کنید به عنوان بخشی از عملیات درخواست/پاسخ HTTP سرویس اولیه به سایر میکروسرویس های داخلی وابسته نباشید.در صورت امکان، هرگز به ارتباط همزمان (درخواست/پاسخ) بین چندین میکروسرویس وابسته نباشید، حتی برای پرس و جوها. هدف هر میکروسرویس مستقل بودن و در دسترس بودن برای مشتری مشتری است، حتی اگر سایر خدماتی که بخشی از برنامه انتها به انتها هستند از کار افتاده یا ناسالم باشند. اگر فکر می‌کنید برای اینکه بتوانید به یک برنامه مشتری پاسخ دهید، باید از یک میکروسرویس به میکروسرویس‌های دیگر (مانند انجام یک درخواست HTTP برای پرس و جوی داده) تماس برقرار کنید، معماری دارید که در مواردی انعطاف‌پذیر نیست. میکروسرویس ها شکست می خورندعلاوه بر این، داشتن وابستگی به HTTP بین میکروسرویس‌ها، مانند ایجاد چرخه‌های طولانی درخواست/پاسخ با زنجیره‌های درخواست HTTP، نه تنها باعث می‌شود میکروسرویس‌های شما مستقل نباشند، بلکه عملکرد آنها نیز به محض اینکه تحت تأثیر قرار می‌گیرد. یکی از خدمات در آن زنجیره عملکرد خوبی ندارد.هر چه بیشتر وابستگی های همزمان بین میکروسرویس ها، مانند درخواست های پرس و جو اضافه کنید، زمان پاسخ کلی برای برنامه های مشتری بدتر می شود.همانطور که در نمودار بالا نشان داده شده است، در ارتباطات همزمان یک "زنجیره ای" از درخواست ها بین ریزسرویس ها ایجاد می شود و در حین ارائه درخواست مشتری انجام می شود. این یک ضد الگو است. در میکروسرویس‌های ارتباط ناهمزمان از پیام‌های ناهمزمان یا نظرسنجی http برای برقراری ارتباط با سایر میکروسرویس‌ها استفاده می‌شود، اما درخواست مشتری بلافاصله ارائه می‌شود.اگر میکروسرویس شما نیاز به انجام یک اقدام اضافی در میکروسرویس دیگری دارد، در صورت امکان، آن عمل را به صورت همزمان و به عنوان بخشی از عملیات درخواست و پاسخ میکروسرویس اصلی انجام ندهید. در عوض، این کار را به صورت ناهمزمان انجام دهید (با استفاده از پیام‌های ناهمزمان یا رویدادهای یکپارچه‌سازی، صف‌ها و غیره). اما تا حد امکان، عمل را به صورت همزمان به عنوان بخشی از عملیات درخواست و پاسخ همزمان اصلی فراخوانی نکنید.و در نهایت (و این همان جایی است که بیشتر مشکلات هنگام ساخت میکروسرویس ها ایجاد می شود)، اگر میکروسرویس اولیه شما به داده هایی نیاز دارد که در اصل متعلق به سایر میکروسرویس ها است، به درخواست های همزمان برای آن داده ها تکیه نکنید. در عوض، آن داده ها (فقط ویژگی هایی که نیاز دارید) را با استفاده از سازگاری نهایی (معمولاً با استفاده از رویدادهای یکپارچه سازی، همانطور که در بخش های آینده توضیح داده شده است) در پایگاه داده سرویس اولیه تکرار یا منتشر کنید.همانطور که قبلاً در شناسایی مرزهای مدل دامنه برای هر بخش میکروسرویس ذکر شد، کپی کردن برخی از داده ها در چندین میکروسرویس طراحی نادرستی نیست - برعکس، هنگام انجام این کار می توانید داده ها را به زبان یا شرایط خاص آن دامنه اضافی ترجمه کنید. یا متن محدود. به عنوان مثال، در برنامه eShopOnContainers شما یک میکروسرویس به نام ID-api دارید که مسئول بیشتر داده های کاربر با موجودی به نام User است. با این حال، زمانی که نیاز به ذخیره داده‌های مربوط به کاربر در میکروسرویس سفارش دارید، آن‌ها را به‌عنوان موجودیت دیگری به نام خریدار ذخیره می‌کنید. موجودیت خریدار هویت یکسانی با موجودیت کاربر اصلی دارد، اما ممکن است فقط چند ویژگی مورد نیاز دامنه سفارش را داشته باشد و نه کل نمایه کاربر.شما ممکن است از هر پروتکلی برای برقراری ارتباط و انتشار داده ها به صورت ناهمزمان در میان میکروسرویس ها استفاده کنید تا در نهایت سازگاری داشته باشید. همانطور که گفته شد، می توانید از رویدادهای یکپارچه سازی با استفاده از یک گذرگاه رویداد یا واسطه پیام استفاده کنید یا حتی می توانید با نظرسنجی از سرویس های دیگر از HTTP استفاده کنید. مهم نیست. قانون مهم این است که وابستگی همزمان بین میکروسرویس های خود ایجاد نکنید.بخش‌های زیر چندین سبک ارتباطی را توضیح می‌دهند که می‌توانید در برنامه‌های مبتنی بر میکروسرویس استفاده کنید.سبک های ارتباطیبسته به نوع ارتباطی که می خواهید استفاده کنید، پروتکل ها و انتخاب های زیادی وجود دارد که می توانید برای ارتباط از آنها استفاده کنید. اگر از مکانیزم ارتباطی مبتنی بر درخواست/پاسخ همزمان استفاده می‌کنید، پروتکل‌هایی مانند رویکردهای HTTP و REST رایج‌ترین هستند، به‌ویژه اگر خدمات خود را خارج از میزبان Docker یا خوشه میکروسرویس منتشر می‌کنید. اگر به صورت داخلی بین سرویس‌ها ارتباط برقرار می‌کنید (در داخل میزبان Docker یا خوشه میکروسرویس‌ها)، ممکن است بخواهید از مکانیسم‌های ارتباطی با فرمت باینری (مانند WCF با استفاده از TCP و فرمت باینری) استفاده کنید. همچنین می توانید از مکانیسم های ارتباطی ناهمزمان و مبتنی بر پیام مانند AMQP استفاده کنید.همچنین چندین فرمت پیام مانند JSON یا XML یا حتی فرمت های باینری وجود دارد که می تواند کارآمدتر باشد. اگر فرمت باینری انتخابی شما استاندارد نیست، احتمالاً ایده خوبی نیست که خدمات خود را با استفاده از آن فرمت به صورت عمومی منتشر کنید. می توانید از یک فرمت غیر استاندارد برای ارتباط داخلی بین میکروسرویس های خود استفاده کنید. شما ممکن است این کار را هنگام برقراری ارتباط بین میکروسرویس ها در میزبان داکر یا خوشه میکروسرویس خود (به عنوان مثال، ارکستراتورهای Docker)، یا برای برنامه های کاربردی مشتری اختصاصی که با میکروسرویس ها صحبت می کنند، انجام دهید.ارتباط درخواست/پاسخ با HTTP و RESTهنگامی که یک مشتری از ارتباط درخواست/پاسخ استفاده می کند، درخواستی را به یک سرویس ارسال می کند، سپس سرویس درخواست را پردازش می کند و پاسخی را ارسال می کند. ارتباط درخواست/پاسخ مخصوصاً برای جست‌وجوی داده‌ها برای یک رابط کاربری هم‌زمان (یک رابط کاربری زنده) از برنامه‌های مشتری مناسب است. بنابراین، همانطور که در شکل 4-16 نشان داده شده است، در معماری میکروسرویس احتمالاً از این مکانیسم ارتباطی برای اکثر پرس و جوها استفاده خواهید کرد.هنگامی که مشتری از ارتباط درخواست/پاسخ استفاده می کند، فرض می کند که پاسخ در مدت زمان کوتاهی، معمولاً کمتر از یک ثانیه یا حداکثر چند ثانیه می رسد. برای پاسخ‌های با تأخیر، باید ارتباطات ناهمزمان را بر اساس الگوهای پیام‌رسانی و فناوری‌های پیام‌رسانی پیاده‌سازی کنید، که رویکرد متفاوتی است.یک سبک معماری محبوب برای ارتباط درخواست/پاسخ REST است. این رویکرد مبتنی بر پروتکل HTTP است که افعال HTTP مانند GET، POST و PUT را در بر می گیرد. REST رایج ترین کمون معماری استیک سبک معماری محبوب برای ارتباط درخواست/پاسخ REST است. این رویکرد مبتنی بر پروتکل HTTP است که افعال HTTP مانند GET، POST و PUT را در بر می گیرد. REST رایج ترین رویکرد ارتباطی معماری مورد استفاده در هنگام ایجاد خدمات است. هنگامی که خدمات ASP.NET Core Web API را توسعه می دهید، می توانید خدمات REST را پیاده سازی کنید.هنگام استفاده از خدمات HTTP REST به عنوان زبان تعریف رابط، ارزش بیشتری وجود دارد. به عنوان مثال، اگر از ابرداده Swagger برای توصیف API سرویس خود استفاده می‌کنید، می‌توانید از ابزارهایی استفاده کنید که خرد مشتری را تولید می‌کنند که می‌تواند مستقیماً خدمات شما را کشف و مصرف کند.