JavaRush /Java Blog /Random-TL /Isang Gabay sa Java Microservices. Bahagi 1: Mga Pangunah...

Isang Gabay sa Java Microservices. Bahagi 1: Mga Pangunahing Kaalaman at Arkitektura ng Microservices

Nai-publish sa grupo
Sa gabay na ito, matututunan mo kung ano ang mga microservice ng Java, kung paano magdisenyo at lumikha ng mga ito. Sinasaklaw din nito ang mga tanong tungkol sa mga library ng microservice ng Java at ang pagiging posible ng paggamit ng mga microservice. Pagsasalin at pag-aangkop ng Java Microservices: A Practical Guide .

Java Microservices: Mga Pangunahing Kaalaman

Upang maunawaan ang mga microservice, kailangan mo munang tukuyin kung ano ang mga ito. Hindi ba ito isang "monolith" - Java monolith: ano ito at ano ang mga pakinabang o disadvantages nito? Isang Gabay sa Java Microservices.  Bahagi 1: Mga Pangunahing Kaalaman at Arkitektura ng Microservices - 1

Ano ang isang Java monolith?

Isipin na nagtatrabaho ka sa isang bangko o isang fintech startup. Bibigyan mo ang mga user ng mobile app na magagamit nila para magbukas ng bagong bank account. Sa Java code ito ay magreresulta sa pagkakaroon ng isang controller class. Pinasimple, ganito ang hitsura:
@Controller
class BankController {

    @PostMapping("/users/register")
    public void register(RegistrationForm form) {
        validate(form);
        riskCheck(form);
        openBankAccount(form);
        // etc..
    }
}
Kailangan mo ang controller upang:
  1. Nakumpirma ang form ng pagpaparehistro.
  2. Sinuri ang mga panganib ng address ng user upang magpasya kung bibigyan siya ng bank account.
  3. Nagbukas ng bank account.
Ipa-package ang klase BankControllerkasama ang iba pang mga source mo sa isang bank.jar o bank.war file para sa pag-deploy - isa itong magandang lumang monolith na naglalaman ng lahat ng code na kailangan para patakbuhin ang iyong bangko. Bilang isang magaspang na pagtatantya, ang paunang laki ng isang .jar (o .war) na file ay mula 1 hanggang 100 MB. Ngayon ay maaari mo nang patakbuhin ang .jar file sa iyong server... at iyon lang ang kailangan mong gawin upang i-deploy ang iyong Java application. Isang Gabay sa Java Microservices.  Bahagi 1: Mga Pangunahing Kaalaman at Arkitektura ng Microservices - 2Larawan, kaliwang parihaba sa itaas: deployment ng isang mono(lithic) bank java -jar bank.jar (cp .war/.ear into appserver). Kanang parihaba: buksan ang browser.

Ano ang problema sa Java monoliths?

Walang likas na mali sa mga monolith ng Java. Gayunpaman, ipinakita ng karanasan na kung sa iyong proyekto:
  • Maraming programmer/team/consultant na nagtatrabaho...
  • ...sa parehong monolith sa ilalim ng presyon mula sa mga customer na may napakalabing mga kinakailangan...
  • sa loob ng ilang taon...
... pagkatapos ay sa kasong ito ang iyong maliit na bank.jar file ay nagiging isang napakalawak na gigabyte ng code lamang, na nakakatakot kahit na lapitan, pabayaan ang pag-deploy.

Paano bawasan ang laki ng isang Java monolith?

Ang isang natural na tanong ay lumitaw: kung paano gawing mas maliit ang monolith? Sa ngayon ang iyong bank.jar ay tumatakbo sa isang JVM, isang proseso sa isang server. Wala na, walang kulang. At sa ngayon ay maaaring pumasok sa isip ang isang lohikal na kaisipan: “Ngunit ang serbisyo sa pag-verify ng panganib ay maaaring gamitin ng ibang mga departamento sa aking kumpanya! Hindi ito direktang nauugnay sa aking monolithic banking application! Marahil ay dapat itong putulin sa monolith at i-deploy bilang isang hiwalay na produkto? Iyon ay, sa teknikal na pagsasalita, ang pagpapatakbo nito bilang isang hiwalay na proseso ng Java.

Ano ang Java microservice?

Sa pagsasagawa, ang pariralang ito ay nangangahulugan na ngayon ang tawag sa pamamaraan riskCheck()ay hindi gagawin mula sa BankController: ang pamamaraang ito o bahagi ng bean kasama ang lahat ng mga auxiliary na klase nito ay ililipat sa sarili nitong proyektong Maven o Gradle. Ide-deploy din ito at ilalagay sa ilalim ng version control nang hiwalay sa banking monolith. Gayunpaman, hindi ginagawa ng buong proseso ng pagkuha na ito ang iyong bagong RiskCheck module sa isang microservice per se, dahil ang kahulugan ng isang microservice ay bukas sa interpretasyon. Ito ay humahantong sa madalas na mga talakayan sa loob ng mga koponan at kumpanya.
  • Ang 5-7 klase ba sa isang proyekto ay micro o ano?
  • 100 or 1000 classes... micro pa rin?
  • Ang microservice ba ay karaniwang nauugnay sa bilang ng mga klase o hindi?
Iwanan natin ang teoretikal na pangangatwiran, at sa halip ay manatili sa mga pragmatikong pagsasaalang-alang at gawin ito:
  1. Tawagan natin ang lahat ng hiwalay na naka-deploy na serbisyo ng mga microservice, anuman ang kanilang laki o mga hangganan ng domain.
  2. Pag-isipan natin kung paano ayusin ang interservice na komunikasyon. Ang aming mga microservice ay nangangailangan ng mga paraan upang makipag-usap sa isa't isa.
Kaya, upang ibuod: dati ay mayroon kang isang proseso ng JVM, isang solidong monolith para sa pagpapatakbo ng bangko. Ngayon ay mayroon ka nang banking monolith JVM na proseso at isang hiwalay na RiskCheck microservice na tumatakbo sa loob ng sarili nitong proseso ng JVM. At ngayon, para masuri ang mga panganib, dapat tawagan ng iyong monolith ang microservice na ito. Paano ito gawin?

Paano magtatag ng komunikasyon sa pagitan ng mga microservice ng Java?

Sa pangkalahatan at sa pangkalahatan, mayroong dalawang pagpipilian - kasabay at asynchronous na komunikasyon.

Kasabay na komunikasyon: (HTTP)/REST

Karaniwan, ang naka-synchronize na komunikasyon sa pagitan ng mga microservice ay nangyayari sa pamamagitan ng HTTP at mga serbisyong tulad ng REST na nagbabalik ng XML o JSON. Siyempre, maaaring may iba pang mga opsyon - kumuha ng hindi bababa sa Google Protocol Buffers . Kung kailangan mo ng agarang tugon, mas mainam na gumamit ng REST na komunikasyon. Sa aming halimbawa, ito mismo ang kailangang gawin, dahil kinakailangan ang pag-verify ng panganib bago magbukas ng account. Kung walang risk checking, walang account. Tatalakayin natin ang mga tool sa ibaba, sa seksyong " Aling mga aklatan ang pinakamainam para sa magkakasabay na Java REST na tawag ".

Pagmemensahe - Asynchronous na Komunikasyon

Ang asynchronous na microservice na komunikasyon ay karaniwang ginagawa sa pamamagitan ng pagpapalitan ng mga mensahe sa pagpapatupad ng JMS at/o paggamit ng protocol gaya ng AMQP . Sumulat kami ng "karaniwan" dito para sa isang dahilan: sabihin nating hindi maaaring maliitin ang bilang ng mga pagsasama ng email/SMTP. Gamitin ito kapag hindi mo kailangan ng agarang tugon. Halimbawa, nag-click ang user sa button na "bumili ngayon", at ikaw naman, ay gustong bumuo ng isang invoice. Ang prosesong ito ay tiyak na hindi dapat mangyari sa loob ng ikot ng paghiling-tugon sa pagbili ng user. Sa ibaba ay ilalarawan namin kung aling mga tool ang pinakamainam para sa asynchronous na Java messaging .

Halimbawa: REST API na tawag sa Java

Sabihin nating pipiliin natin ang kasabay na microservice na komunikasyon. Sa kasong ito, ang aming Java code (ang ipinakita namin sa itaas) sa mababang antas ay magiging ganito ang hitsura. (sa pamamagitan ng mababang antas dito ang ibig naming sabihin ay ang katotohanan na para sa microservice na komunikasyon, ang mga library ng kliyente ay karaniwang nilikha na nag-abstract sa iyo mula sa aktwal na mga tawag sa 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..
    }
}
Batay sa code, nagiging malinaw na kailangan na nating mag-deploy ng dalawang serbisyo ng Java (micro), Bank at RiskCheck. Bilang resulta, magkakaroon tayo ng dalawang proseso ng JVM na tumatakbo. Isang Gabay sa Java Microservices.  Bahagi 1: Mga Pangunahing Kaalaman at Arkitektura ng Microservices - 3Iyon lang ang kailangan mo para makabuo ng proyekto ng Java microservices: bumuo lang at mag-deploy ng mas maliliit na chunks (.jar o .war file) sa halip na isang monolitik. Ang sagot sa tanong ay nananatiling hindi malinaw: paano natin dapat i-cut ang monolith sa mga microservice? Gaano dapat kaliit ang mga pirasong ito, paano matukoy ang tamang sukat? Suriin natin.

Arkitektura ng Java Microservices

Sa pagsasagawa, ang mga kumpanya ay bumuo ng mga proyekto ng microservice sa iba't ibang paraan. Ang diskarte ay depende sa kung sinusubukan mong baguhin ang isang umiiral na monolith sa isang microservices proyekto o simulan ang proyekto mula sa simula.

Mula sa monolith hanggang sa mga microservice

Ang isa sa mga pinaka-lohikal na ideya ay ang pagkuha ng mga microservice mula sa isang umiiral na monolith. Tandaan na ang prefix na "micro" dito ay hindi talaga nangangahulugan na ang mga serbisyong nakuha ay magiging tunay na maliit; ito ay hindi kinakailangan ang kaso. Tingnan natin ang theoretical background.

Ideya: hatiin ang monolith sa mga microservice

Maaaring ilapat ang isang microservice approach sa mga legacy na proyekto. At dahil jan:
  1. Kadalasan, ang mga naturang proyekto ay mahirap mapanatili/palitan/palawakin.
  2. Ang bawat tao'y, mula sa mga developer hanggang sa pamamahala, ay nais ng pagpapasimple.
  3. Mayroon kang (medyo) malinaw na mga hangganan ng domain, ibig sabihin, alam mo nang eksakto kung ano ang dapat gawin ng iyong software.
Pagbabalik sa aming halimbawa, nangangahulugan ito na maaari mong tingnan ang iyong Java banking monolith at subukang hatiin ito sa mga hangganan ng domain.
  • Kaya, makatwirang paghiwalayin ang pagproseso ng data ng user (tulad ng mga pangalan, address, numero ng telepono) sa isang hiwalay na microservice na "Account Management".
  • O ang nabanggit na "Risk Checker Module" na sumusuri sa mga antas ng panganib ng user at maaaring magamit ng marami pang proyekto o kahit na mga departamento ng kumpanya.
  • O isang module sa pag-invoice na nagpapadala ng mga invoice sa format na PDF o sa pamamagitan ng koreo.

Pagpapatupad ng isang ideya: hayaan ang ibang tao na gawin ito

Ang diskarte na inilarawan sa itaas ay mukhang mahusay sa papel at mga diagram na tulad ng UML. Gayunpaman, ang lahat ay hindi gaanong simple. Ang praktikal na pagpapatupad nito ay nangangailangan ng seryosong teknikal na paghahanda: ang agwat sa pagitan ng aming pag-unawa sa kung ano ang magandang kunin mula sa isang monolith at ang proseso ng pagkuha mismo ay napakalaki. Karamihan sa mga proyekto ng enterprise ay umabot sa isang yugto kung saan ang mga developer ay natatakot, halimbawa, i-upgrade ang isang 7 taong gulang na bersyon ng Hibernate sa isang mas bago. Ang mga aklatan ay ia-update kasama nito, ngunit may tunay na panganib na masira ang isang bagay. Kaya't ang parehong mga developer na iyon ay kailangan na ngayong maghukay sa mga sinaunang legacy code na may hindi malinaw na mga hangganan ng transaksyon sa database at kumuha ng mga mahusay na tinukoy na microservice? Mas madalas kaysa sa hindi, ang problemang ito ay napaka-kumplikado at hindi maaaring "malutas" sa isang whiteboard o sa mga pulong ng arkitektura. Isang Gabay sa Java Microservices.  Bahagi 1: Mga Pangunahing Kaalaman at Arkitektura ng Microservices - 4Upang banggitin ang Twitter developer na si @simonbrown: Sasabihin ko ito nang paulit-ulit... kung ang mga tao ay hindi makabuo ng mga monolith nang tama, ang mga microservice ay hindi makakatulong. Simon Brown

Proyekto mula sa simula batay sa arkitektura ng microservice

Para sa mga bagong proyekto ng Java, ang tatlong may bilang na mga item mula sa nakaraang bahagi ay mukhang bahagyang naiiba:
  1. Magsisimula ka sa isang malinis na slate, kaya walang "baggage" upang mapanatili.
  2. Nais ng mga developer na panatilihing simple ang mga bagay sa hinaharap.
  3. Problema: Mayroon kang mas malabong larawan ng mga hangganan ng domain: hindi mo alam kung ano talaga ang dapat gawin ng iyong software (hint: agile ;))
Ito ay humahantong sa mga kumpanyang sumusubok ng mga bagong proyekto sa Java microservices.

Teknikal na arkitektura ng microservice

Ang unang punto ay tila ang pinaka-halata para sa mga developer, ngunit mayroon ding mga malakas na hinihikayat ito. Inirerekomenda ni Hadi Hariri ang "Extract Microservice" refactoring sa IntelliJ. At kahit na ang sumusunod na halimbawa ay napaka-pinasimple, ang mga pagpapatupad na sinusunod sa mga tunay na proyekto, sa kasamaang-palad, ay hindi masyadong lumayo mula dito. Bago ang mga microservice
@Service
class UserService {

    public void register(User user) {
        String email = user.getEmail();
        String username =  email.substring(0, email.indexOf("@"));
        // ...
    }
}
Sa substring Java microservice
@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());
        // ...
    }
}
Kaya mahalagang binabalot mo ang isang Java method na tawag sa isang HTTP na tawag, nang walang malinaw na dahilan para gawin ito. Ang isa sa mga dahilan, gayunpaman, ay ito: kakulangan ng karanasan at sinusubukang pilitin ang isang Java microservices approach. Rekomendasyon: Huwag gawin ito.

Ang arkitektura ng microservice na nakatuon sa daloy ng trabaho

Ang susunod na karaniwang diskarte ay ang hatiin ang mga microservice ng Java sa mga module na nakabatay sa daloy ng trabaho. Halimbawa sa totoong buhay: Sa Germany, kapag pumunta ka sa isang (pampublikong) doktor, dapat niyang itala ang iyong pagbisita sa kanyang medikal na CRM system. Upang makakuha ng bayad mula sa insurance, magpapadala siya ng data tungkol sa iyong paggamot (at ang paggamot ng iba pang mga pasyente) sa tagapamagitan sa pamamagitan ng XML. Titingnan ng broker ang XML file na ito at (pinasimple):
  1. Susuriin kung ang tamang XML file ay natanggap.
  2. Susuriin nito ang pagiging totoo ng mga pamamaraan: sabihin, ang isang taong gulang na bata na nakatanggap ng tatlong mga pamamaraan sa paglilinis ng ngipin sa isang araw mula sa isang gynecologist ay mukhang medyo kahina-hinala.
  3. Pagsasamahin ang XML sa ilang iba pang bureaucratic data.
  4. Ipapasa ang XML file sa kompanya ng seguro upang simulan ang mga pagbabayad.
  5. At ipapadala nito ang resulta sa doktor, na magbibigay sa kanya ng mensaheng "tagumpay" o "mangyaring muling ipadala ang recording na ito sa sandaling ito ay makatuwiran."
Tandaan. Sa halimbawang ito, ang komunikasyon sa pagitan ng mga microservice ay hindi gumaganap ng isang papel, ngunit maaaring maisagawa nang asynchronous ng isang broker ng mensahe (hal. RabbitMQ), dahil ang doktor ay hindi pa rin nakakatanggap ng agarang feedback. Isang Gabay sa Java Microservices.  Bahagi 1: Mga Pangunahing Kaalaman at Arkitektura ng Microservices - 5Muli, ito ay mukhang mahusay sa papel, ngunit natural na mga tanong ang lumitaw:
  • Kailangan bang mag-deploy ng anim na application para maproseso ang isang XML file?
  • Tunay bang independyente ang mga microservice na ito sa isa't isa? Maaari ba silang i-deploy nang hiwalay sa isa't isa? Sa iba't ibang bersyon at API scheme?
  • Ano ang ginagawa ng microservice ng kredibilidad kung hindi gumana ang microservice ng pag-verify? Gumagana pa ba ang sistema?
  • Ang mga microservice ba ay nagbabahagi ng parehong database (tiyak na kailangan nila ng ilang karaniwang data sa mga talahanayan ng DB), o mayroon ba silang kanya-kanyang sarili?
  • … at marami pang iba.
Kapansin-pansin, ang diagram sa itaas ay mukhang mas simple dahil ang bawat serbisyo ay mayroon na ngayong sarili nitong tumpak, mahusay na tinukoy na layunin. Dati ay parang ganito itong nakakatakot na monolith: Isang Gabay sa Java Microservices.  Bahagi 1: Mga Pangunahing Kaalaman at Arkitektura ng Microservices - 6Bagama't maaari kang magtaltalan tungkol sa pagiging simple ng mga diagram na ito, tiyak na kailangan mo na ngayong lutasin ang mga karagdagang hamon sa pagpapatakbo.
  • Hindi mo lang kailangan na mag-deploy ng isang application, ngunit hindi bababa sa anim.
  • Maaaring kailanganin mong mag-deploy ng maramihang mga database, depende sa kung gaano kalayo ang gusto mong puntahan sa arkitektura ng microservices.
  • Kailangan mong tiyakin na ang bawat system ay online at gumagana nang maayos.
  • Kailangan mong tiyakin na ang iyong mga tawag sa pagitan ng mga microservice ay tunay na nababanat (tingnan ang Paano gumawa ng isang Java microservice na nababanat?).
  • At lahat ng iba pa na ipinahihiwatig ng setup na ito - mula sa mga lokal na setting ng pag-unlad hanggang sa pagsubok sa pagsasama.
Kaya ang rekomendasyon ay:
  • Kung hindi ka Netflix (malamang, hindi ka Netflix)...
  • Maliban na lang kung mayroon kang napakalakas na kasanayan sa trabaho kung saan bubuksan mo ang development environment at nagdudulot ito ng kaguluhang unggoy na nagtatapon sa iyong database ng produksyon na madaling maibabalik sa loob ng 5 segundo.
  • o para kang @monzo at handang sumubok ng 1500 microservice dahil lang kaya mo.
→ Huwag gawin ito. At ngayon ito ay hindi gaanong hyperbolic. Ang pagsisikap na magmodelo ng mga microservice sa mga hangganan ng domain ay tila makatwiran. Ngunit hindi ito nangangahulugan na kailangan mong kumuha ng isang daloy ng trabaho at hatiin ito sa maliliit na indibidwal na bahagi (tumanggap ng XML, patunayan ang XML, pasulong na XML). Kaya naman, sa tuwing magsisimula ka ng bagong proyekto sa Java microservices at ang mga hangganan ng domain ay malabo pa rin, subukang panatilihing mababa ang laki ng iyong mga microservice. Maaari kang magdagdag ng higit pang mga module anumang oras sa ibang pagkakataon. At tiyaking mayroon kang mga advanced na DevOps sa team/kumpanya/dibisyon para suportahan ang iyong bagong imprastraktura.

Polyglot o arkitektura ng microservice na nakatuon sa koponan

Mayroong isang pangatlo, halos libertarian, na diskarte sa pagbuo ng mga microservice: nagpapahintulot sa mga koponan o kahit na mga indibidwal na ipatupad ang mga kwento ng gumagamit gamit ang anumang bilang ng mga wika o microservice (tinatawag ng mga marketer ang diskarte na ito na "polyglot programming"). Kaya, ang XML validation service na inilarawan sa itaas ay maaaring isulat sa Java, habang ang validation microservice sa parehong oras ay maaaring isulat sa Haskell (upang gawin itong mathematically sound). Para sa microservice ng pagpapasa ng insurance, maaari mong gamitin ang Erlang (dahil kailangan talaga itong sukat ;)). Ang maaaring mukhang masaya mula sa pananaw ng isang developer (pagbuo ng perpektong sistema gamit ang iyong perpektong wika sa isang nakahiwalay na kapaligiran) ay, sa katunayan, hindi kailanman kung ano ang gusto ng organisasyon: homogenization at standardization. Nangangahulugan ito ng medyo standardized na hanay ng mga wika, aklatan, at tool para patuloy na suportahan ng ibang mga developer ang iyong Haskell microservice sa hinaharap kapag lumipat ka sa mas luntiang pastulan. Isang Gabay sa Java Microservices.  Bahagi 1: Mga Pangunahing Kaalaman at Arkitektura ng Microservices - 8Ipinakikita ng kasaysayan na kadalasang nagiging masyadong malalim ang pagkakaugat ng standardisasyon. Halimbawa, minsan hindi pinapayagan ang mga developer sa malalaking kumpanya ng Fortune 500 na gamitin ang Spring dahil ito ay "hindi bahagi ng roadmap ng teknolohiya ng kumpanya." Gayunpaman, ang isang kumpletong paglipat sa diskarte sa polyglot ay halos pareho, ang kabilang panig ng parehong barya. Rekomendasyon: Kung gagamit ka ng polyglot programming, subukan ang mas kaunting pagkakaiba-iba sa loob ng parehong ecosystem ng programming language. Kaya, mas mahusay na gamitin ang Kotlin at Java nang magkasama (ang parehong mga wika ay batay sa JVM at 100% tugma sa isa't isa), kaysa sa Java at, sabihin nating, Haskell. Sa susunod na bahagi, matututunan mo ang tungkol sa pag-deploy at pagsubok ng mga microservice ng Java.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION