در این راهنما، می آموزید که میکروسرویس های جاوا چیست، چگونه آنها را طراحی و ایجاد کنید. همچنین سوالاتی در مورد کتابخانه های میکروسرویس جاوا و امکان استفاده از میکروسرویس ها را پوشش می دهد. ترجمه و اقتباس از Microservices جاوا: راهنمای عملی .
جاوا میکروسرویس: اصول
برای درک میکروسرویس ها، ابتدا باید تعریف کنید که چه چیزی نیستند. آیا یک "مونولیت" نیست - یکپارچه جاوا: چیست و مزایا یا معایب آن چیست؟یکپارچه جاوا چیست؟
تصور کنید برای یک بانک یا یک استارت آپ فین تک کار می کنید. شما یک اپلیکیشن موبایلی را در اختیار کاربران قرار می دهید که می توانند از آن برای باز کردن یک حساب بانکی جدید استفاده کنند. در کد جاوا این منجر به حضور یک کلاس کنترلر می شود. ساده شده، به نظر می رسد این است:@Controller
class BankController {
@PostMapping("/users/register")
public void register(RegistrationForm form) {
validate(form);
riskCheck(form);
openBankAccount(form);
// etc..
}
}
شما به کنترلر نیاز دارید تا:
- فرم ثبت نام را تایید کرد.
- خطرات آدرس کاربر را بررسی کرد تا تصمیم بگیرد که آیا یک حساب بانکی به او ارائه دهد یا خیر.
- حساب بانکی باز کرد
BankController
به همراه بقیه منابع شما در یک فایل bank.jar یا bank.war برای استقرار بسته بندی می شود - این یک مونولیت قدیمی خوب است که حاوی تمام کدهای مورد نیاز برای اجرای بانک شما است. به عنوان یک تخمین تقریبی، اندازه اولیه یک فایل jar (یا .war) از 1 تا 100 مگابایت متغیر است. اکنون می توانید به سادگی فایل jar را روی سرور خود اجرا کنید... و این تنها کاری است که برای استقرار برنامه جاوا خود باید انجام دهید. تصویر، مستطیل بالا سمت چپ: استقرار یک بانک تک (لیتیک) جاوا -jar bank.jar (cp .war/.ear در سرور برنامه). مستطیل راست: مرورگر را باز کنید.
مشکل یکپارچه های جاوا چیست؟
هیچ مشکلی ذاتاً با یکپارچههای جاوا وجود ندارد. با این حال، تجربه نشان داده است که اگر در پروژه شما:- برنامه نویسان / تیم ها / مشاوران زیادی در حال کار هستند ...
- ... بر روی همان یکپارچه تحت فشار مشتریان با الزامات بسیار مبهم ...
- در عرض یکی دو سال ...
چگونه اندازه یک مونولیت جاوا را کاهش دهیم؟
یک سوال طبیعی مطرح می شود: چگونه یکپارچه را کوچکتر کنیم؟ در حال حاضر bank.jar شما روی یک JVM، یک فرآیند روی یک سرور در حال اجرا است. نه بیشتر نه کمتر. و در حال حاضر ممکن است یک فکر منطقی به ذهن خطور کند: "اما خدمات تأیید خطر می تواند توسط سایر بخش های شرکت من استفاده شود! ارتباط مستقیمی با برنامه بانکداری یکپارچه من ندارد! شاید باید از یکپارچه خارج شود و به عنوان یک محصول جداگانه به کار گرفته شود؟ یعنی از نظر فنی، اجرای آن به عنوان یک فرآیند جاوا جداگانه.میکروسرویس جاوا چیست؟
در عمل، این عبارت به این معنی است که اکنون فراخوانی متدriskCheck()
از BankController انجام نخواهد شد: این متد یا جزء bean با تمام کلاس های کمکی خود به پروژه Maven یا Gradle خود منتقل می شود. همچنین مستقل از یکپارچگی بانکی مستقر شده و تحت کنترل نسخه قرار می گیرد. با این حال، کل این فرآیند استخراج ماژول جدید RiskCheck شما را به خودی خود به یک میکروسرویس تبدیل نمی کند، زیرا تعریف میکروسرویس قابل تفسیر است. این منجر به بحث های مکرر در تیم ها و شرکت ها می شود.
- آیا 5-7 کلاس در یک پروژه میکرو است یا چه؟
- 100 یا 1000 کلاس ... هنوز میکرو؟
- آیا میکروسرویس به طور کلی به تعداد کلاس ها مربوط می شود یا خیر؟
- بیایید همه سرویسهای مستقر جداگانه را بدون در نظر گرفتن اندازه یا مرزهای دامنه، میکروسرویسها بنامیم.
- بیایید به نحوه ترتیب دادن ارتباطات بین سرویس فکر کنیم. میکروسرویس های ما به راه هایی برای برقراری ارتباط با یکدیگر نیاز دارند.
چگونه بین میکروسرویس های جاوا ارتباط برقرار کنیم؟
به طور کلی و به طور کلی، دو گزینه وجود دارد - ارتباط همزمان و ناهمزمان.ارتباط همزمان: (HTTP)/REST
به طور معمول، ارتباط همگامسازی شده بین میکروسرویسها از طریق HTTP و سرویسهای مشابه REST انجام میشود که XML یا JSON را برمیگردانند. البته، ممکن است گزینه های دیگری نیز وجود داشته باشد - حداقل از Google Protocol Buffers استفاده کنید . اگر نیاز به پاسخ فوری دارید، بهتر است از ارتباط REST استفاده کنید. در مثال ما، این دقیقاً همان کاری است که باید انجام شود، زیرا تأیید ریسک قبل از افتتاح حساب مورد نیاز است. اگر بررسی ریسک وجود نداشته باشد، هیچ حسابی وجود ندارد. ابزارهای زیر را در بخش « کدام کتابخانهها برای تماسهای REST همگام جاوا بهتر هستند » مورد بحث قرار خواهیم داد.پیام رسانی - ارتباطات ناهمزمان
ارتباط میکروسرویس ناهمزمان معمولاً با تبادل پیام با اجرای JMS و/یا استفاده از پروتکلی مانند AMQP انجام میشود . ما "معمولا" را در اینجا به دلیلی نوشتیم: فرض کنید تعداد ادغام های ایمیل/SMTP را نمی توان دست کم گرفت. زمانی که نیاز به پاسخ فوری ندارید از آن استفاده کنید. به عنوان مثال، کاربر روی دکمه "خرید اکنون" کلیک می کند و شما نیز به نوبه خود می خواهید یک فاکتور ایجاد کنید. این فرآیند مطمئناً نباید در چرخه درخواست خرید-پاسخ کاربر رخ دهد. در زیر توضیح خواهیم داد که کدام ابزارها برای پیام رسانی ناهمزمان جاوا بهترین هستند .مثال: REST API فراخوانی در جاوا
بیایید فرض کنیم ارتباط میکروسرویس سنکرون را انتخاب می کنیم. در این حالت، کد جاوا ما (همانی که در بالا ارائه کردیم) در سطح پایین چیزی شبیه به این خواهد بود. (در اینجا منظور ما از سطح پایین این واقعیت است که برای ارتباطات میکروسرویس، معمولاً کتابخانه های مشتری ایجاد می شوند که شما را از تماس های HTTP واقعی انتزاع می کند).@Controller
class BankController {
@Autowired
private HttpClient httpClient;
@PostMapping("/users/register")
public void register(RegistrationForm form) {
validate(form);
httpClient.send(riskRequest, responseHandler());
setupAccount(form);
// etc..
}
}
بر اساس کد، مشخص می شود که اکنون باید دو سرویس جاوا (micro) بانک و RiskCheck را مستقر کنیم. در نتیجه، دو فرآیند JVM در حال اجرا خواهیم داشت. این تمام چیزی است که برای توسعه یک پروژه میکروسرویس جاوا نیاز دارید: فقط تکه های کوچکتر (فایل های jar یا .war) را به جای یک قطعه یکپارچه بسازید و بکار ببرید. پاسخ به این سوال همچنان نامشخص است: چگونه باید یکپارچه را به میکروسرویس برش دهیم؟ این قطعات چقدر باید کوچک باشند، چگونه اندازه صحیح را تعیین کنیم؟ بیایید بررسی کنیم.
معماری میکروسرویس جاوا
در عمل، شرکت ها پروژه های میکروسرویس را به روش های مختلف توسعه می دهند. این رویکرد به این بستگی دارد که آیا میخواهید یک پروژه یکپارچه موجود را به یک پروژه میکروسرویس تبدیل کنید یا پروژه را از ابتدا شروع کنید.از یکپارچه تا میکروسرویس
یکی از منطقی ترین ایده ها استخراج میکروسرویس ها از یک مونولیت موجود است. توجه داشته باشید که پیشوند «micro» در اینجا در واقع به این معنی نیست که خدمات استخراج شده واقعاً کوچک خواهند بود؛ لزوماً اینطور نیست. بیایید به پیشینه نظری نگاه کنیم.ایده: یکپارچه را به میکروسرویس ها تقسیم کنید
رویکرد میکروسرویس را می توان برای پروژه های قدیمی به کار برد. و به همین دلیل:- اغلب، نگهداری/تغییر/گسترش چنین پروژه هایی دشوار است.
- همه، از توسعه دهندگان گرفته تا مدیریت، خواهان ساده سازی هستند.
- شما مرزهای دامنه (نسبتا) واضحی دارید، به این معنی که دقیقاً می دانید نرم افزار شما باید چه کاری انجام دهد.
- بنابراین، منطقی است که پردازش دادههای کاربر (مانند نام، آدرس، شماره تلفن) را در یک میکروسرویس جداگانه «مدیریت حساب» جدا کنیم.
- یا "ماژول بررسی ریسک" که سطوح ریسک کاربر را بررسی می کند و می تواند توسط بسیاری از پروژه های دیگر یا حتی بخش های شرکت استفاده شود.
- یا یک ماژول صورتحساب که فاکتورها را در قالب PDF یا از طریق پست ارسال می کند.
اجرای یک ایده: اجازه دهید شخص دیگری آن را انجام دهد
روشی که در بالا توضیح داده شد روی کاغذ و نمودارهای UML مانند عالی به نظر می رسد. با این حال، همه چیز به این سادگی نیست. اجرای عملی آن مستلزم آمادگی فنی جدی است: شکاف بین درک ما از آنچه استخراج کردن از یکپارچه خوب است و خود فرآیند استخراج بسیار زیاد است. بیشتر پروژههای سازمانی به مرحلهای میرسند که توسعهدهندگان میترسند، مثلاً نسخه ۷ ساله Hibernate را به نسخه جدیدتر ارتقا دهند. کتابخانه ها همراه با آن به روز خواهند شد، اما خطر واقعی شکستن چیزی وجود دارد. بنابراین همان توسعه دهندگان اکنون باید از طریق کدهای قدیمی قدیمی با مرزهای تراکنش پایگاه داده نامشخص و استخراج ریزسرویس های کاملاً تعریف شده را بررسی کنند؟ اغلب اوقات، این مشکل بسیار پیچیده است و نمی توان آن را در یک تخته سفید یا در جلسات معماری "حل" کرد. به نقل از توسعه دهنده توییتر @simonbrown: من این را بارها و بارها خواهم گفت... اگر مردم نتوانند به درستی یکپارچه بسازند، میکروسرویس ها کمکی نمی کنند. سیمون براونپروژه از ابتدا بر اساس معماری میکروسرویس
در مورد پروژه های جدید جاوا، سه نقطه شماره گذاری شده از قسمت قبل کمی متفاوت به نظر می رسند:- شما با یک لوح تمیز شروع می کنید، بنابراین هیچ "چمدانی" برای نگهداری وجود ندارد.
- توسعه دهندگان مایلند در آینده همه چیز را ساده نگه دارند.
- مشکل: شما تصویر بسیار مبهم تری از مرزهای دامنه دارید: نمی دانید نرم افزار شما واقعاً قرار است چه کاری انجام دهد (اشاره: چابک ؛))
معماری میکروسرویس فنی
به نظر می رسد اولین نکته برای توسعه دهندگان واضح ترین نکته باشد، اما کسانی نیز هستند که به شدت آن را منع می کنند. هادی حریری بازآفرینی "Extract Microservice" را در IntelliJ توصیه می کند. و اگرچه مثال زیر بسیار ساده شده است، اما متاسفانه پیاده سازی های مشاهده شده در پروژه های واقعی از آن دور نمی شود. قبل از میکروسرویس ها@Service
class UserService {
public void register(User user) {
String email = user.getEmail();
String username = email.substring(0, email.indexOf("@"));
// ...
}
}
با زیر رشته جاوا میکروسرویس
@Service
class UserService {
@Autowired
private HttpClient client;
public void register(User user) {
String email = user.getEmail();
//теперь вызываем substring microservice via http
String username = httpClient.send(substringRequest(email), responseHandler());
// ...
}
}
بنابراین شما اساساً یک فراخوانی متد جاوا را در یک تماس HTTP بدون هیچ دلیل واضحی برای انجام این کار قرار می دهید. با این حال، یک دلیل این است: عدم تجربه و تلاش برای تحمیل رویکرد میکروسرویس جاوا. توصیه: این کار را نکنید.
معماری میکروسرویس مبتنی بر گردش کار
رویکرد متداول بعدی تقسیم میکروسرویس های جاوا به ماژول های مبتنی بر گردش کار است. مثال واقعی: در آلمان، وقتی نزد یک پزشک (عمومی) می روید، او باید ویزیت شما را در سیستم CRM پزشکی خود ثبت کند. برای دریافت پرداخت از بیمه، او داده های مربوط به درمان شما (و درمان سایر بیماران) را از طریق XML به واسطه ارسال می کند. کارگزار به این فایل XML نگاه می کند و (ساده شده):- بررسی خواهد کرد که آیا فایل XML صحیح دریافت شده است.
- معقول بودن روش ها را بررسی می کند: مثلاً یک کودک یک ساله که سه روش تمیز کردن دندان را در یک روز از متخصص زنان دریافت کرده است تا حدودی مشکوک به نظر می رسد.
- XML را با برخی داده های بوروکراتیک دیگر ترکیب می کند.
- فایل XML را برای شروع پرداخت ها به شرکت بیمه ارسال می کند.
- و نتیجه را برای پزشک ارسال میکند و پیام «موفقیت» یا «لطفاً به محض اینکه منطقی شد، این ضبط را دوباره ارسال کنید» را برای او ارسال میکند.
- آیا برای پردازش یک فایل XML نیاز به استقرار شش برنامه کاربردی است؟
- آیا این میکروسرویس ها واقعاً مستقل از یکدیگر هستند؟ آیا می توان آنها را مستقل از یکدیگر مستقر کرد؟ با نسخه های مختلف و طرح های API؟
- اگر میکروسرویس تأیید صحت کار نکند، میکروسرویس قابل قبول بودن اطلاعات چه می کند؟ آیا سیستم هنوز کار می کند؟
- آیا این میکروسرویس ها پایگاه داده یکسانی را به اشتراک می گذارند (مطمئناً به برخی از داده های رایج در جداول DB نیاز دارند)، یا هر کدام خود را دارند؟
- … و خیلی بیشتر.
- شما فقط نیازی به استقرار یک برنامه ندارید، بلکه حداقل شش برنامه را نیاز دارید.
- حتی ممکن است نیاز به استقرار چندین پایگاه داده داشته باشید، بسته به اینکه تا چه حد می خواهید به معماری میکروسرویس ها بروید.
- شما باید مطمئن شوید که هر سیستم آنلاین است و به درستی کار می کند.
- باید مطمئن شوید که تماسهای شما بین میکروسرویسها واقعاً انعطافپذیر هستند (به نحوه انعطافپذیری میکروسرویس جاوا مراجعه کنید؟).
- و هر چیز دیگری که این تنظیم دلالت دارد - از تنظیمات توسعه محلی گرفته تا تست یکپارچه سازی.
- اگر نتفلیکس نیستید (احتمالاً نتفلیکس نیستید)...
- مگر اینکه در جایی که محیط توسعه را باز میکنید مهارتهای کاری فوقالعاده قوی داشته باشید و یک میمون آشوب را فرا میخواند که پایگاه داده تولید شما را دور میاندازد که به راحتی در 5 ثانیه بازیابی میشود.
- یا احساس می کنید که @monzo هستید و می خواهید 1500 میکروسرویس را امتحان کنید فقط به این دلیل که می توانید.
GO TO FULL VERSION