معرفی معماری میکروسرویس (Microservices Architecture)
معماری میکروسرویس (Microservices Architecture) به مرور در حال کسب محبوبیت فزایندهای است و امروزه تقریباً در همه پروژههای نرمافزاری عمده از آن استفاده میشود. دلیل اصلی این مسئله ناشی از مزیتهای آن و مسائلی است که حل میکند. هدف ما در این مقاله ارائه مروری از معماری میکروسرویس به همراه مزیتها و معایب آن است.
ما همچنین به بررسی فرایند تکامل برنامهنویسی نرمافزار میپردازیم تا بتوانیم چگونگی بهبود معماری نرمافزار در طی زمان و دلیل این که معماری میکروسرویس به مرور به روش غالب در توسعه نرمافزارهای سازمانی تبدیل شده است را درک کنیم. در نهایت برنامههای نرمافزاری که میتوان برای ساخت معماری میکروسرویس استفاده کرد را معرفی خواهیم کرد.
میکروسرویس چیست؟
در ابتدا باید مفهوم خود میکروسرویس را درک کنیم. میکروسرویس، همان طور که از نام آن مشخص میشود، اساساً به سرویسهای نرمافزاری مستقلی گفته میشود که کارکردهای تجاری خاصی را در یک اپلیکیشن نرمافزاری ارائه میکنند. این سرویسها میتوانند به صورت مستقل از هم نگهداری، نظارت و توزیع شوند.
میکروسرویسها بر مبنای معماری مبتنی بر سرویس ساخته شدهاند.
معماری مبتنی بر سرویس یا «Services Oriented Architecture» به اختصار (SOA) به اپلیکیشنها امکان ارتباط با یکدیگر روی یک رایانه منفرد و یا در زمان توزیع اپلیکیشنها روی چندین رایانه در یک شبکه را ارائه میکند. هر میکروسرویس ارتباط اندکی با سرویسهای دیگر دارد. این سرویسها خودکفا هستند و یک کارکرد منفرد (یا گروهی از کارکردهای مشترک) را ارائه میکنند.
معماری میکروسرویسها به طور طبیعی در سازمانهای بزرگ و پیچیده استفاده میشود که در آنها چند تیم توسعه میتوانند مستقل از هم برای ارائه یک کارکرد تجاری کار بکنند و یا اپلیکیشنها ملزم به ارائه خدمات به یک حوزه تجاری باشند.
پیش از آن که بخواهیم به توضیح مسائلی که میکروسرویس برای حل آنها ابداع شده بپردازیم، قصد داریم تاریخچه تکامل نرمافزار را توضیح دهیم.
سابقه تکامل برنامهنویسی نرمافزار
اپلیکیشنهای نرمافزاری همواره باید نگهداری شده و بهبود یابند. همواره این نیاز برای پیادهسازی الزامات جدید و بهبود ویژگیهای موجود وجود خواهد داشت. به علاوه اپلیکیشنهای نرمافزاری به طور موردی نیازمند اجرای سریعتر هستند. برخی اوقات ویژگیهای موجود باید منسوخ شوند.
در نتیجه بهبود و نگهداری اپلیکیشنهای نرمافزاری یک جزء ضروری از چرخه عمر نرمافزار است. خلاصه همه بحثهای فوق این است که ما همواره به نگهداری و بهبود نرمافزار نیاز داریم. از این رو باید این فرایند را سادهتر کنیم.
تکامل رایانهها
ابتدا باید با فرایند تکامل رایانهها در طی زمان آشنا شویم. در تصویر زیر این تکامل سیستمهای رایانهای به صورت خلاصه ارائه شده است:
زمانی که رایانهها برای اولین بار در دهه 1940 میلادی ارائه شدند، نرمافزار به صورت پانچ شده درون سختافزارهای بزرگ و گرانقیمت مانند کارتهای پانچ و نوارهای پانچ جاسازی شده بود. دستورالعملها به زبان ماشین باینری نوشته شده بودند. متعاقباً اگر لازم میشد تغییری پیادهسازی شود، یک کارشناس زبان باینری ماشین باید دستورالعملهای جدید را در اختیار ماشین قرار میداد. این امر یک فرایند بسیار گرانقیمت بود.
سپس نسل دوم رایانهها در دهه 1950 میلادی به عنوان نسخه بهبود یافته نسل اول رایانهها معرفی شدند. این رایانهها به برنامههایی با زبان اسمبلی نیاز داشتند که در تراشههای سختافزاری کوچکتری نوشته میشد. فلسفه طراحی این رایانهها پیرامون این واقعیت شکل گرفته بود که یادگیری زبان نمادین اسمبلی بسیار راحتتر از آموختن کدهای باینری است. در نتیجه اسمبلرها معرفی شدند که کد ماشین را به زبان نمادین اسمبلی تبدیل میکردند.
در این مورد نیز هر زمان که تغییری مورد نیاز بود، فرد باید دستورالعملها را در سختافزار وارد میکرد. در نتیجه نرمافزار و سختافزار باید از همدیگر جدا میشدند.
و سپس نسل سوم رایانهها در دهه 1960 میلادی عرضه شدند. این رایانهها به کامپایلر و مفسر برای ترجمه زبان قابل فهم از سوی انسان به کد ماشین نیاز داشتند. این رایانهها کوچکتر بودند و میبایست نرمافزارهای قابل تعامل از سوی کاربر روی آنها نصب میشد. نسل سوم رایانهها میتوانستند چندین اپلیکیشن را همزمان اجرا کنند. زبانهای برنامهنویسی مختلفی معرفی شدند که روی این رایانهها نصب میشدند. سختافزار همچنان گرانقیمت بود؛ اما انعطافپذیری حاصل از جداسازی نرمافزار از سختافزار موجب ایجاد فرصتهای بیشماری برای بهبود کارکرد آنها شد.
در نهایت نسل چهارم رایانهها در دهه 1970 میلادی معرفی شدند. این رایانهها دستگاههای دستی بودند که میتوانستند در کف دست جای بگیرند. در این مورد نیز اپلیکیشنهای جدید معرفی شدند که میتوانستند روی دستگاهها بدون نیاز به خرید سختافزار جدید نصب شوند. سهولت نصب و قابلیت نگهداری موجب شد که بسیاری از شرکتها بتوانند ایدههای فناورانه جدیدی را ابداع کنند.
یک طرح مشترک وجود دارد. رایانهها به این دلیل تکامل یافتند که همواره نیاز به نگهداری و بهبود اپلیکیشنهای نصب شده روی رایانهها وجود داشته است.
تکامل نرمافزار
تکامل نرمافزار نیز چرخه مشابه را طی کرده است. تصور زیر فرایند تکامل نرمافزار را نشان میدهد:
- نسل اول (اواخر دهه 1970 میلادی): مفاهیم شیءگرایی مانند وراثت، کپسولهسازی، و چندریختی معرفی شدند تا قابلیت استفاده مجدد از کد و قابلیت نگهداری فراهم شوند.
- نسل دوم (دهه 1990 میلادی): اپلیکیشنها با استفاده از معماری لایهبندی شده طراحی و پیادهسازی شدند. معماری لایهبندی شده برای کاهش در هم تنیدگی زیاد بین اجزای مختلف اپلیکیشنهای نرمافزاری معرفی شد. در نتیجه تست نرمافزار و زمان برای تحویل نرمافزار کاهش یافت. اپلیکیشنها همچنان یکپارچه بودند، یعنی یک واحد منفرد که همه کارکردهای اپلیکیشن وجود داشت در آن کپسولهسازی شده بود.
- نسل سوم (دهه 2000 میلادی): در این زمان اپلیکیشنهای با توزیع مبتنی بر سرویس معرفی شدند. روش طراحی مورد استفاده در این نسل شامل تعریف سرویس ریموت بود که به اپلیکیشنها امکان مقیاسبندی و توزیع روی ماشینهای چندگانه را میداد.
پیش از معرفی میکروسرویسها، اغلب اپلیکیشنهای سازمانی یکپارچه بودند. در ادامه مشکلات این پارادایم را بررسی میکنیم.
معماری اپلیکیشنهای نرمافزاری در بازههای زمانی اخیر و مشکلات این معماریها
در سالهای اخیر اپلیکیشنهای نرمافزاری در معماریهای چندلایه پیادهسازی میشدند. به عنوان نمونه در تصویر زیر یک معماری معمول برای اپلیکیشن نرمافزاری سازمانی ارائه شده است:
هر لایه در کد نرمافزاری پیادهسازی میشد و از چندین کلاس و اینترفیس تشکیل یافته بود:
لایه داده
این لایه برای ذخیرهسازی دادهها در پایگاه داده و فایلها پیادهسازی شده است. تنها مسئولیت این لایه ارائه دادهها از منابع دادهای مختلف است.
لایه تجاری
مسئولیت لایه تجاری، بازیابی دادهها از لایه داده و اجرای محاسبات است. لایه تجاری نمیداند که دادهها در فایل یا پایگاه داده یا در موارد دیگر هستند. لایه تجاری به لایه دادهها وابسته است.
لایه سرویس
لایه سرویس روی لایه تجاری قرار میگیرد. این لایه یک پوشش برای لایه تجاری ایجاد میکند که شامل امنیت/گزارشگیری/وساطت برای فراخوانی کارکردها است. لایه سرویس به لایه تجاری وابسته است.
لایه میزبانی
سرویسها از طریق این لایه میزبانی میشوند. لایه میزبانی از فناوریهای مبتنی بر سرویس مانند WCF یا REST API برای میزبانی با استفاده از پروتکلهای مختلف مانند http ،https ،tcp ،named pipes و غیره بهره میگیرد. کل اپلیکیشن به صورت یک پردازش نرمافزاری برای نمونه سرویس ویندوز یا وبسرویس IIS اجرا میشود. اپلیکیشنها از طریق URL مانند https://example.com/myapplication در دسترس هستند.
لایه رابط کاربری
لایه اینترفیس یا رابط کاربری شامل کدهایی است که در لایه میزبانی مورد ارجاع قرار میگیرند و به منظور ایجاد امکان تعامل با اپلیکیشن برای کاربران طراحی شده است.
این طراحی به توسعهدهندگان امکان میدهد که روی یک کارکرد خاص متمرکز شوند، ویژگی را تست کنند، و یا اپلیکیشن را با استفاده از کنترل معکوس از طریق تزریق وابستگیها و میزبانی یک اپلیکیشن روی ماشینهای متعدد تجزیه کنند.
طراحی یکپارچه لایهبندی شده مزایای زیادی دارد؛ اما نواقصی نیز دارد. در ادامه فهرستی از مشکلات رایج این نوع معماری را مورد اشاره قرار دادهایم:
- این طراحی برای مقیاسبندی و نگهداری اپلیکیشن سرراست نیست. این طراحی زمان مورد نیاز برای قرار دادن کارکردهای جدید در اختیار کاربر را افزایش داده است، چون چرخه توسعه زمان بیشتری طول میکشد.
- از آنجا که کل اپلیکیشن به صورت یک پردازش منفرد میزبانی میشود، هر بار که لازم باشد یک بهروزرسانی اجرا شود، کل اپلیکیشن باید متوقف شود و سپس نسخه جدیدی از اپلیکیشن باید توزیع شود.
- برای ایجاد تعادل در بار کاری، کل اپلیکیشن نرمافزاری روی چند ماشین توزیع میشود. به علاوه، امکان توزیع کارکردهای خاص روی سرورهای چندگانه برای متوازنسازی بار وجود ندارد.
- طراحی اپلیکیشن پیچیده است، چون همه ویژگیها در یک اپلیکیشن یکپارچه منفرد پیادهسازی شدهاند.
- زمانی که تعداد اپلیکیشنها در سازمان افزایش مییابد، توزیع اپلیکیشنهای یکپارچه نیازمند اطلاعرسانی و هماهنگی با همه تیمهای توسعه ویژگیهای جدید است. این امر موجب افزایش زمان مورد نیاز برای تست و توزیع اپلیکیشن میشود.
- بدین ترتیب در طراحی یک «نقطه شکست منفرد» (Single Point of Failure) ایجاد میشود که یک خطای غیر قابل بازیابی منفرد نمیتواند پردازشی را که اپلیکیشن روی آن میزبانی شده است متوقف کند.
- این معماری اپلیکیشن را وادار میکند که در یک مجموعه فناوری منفرد پیادهسازی شود.
- در مواردی که زمان تحویل طولانیتر شود، در طی زمان نیازمند پول بیشتری برای توسعه و نگهداری اپلیکیشن خواهد بود.
- از آنجا که همه کد درون یک اپلیکیشن منفرد قرار دارد، نگهداری کد پس از مدتی به سرعت دشوار میشود.
معماری میکروسرویس چگونه است؟
به طور خلاصه یک مفهوم وجود دارد و آن این است که ما همواره ملزم هستیم نرمافزار را نگهداری و بهروزرسانی کنیم. باید فرایند بهبود اپلیکیشنها را آسانتر و مقدار زمان مورد نیاز برای ارائه نسخههای جدید اپلیکیشنها را کوتاهتر کنیم.
میکروسرویسها برای حل مسائل اشاره شده فوق معرفی شدهاند. معماری میکروسرویس یک بهینهسازی در زمینه معماری فوقالذکر محسوب میشود. در این معماری هر کارکرد تجاری به صورت یک سرویس ارائه میشود. هر سرویس میتواند به صورت مستقل از سرویسهای دیگر میزبانی و توزیع شود.
معماری میکروسرویس
هر سرویس را میتوان یک اپلیکیشن کوچک تصور کرد.
- همه سرویسها میتوانند حتی زمانی که سرویسها روی ماشینهای مختلف هستند، با همدیگر ارتباط داشته باشند. این وضعیت در ادامه امکان پیادهسازی کارکردهای جدید در سرویسها را فراهم میسازد.
- میکروسرویسها، سازمانها را تشویق میکنند که از فرایند توزیع و تحویل پیوسته خودکار پیروی کنند.
- اپلیکیشنها در نهایت بسیار پایدارتر میشوند، چون هر ویژگی میتواند به صورت مستقلانه تست و توزیع شود.
- از آنجا که هر سرویس روی پردازش مجزایی میزبانی میشود، اگر یک سرویس به نقطه تنگنای اپلیکیشن تبدیل شود و به منابع زیادی نیاز داشته باشد، در این صورت میتوان آن را بدون هیچ گونه تأثیر سوء روی سرویسهای دیگر، به ماشین دیگری انتقال داد.
- زمانی که کاربران بیشتری شروع به استفاده از یک ویژگی اپلیکیشن بکنند، آن سرویس میتواند با توزیع روی رایانههای قدرتمندتر یا از طریق استفاده از کش بدون این که روی سرویسهای دیگر هیچ تأثیری بگذارد، مقیاسبندی شود.
- این معماری پایداری اپلیکیشن را نیز افزایش میدهد، چون هر سرویس میتواند به صورت مستقلانه ساخته، تست، توزیع و استفاده شود.
- کد اپلیکیشن میتواند به سادگی نگهداری شود و پردازشها میتوانند به صورت مجزا تحت نظارت قرار بگیرند.
- توسعهدهندگان اختصاصی میتوانند سرویسها را به صورت مستقل از هم پیادهسازی کرده و این سرویسها را بدون تأثیرگذاری روی سرویسهای دیگر انتشار دهند.
- بدین ترتیب نقطه شکست منفرد نیز از بین میرود، زیرا یک سرویس میتواند بدون تأثیرگذاری روی ویژگیهای دیگری که اپلیکیشن نرمافزاری ارائه میکند، متوقف شود.
- در نتیجه این طراحی زمان مورد نیاز برای تحویل نسخههای جدید را کاهش میدهد و بنابراین هزینه را در طی زمان کاهش میدهد.
- قابلیت استفاده مجدد از کد افزایش مییابد، زیرا یک ویژگی به صورت سرویس میزبانی شده است و امکان استفاده چند سرویس از یک ویژگی به جای پیادهسازی مجدد کد در هر مورد وجود دارد.
- معماری مبتنی بر سرویس امکان استفاده از مجموعه متنوعی از فناوری برای رفع نیازها وجود دارد. به عنوان نمونه بستههای تحلیل داده زبان R یا پایتون میتوانند به صورت مجزا توزیع و میزبانی شوند و همزمان میتوان از C#.Net برای پیادهسازی سرویسها استفاده کرد. به علاوه میتوان از NodeJS در سمت سرور استفاده کرد و AngularJs و ReactJs نیز برای پیادهسازی رابط کاربری مورد استفاده قرار گیرند. هر ویژگی تجاری میتواند با استفاده از مجموعه مختلفی و از طریق تیم متفاوتی، مستقل از ویژگیهای دیگر پیادهسازی شود.
منبع: فرادرس