JavaRush /Java Blogu /Random-AZ /Java Mikroservisləri üçün bələdçi. 1-ci hissə: Mikroservi...

Java Mikroservisləri üçün bələdçi. 1-ci hissə: Mikroservislərin əsasları və arxitekturası

Qrupda dərc edilmişdir
Bu təlimatda siz Java mikroservislərinin nə olduğunu, onların dizaynını və yaradılmasını öyrənəcəksiniz. O, həmçinin Java mikroservis kitabxanaları və mikroservislərdən istifadənin mümkünlüyü ilə bağlı sualları əhatə edir. Java Mikroservislərinin tərcüməsi və uyğunlaşdırılması : Praktik Bələdçi .

Java Mikroxidmətləri: Əsaslar

Mikroservisləri başa düşmək üçün əvvəlcə onların nə olmadığını müəyyənləşdirməlisiniz. Bu "monolit" deyilmi - Java monolit: bu nədir və onun üstünlükləri və ya mənfi cəhətləri nədir? Java Mikroservisləri üçün bələdçi.  1-ci hissə: Mikroservislərin əsasları və arxitekturası - 1

Java monolit nədir?

Təsəvvür edin ki, bir bankda və ya fintech startapında işləyirsiniz. Siz istifadəçilərə yeni bank hesabı açmaq üçün istifadə edə biləcəkləri mobil proqram təqdim edirsiniz. Java kodunda bu, nəzarətçi sinifinin olması ilə nəticələnəcək. Sadələşdirilmiş, belə görünür:
@Controller
class BankController {

    @PostMapping("/users/register")
    public void register(RegistrationForm form) {
        validate(form);
        riskCheck(form);
        openBankAccount(form);
        // etc..
    }
}
Sizə nəzarətçi lazımdır:
  1. Qeydiyyat formasını təsdiqlədi.
  2. İstifadəçiyə bank hesabı təqdim edib-etməmək barədə qərar vermək üçün onun ünvanının risklərini yoxladı.
  3. Bank hesabı açdı.
Sinif BankControlleryerləşdirmə üçün qalan mənbələrinizlə birlikdə bank.jar və ya bank.war faylına paketlənəcək - bu, bankınızı idarə etmək üçün lazım olan bütün kodları ehtiva edən köhnə yaxşı monolitdir. Təxmini hesablama olaraq, .jar (və ya .war) faylının ilkin ölçüsü 1 ilə 100 MB arasında dəyişəcək. İndi siz sadəcə olaraq serverinizdə .jar faylını işə sala bilərsiniz... və Java proqramınızı yerləşdirmək üçün sizə lazım olan hər şey budur. Java Mikroservisləri üçün bələdçi.  1-ci hissə: Mikroservislərin əsasları və arxitekturası - 2Şəkil, yuxarı sol düzbucaqlı: mono(litik) bankın yerləşdirilməsi java -jar bank.jar (cp .war/.ear appserver-ə). Sağ düzbucaqlı: brauzeri açın.

Java monolitləri ilə bağlı problem nədir?

Java monolitlərində heç bir problem yoxdur. Ancaq təcrübə göstərdi ki, əgər layihənizdə:
  • Bir çox proqramçı/komanda/məsləhətçi işləyir...
  • ...çox qeyri-müəyyən tələbləri olan müştərilərin təzyiqi altında eyni monolit üzərində...
  • bir neçə il ərzində...
... bu halda sizin kiçik bank.jar faylınız təkbaşına nəhəng gigabayt koda çevrilir ki, bu da yerləşdirməyi bir yana, yaxınlaşmaq belə qorxuludur.

Java monolitinin ölçüsünü necə azaltmaq olar?

Təbii sual yaranır: monoliti necə kiçik etmək olar? Hal-hazırda bank.jar bir JVM-də, bir serverdə bir prosesdə işləyir. Nə çox, nə də az. Və indi ağlıma məntiqli bir fikir gələ bilər: “Ancaq riskin yoxlanılması xidmətindən mənim şirkətimdəki digər şöbələr də istifadə edə bilər! Bu, mənim monolit bank tətbiqimlə birbaşa əlaqəli deyil! Bəlkə onu monolitdən kəsib ayrı bir məhsul kimi yerləşdirmək lazımdır? Yəni texniki desək, onu ayrıca Java prosesi kimi idarə edir.”

Java mikroservisi nədir?

Praktikada bu ifadə o deməkdir ki, indi metod çağırışı riskCheck()BankController-dən edilməyəcək: bu metod və ya lobya komponenti bütün köməkçi sinifləri ilə öz Maven və ya Gradle layihəsinə köçürüləcək. O, həmçinin bank monolitindən asılı olmayaraq yerləşdiriləcək və versiya nəzarəti altında yerləşdiriləcək. Bununla belə, bütün bu çıxarma prosesi sizin yeni RiskCheck modulunuzu özlüyündə mikroservisə çevirmir, çünki mikroservisin tərifi şərhə açıqdır. Bu, komandalar və şirkətlər daxilində tez-tez müzakirələrə səbəb olur.
  • Layihədə 5-7 sinif mikro və ya nə var?
  • 100 və ya 1000 sinif... hələ də mikro?
  • Mikroservis ümumiyyətlə siniflərin sayı ilə bağlıdır, ya yox?
Gəlin nəzəri mülahizələri geridə qoyaq və bunun əvəzinə praqmatik mülahizələrə sadiq qalaq və bunu edək:
  1. Ölçüsündən və ya domen sərhədlərindən asılı olmayaraq, ayrı-ayrılıqda yerləşdirilən bütün xidmətlərə mikroservislər deyək.
  2. Xidmətlərarası əlaqəni necə təşkil edəcəyimizi düşünək. Mikroservislərimizin bir-biri ilə əlaqə qurma yollarına ehtiyacı var.
Beləliklə, ümumiləşdirmək üçün: əvvəllər bir JVM prosesiniz var idi, bankı idarə etmək üçün möhkəm monolit. İndi sizin bankçılıq monolit JVM prosesi və öz JVM prosesi çərçivəsində işləyən ayrıca RiskCheck mikroservisi var. İndi isə riskləri yoxlamaq üçün monolitiniz bu mikroservisə çağırmalıdır. Bunu necə etmək olar?

Java mikroservisləri arasında əlaqəni necə qurmaq olar?

Ümumiyyətlə və ümumiyyətlə, iki variant var - sinxron və asinxron rabitə.

Sinxron rabitə: (HTTP)/REST

Tipik olaraq, mikroservislər arasında sinxronlaşdırılmış əlaqə XML və ya JSON qaytaran HTTP və REST kimi xidmətlər vasitəsilə baş verir. Əlbəttə ki, başqa variantlar ola bilər - ən azı Google Protokol Buferlərini götürün . Dərhal cavab lazımdırsa, REST rabitəsindən istifadə etmək daha yaxşıdır. Bizim nümunəmizdə, hesab açmadan əvvəl riskin yoxlanılması tələb olunduğundan, məhz bunu etmək lazımdır. Risk yoxlanışı yoxdursa, hesab da yoxdur. Aşağıdakı alətləri " Sinxron Java REST zəngləri üçün ən yaxşı kitabxanalar " bölməsində müzakirə edəcəyik .

Mesajlaşma - Asinxron Ünsiyyət

Asinxron mikroservis rabitəsi adətən JMS tətbiqi ilə mesaj mübadiləsi və/yaxud AMQP kimi protokoldan istifadə etməklə həyata keçirilir . Burada bir səbəbə görə "adətən" yazdıq: tutaq ki, e-poçt/SMTP inteqrasiyalarının sayını qiymətləndirmək olmaz. Dərhal cavaba ehtiyacınız olmadıqda istifadə edin. Məsələn, istifadəçi “indi al” düyməsini sıxır və siz də öz növbəsində faktura yaratmaq istəyirsiniz. Bu proses, şübhəsiz ki, istifadəçinin satınalma sorğusu-cavab dövrü ərzində baş verməməlidir. Aşağıda asinxron Java mesajlaşması üçün hansı vasitələrin ən yaxşı olduğunu təsvir edəcəyik .

Nümunə: Java-da REST API çağırışı

Tutaq ki, biz sinxron mikroservis rabitəsini seçirik. Bu halda, aşağı səviyyədə Java kodumuz (yuxarıda təqdim etdiyimiz) bu kimi görünəcək. (aşağı səviyyə dedikdə, mikroservis rabitəsi üçün adətən sizi faktiki HTTP zənglərindən mücərrəd edən müştəri kitabxanalarının yaradıldığını nəzərdə tuturuq).
@Controller
class BankController {

    @Autowired
    private HttpClient httpClient;

    @PostMapping("/users/register")
    public void register(RegistrationForm form) {
        validate(form);
        httpClient.send(riskRequest, responseHandler());
        setupAccount(form);
        // etc..
    }
}
Koda əsaslanaraq aydın olur ki, biz indi iki Java (mikro) xidmətini, Bank və RiskCheck tətbiq etməliyik. Nəticədə iki JVM prosesi işləyəcək. Java Mikroservisləri üçün bələdçi.  1-ci hissə: Mikroservislərin əsasları və arxitekturası - 3Java mikroservisləri layihəsini inkişaf etdirmək üçün sizə lazım olan hər şey budur: bir monolit yerinə daha kiçik hissələr (.jar və ya .war faylları) qurun və yerləşdirin. Sualın cavabı qeyri-müəyyən olaraq qalır: monoliti mikroservislərə necə kəsməliyik? Bu parçalar nə qədər kiçik olmalıdır, düzgün ölçüsü necə təyin etmək olar? yoxlayaq.

Java Mikroservislər Memarlığı

Təcrübədə şirkətlər müxtəlif yollarla mikroservis layihələri hazırlayırlar. Bu yanaşma, mövcud monoliti mikroservis layihəsinə çevirməyə çalışmağınızdan və ya layihəni sıfırdan başlamağınızdan asılıdır.

Monolitdən mikroservislərə qədər

Ən məntiqli ideyalardan biri mövcud monolitdən mikroservislər çıxarmaqdır. Qeyd edək ki, buradakı "mikro" prefiksi əslində çıxarılan xidmətlərin həqiqətən kiçik olacağı anlamına gəlmir; bu, mütləq belə deyil. Nəzəri əsaslara nəzər salaq.

İdeya: monoliti mikroservislərə ayırın

Mikroservis yanaşması köhnə layihələrə tətbiq edilə bilər. Və buna görə də:
  1. Çox vaxt belə layihələri saxlamaq/dəyişmək/genişləndirmək çətindir.
  2. Tərtibatçılardan tutmuş idarəetməyə qədər hamı sadələşdirmə istəyir.
  3. Sizin (nisbətən) aydın domen sərhədləriniz var, yəni proqram təminatınızın nə etməli olduğunu dəqiq bilirsiniz.
Nümunəmizə qayıdaraq, bu o deməkdir ki, siz Java bankçılıq monolitinizə baxa və onu domen sərhədləri boyunca parçalamağa cəhd edə bilərsiniz.
  • Beləliklə, istifadəçi məlumatlarının (adlar, ünvanlar, telefon nömrələri kimi) emalını ayrıca "Hesabın İdarə Edilməsi" mikroservisinə ayırmaq məqsədəuyğun olardı.
  • Və ya istifadəçinin risk səviyyələrini yoxlayan və bir çox digər layihələr və ya hətta şirkətin departamentləri tərəfindən istifadə edilə bilən yuxarıda qeyd olunan "Risk Yoxlama Modulu".
  • Və ya fakturaları PDF formatında və ya poçtla göndərən faktura modulu.

İdeyanın həyata keçirilməsi: başqasına icazə verin

Yuxarıda təsvir edilən yanaşma kağızda və UML kimi diaqramlarda əla görünür. Bununla belə, hər şey o qədər də sadə deyil. Onun praktiki həyata keçirilməsi ciddi texniki hazırlıq tələb edir: monolitdən nə çıxarmağın gözəl olacağını başa düşməyimizlə hasilat prosesinin özü arasında fərq çox böyükdür. Əksər müəssisə layihələri elə bir mərhələyə çatır ki, tərtibatçılar, məsələn, Hibernate-in 7 illik versiyasını daha yenisinə təkmilləşdirməkdən çəkinirlər. Kitabxanalar onunla birlikdə yenilənəcək, lakin nəyisə sındırmaq təhlükəsi var. Beləliklə, eyni tərtibatçılar indi qeyri-müəyyən verilənlər bazası əməliyyat sərhədləri ilə qədim miras kodunu kəşf etməli və yaxşı müəyyən edilmiş mikroservisləri çıxarmalıdırlar? Çox vaxt bu problem çox mürəkkəbdir və lövhədə və ya memarlıq iclaslarında "həll edilə bilməz". Java Mikroservisləri üçün bələdçi.  1-ci hissə: Mikroservislərin əsasları və arxitekturası - 4Twitter tərtibatçısı @simonbrown-dan sitat gətirmək üçün: Mən bunu təkrar-təkrar deyəcəyəm... əgər insanlar monolitləri düzgün qura bilmirlərsə, mikroservislər kömək etməyəcək. Simon Brown

Mikroservis arxitekturasına əsaslanan sıfırdan layihə

Yeni Java layihələri vəziyyətində, əvvəlki hissədəki üç nömrəli nöqtə bir qədər fərqli görünür:
  1. Təmiz bir şiferlə başlayırsınız, ona görə də saxlanacaq “baqaj” yoxdur.
  2. Tərtibatçılar gələcəkdə hər şeyi sadə saxlamaq istəyirlər.
  3. Problem: Sizdə domen sərhədlərinin daha qeyri-səlis mənzərəsi var: proqramınızın əslində nə etməli olduğunu bilmirsiniz (işarə: çevik ;))
Bu, şirkətlərin Java mikroservisləri ilə yeni layihələrə cəhd etmələrinə səbəb olur.

Texniki mikroservis arxitekturası

İlk nöqtə tərtibatçılar üçün ən açıq görünür, lakin bunu qəti şəkildə rədd edənlər də var. Hadi Həriri IntelliJ-də "Extract Microservice" refaktorinqini tövsiyə edir. Aşağıdakı nümunə çox sadələşdirilmiş olsa da, real layihələrdə müşahidə olunan tətbiqlər təəssüf ki, bundan çox da uzağa getmir. Mikroservislərdən əvvəl
@Service
class UserService {

    public void register(User user) {
        String email = user.getEmail();
        String username =  email.substring(0, email.indexOf("@"));
        // ...
    }
}
Alt sətir Java mikroservisi ilə
@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());
        // ...
    }
}
Beləliklə, siz əslində heç bir aşkar səbəb olmadan Java metodu çağırışını HTTP çağırışına daxil edirsiniz. Bununla belə, bir səbəb budur: təcrübənin olmaması və Java mikroservisləri yanaşmasını məcbur etməyə çalışmaq. Tövsiyə: Bunu etməyin.

İş axını yönümlü mikroservis arxitekturası

Növbəti ümumi yanaşma Java mikroservislərini iş axınına əsaslanan modullara bölməkdir. Real həyat nümunəsi: Almaniyada (ictimai) həkimə getdiyiniz zaman o, sizin səfərinizi tibbi CRM sistemində qeyd etməlidir. Sığortadan ödəniş almaq üçün o, XML vasitəsilə sizin müalicəniz (və digər xəstələrin müalicəsi) haqqında məlumatları vasitəçiyə göndərəcək. Broker bu XML faylına baxacaq və (sadələşdirilmiş):
  1. Düzgün XML faylının qəbul edilib-edilmədiyini yoxlayacaq.
  2. Prosedurların inandırıcılığını yoxlayacaq: deyək ki, bir ginekoloqdan bir gündə üç diş təmizləmə proseduru alan bir yaşlı uşaq bir qədər şübhəli görünür.
  3. XML-i bəzi digər bürokratik məlumatlar ilə birləşdirəcək.
  4. Ödənişlərə başlamaq üçün XML faylını sığorta şirkətinə göndərəcək.
  5. Və o, nəticəni həkimə göndərərək ona “uğur” və ya “məntiqi gələn kimi bu qeydi yenidən göndərin” mesajını verəcək.
Qeyd. Bu nümunədə, mikroservislər arasında əlaqə rol oynamır, lakin bir mesaj brokeri (məsələn, RabbitMQ) tərəfindən asinxron şəkildə edilə bilər, çünki həkim hər halda dərhal rəy almır. Java Mikroservisləri üçün bələdçi.  1-ci hissə: Mikroservislərin əsasları və arxitekturası - 5Yenə də bu kağız üzərində əla görünür, lakin təbii suallar yaranır:
  • Bir XML faylını emal etmək üçün altı proqram yerləşdirmək lazımdırmı?
  • Bu mikroservislər həqiqətən bir-birindən müstəqildirmi? Onlar bir-birindən müstəqil şəkildə yerləşdirilə bilərmi? Müxtəlif versiyalar və API sxemləri ilə?
  • Doğrulama mikroxidməti işləmirsə, etibarlılıq mikroxidməti nə edir? Sistem hələ də işləyir?
  • Bu mikroservislər eyni verilənlər bazasını paylaşırmı (onlar, şübhəsiz ki, verilənlər bazası cədvəllərində bəzi ümumi məlumatlara ehtiyac duyurlar) yoxsa onların hər birinin özünəməxsus var?
  • … və daha çox.
Maraqlıdır ki, yuxarıdakı diaqram daha sadə görünür, çünki indi hər bir xidmətin öz dəqiq, dəqiq müəyyən edilmiş məqsədi var. Əvvəllər bu qorxulu monolit kimi görünürdü: Java Mikroservisləri üçün bələdçi.  1-ci hissə: Mikroservislərin əsasları və arxitekturası - 6Bu diaqramların sadəliyi haqqında mübahisə edə bilsəniz də, indi mütləq bu əlavə əməliyyat problemlərini həll etməlisiniz.
  • Sizə sadəcə bir proqram deyil, ən azı altı tətbiq yerləşdirmək lazımdır.
  • Mikroservislərin arxitekturasına nə qədər getmək istədiyinizdən asılı olaraq, hətta bir neçə verilənlər bazası yerləşdirməyinizə ehtiyac ola bilər.
  • Hər bir sistemin onlayn olduğundan və düzgün işlədiyinə əmin olmalısınız.
  • Mikroservislər arasında zənglərinizin həqiqətən davamlı olduğundan əmin olmalısınız (bax: Java mikroservisini necə möhkəm etmək olar?).
  • Və bu quraşdırmanın nəzərdə tutduğu hər şey - yerli inkişaf parametrlərindən tutmuş inteqrasiya testinə qədər.
Beləliklə, tövsiyə belə olardı:
  • Əgər Netflix deyilsinizsə (ehtimal ki, Netflix deyilsiniz)...
  • Əgər inkişaf mühitini açdığınız və 5 saniyə ərzində asanlıqla bərpa olunan istehsal məlumat bazanızı atan xaos meymununu çağırdığınız super güclü iş bacarıqlarınız yoxdursa.
  • və ya özünüzü @monzo kimi hiss edirsiniz və sadəcə bacardığınız üçün 1500 mikroservisi sınamağa hazırsınız.
→ Bunu etmə. Və indi daha az hiperbolikdir. Mikroservisləri domen sərhədləri boyunca modelləşdirməyə çalışmaq olduqca məqbul görünür. Lakin bu o demək deyil ki, siz bir iş axını götürməli və onu kiçik fərdi hissələrə bölməlisiniz (XML qəbul edin, XML-i doğrulayın, XML-i yönləndirin). Beləliklə, Java mikroservisləri ilə yeni bir layihəyə başladığınız zaman və domen sərhədləri hələ də çox qeyri-müəyyəndir, mikroservislərinizin ölçüsünü aşağı səviyyədə saxlamağa çalışın. Siz həmişə sonra daha çox modul əlavə edə bilərsiniz. Yeni infrastrukturunuzu dəstəkləmək üçün komandada/şirkətdə/bölmədə qabaqcıl DevOps-a sahib olduğunuzdan əmin olun.

Poliqlot və ya komanda yönümlü mikroservis arxitekturası

Mikroservislərin inkişafı üçün üçüncü, demək olar ki, libertar yanaşma var: komandalara və ya hətta fərdlərə istənilən sayda dildən və ya mikroservisdən istifadə edərək istifadəçi hekayələrini həyata keçirməyə icazə vermək (marketoloqlar bu yanaşmanı “poliqlot proqramlaşdırma” adlandırırlar). Beləliklə, yuxarıda təsvir edilən XML doğrulama xidməti Java-da, doğrulama mikroservisi isə eyni zamanda Haskell-də (riyazi cəhətdən düzgün olması üçün) yazıla bilər. Sığorta göndərmə mikroxidməti üçün siz Erlanqdan istifadə edə bilərsiniz (çünki o, həqiqətən miqyaslanmalıdır;)). Tərtibatçının nöqteyi-nəzərindən əyləncəli görünə bilən şey (təcrid olunmuş mühitdə mükəmməl dilinizlə mükəmməl sistemi inkişaf etdirmək) əslində heç vaxt təşkilatın istədiyi şey deyil: homogenləşdirmə və standartlaşdırma. Bu, nisbətən standartlaşdırılmış dillər, kitabxanalar və alətlər dəsti deməkdir ki, siz daha yaşıl otlaqlara keçdiyiniz zaman digər tərtibatçılar gələcəkdə Haskell mikroservisinizi dəstəkləməyə davam edə bilsinlər. Java Mikroservisləri üçün bələdçi.  1-ci hissə: Mikroservislərin əsasları və arxitekturası - 8Tarix göstərir ki, standartlaşdırma adətən çox dərin kök salır. Məsələn, böyük Fortune 500 şirkətlərində tərtibatçılara bəzən Spring-dən istifadə etməyə icazə verilmirdi, çünki bu, "şirkətin texnologiya yol xəritəsinin bir hissəsi deyildi". Bununla belə, poliqlot yanaşmasına tam keçid demək olar ki, eyni şeydir, eyni sikkənin digər tərəfidir. Tövsiyə: Poliqlot proqramlaşdırmadan istifadə edəcəksinizsə, eyni proqramlaşdırma dili ekosistemində daha az müxtəlifliyə cəhd edin. Beləliklə, Java və deyək ki, Haskelldənsə, Kotlin və Java-dan (hər iki dil JVM-ə əsaslanır və bir-biri ilə 100% uyğundur) birlikdə istifadə etmək daha yaxşıdır. Növbəti hissədə siz Java mikroservislərinin tətbiqi və sınaqdan keçirilməsi haqqında öyrənəcəksiniz.
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION