Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Artikulu honetan, lantzen ari naizen proiektua monolito handi batetik mikrozerbitzu multzo izatera nola eraldatu den hitz egingo dut.

Proiektua aspaldi hasi zen bere historia, 2000. urtearen hasieran. Lehen bertsioak Visual Basic 6-n idatzi ziren. Denborarekin, argi geratu zen hizkuntza honen garapena zaila izango zela aurrerantzean onartzea, IDEa geroztik. eta hizkuntza bera gutxi garatuta dago. 2000ko hamarkadaren amaieran, etorkizun handiko C#ra aldatzea erabaki zen. Bertsio berria zaharraren berrikuspenarekin paraleloan idatzi zen, pixkanaka gero eta kode gehiago idatzi zen .NET-en. C#-n backend hasiera batean zerbitzu-arkitektura batean zentratu zen, baina garapenean zehar, logikadun liburutegi arruntak erabili ziren eta zerbitzuak prozesu bakarrean abiarazi ziren. Emaitza "zerbitzuaren monolito" deitu genion aplikazio bat izan zen.

Konbinazio honen abantail bakanetako bat zerbitzuek kanpoko API baten bidez elkarri deitzeko gaitasuna izan zen. Zerbitzu zuzenago batera igarotzeko aurrebaldintza argiak zeuden, eta etorkizunean, mikrozerbitzuen arkitektura.

2015 inguruan hasi ginen deskonposizioaren inguruko lana. Oraindik ez gara egoera ideal batera iritsi - oraindik ere proiektu handi baten zatiak daude nekez deitu daitezkeenak monolitoak, baina ez dute mikrozerbitzuen itxurarik ere. Hala ere, aurrerapena nabarmena da.
Artikuluan horri buruz hitz egingo dut.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Edukia

Arkitektura eta lehendik dagoen irtenbidearen arazoak


Hasieran, arkitekturak honela zeukan: UI aplikazio bereizia da, zati monolitikoa Visual Basic 6-n idatzita dago, .NET aplikazioa datu-base handi samarrarekin lan egiten duten erlazionatutako zerbitzu multzo bat da.

Aurreko irtenbidearen desabantailak

Porrot puntu bakarra
Huts-puntu bakarra izan genuen: .NET aplikazioa prozesu bakarrean exekutatu zen. Moduluren batek huts egiten bazuen, aplikazio osoa huts egin zuen eta berrabiarazi behar izan zen. Erabiltzaile ezberdinentzako prozesu ugari automatizatzen ditugunez, horietako batean hutsegite batengatik, denek ezin izan dute denbora pixka bat funtzionatu. Eta software-akatsen bat izanez gero, babeskopiak ere ez zuen lagundu.

Hobekuntza-ilara
Eragozpen hau antolakuntzazkoa da. Gure aplikazioak bezero asko ditu, eta guztiek hobetu nahi dute lehenbailehen. Aurretik, ezinezkoa zen paraleloan egitea, eta bezero guztiak ilaran zeuden. Prozesu hori negatiboa izan zen enpresentzat, euren zeregina baliotsua zela frogatu behar zutelako. Eta garapen taldeak denbora eman zuen ilara hau antolatzen. Honek denbora eta esfortzu handia behar zuen, eta produktua, azken finean, ezin zen aldatu nahi bezain azkar.

Baliabideen erabilera desegokia
Zerbitzuak prozesu bakarrean ostatzerakoan, beti konfigurazioa guztiz kopiatzen dugu zerbitzaritik zerbitzarira. Gehien kargatutako zerbitzuak bereiz jarri nahi genituen, baliabideak ez xahutzeko eta gure hedapen-eskemaren gaineko kontrol malguagoa lortzeko.

Teknologia modernoak ezartzea zaila
Garatzaile guztientzat ezaguna den arazoa: teknologia modernoak proiektuan sartzeko nahia dago, baina ez dago aukerarik. Irtenbide monolitiko handi batekin, egungo liburutegiaren edozein eguneraketa, berri baterako trantsizioa ahaztu gabe, zeregin ez-huts samarra bihurtzen da. Denbora luzea behar da taldeburuari frogatzeko horrek alferrik galdutako nerbioak baino hobari gehiago ekarriko dituela.

Aldaketak emateko zailtasuna
Hau izan zen arazo larriena: bi hilabetez behin kaleratzen genituen.
Argitalpen bakoitza benetako hondamendia bihurtu zen bankuarentzat, garatzaileek probak eta ahaleginak egin arren. Enpresak ulertu zuen aste hasieran bere funtzionalitate batzuk ez zirela funtzionatuko. Eta garatzaileek ulertu zuten aste bat istilu larrien zain zegoela.
Denek zuten egoera aldatzeko gogoa.

Mikrozerbitzuetatik itxaropenak


Osagaien jaulkipena prest dagoenean. Osagaiak prest daudenean entregatzea, disoluzioa deskonposatuz eta prozesu desberdinak bereiziz.

Produktu talde txikiak. Hau garrantzitsua da monolito zaharrean lan egiten zuen talde handi bat kudeatzea zaila zelako. Halako talde bat prozesu zorrotz baten arabera lan egitera behartuta zegoen, baina sormen eta independentzia gehiago nahi zuten. Talde txikiek baino ezin zuten hori ordaindu.

Zerbitzuen isolamendua prozesu bereizietan. Egokiena, edukiontzietan isolatu nahi nuen, baina .NET Framework-en idatzitako zerbitzu ugari Windows-en bakarrik exekutatzen dira. .NET Core-n oinarritutako zerbitzuak agertzen ari dira orain, baina oraindik gutxi daude.

Hedapen-malgutasuna. Zerbitzuak behar dugun moduan konbinatu nahiko genituzke, eta ez kodeak behartzen duen moduan.

Teknologia berrien erabilera. Hau edozein programatzailerentzat interesgarria da.

Trantsizio arazoak


Noski, monolito bat mikrozerbitzuetan apurtzea erraza balitz, ez litzateke kongresuetan horri buruz hitz egin eta artikuluak idatzi beharrik izango. Prozesu honetan akats asko daude; oztopatu gaituzten nagusiak deskribatuko ditut.

Lehen arazoa monolito gehienentzat tipikoa: negozio-logikaren koherentzia. Monolito bat idazten dugunean, gure klaseak berrerabili nahi ditugu, beharrezkoa ez den kodea ez idazteko. Eta mikrozerbitzuetara pasatzean, hori arazo bihurtzen da: kode guztia nahiko estu lotuta dago, eta zaila da zerbitzuak bereiztea.

Lanak hasi zirenean, biltegiak 500 proiektu baino gehiago eta 700 mila kode lerro baino gehiago zituen. Hau nahiko erabaki handia da eta bigarren arazoa. Ezin izan zen hartu eta mikrozerbitzuetan banatzea besterik gabe.

Hirugarren arazoa β€” Beharrezko azpiegitura falta. Izan ere, eskuz iturburu-kodea zerbitzarietan kopiatzen ari ginen.

Nola pasa monolitotik mikrozerbitzuetara


Mikrozerbitzuak hornitzea

Lehenik eta behin, berehala zehaztu genuen mikrozerbitzuen bereizketa prozesu iteratibo bat dela. Negozio-arazoak paraleloan garatzea eskatzen genuen beti. Hori teknikoki nola inplementatuko dugun dagoeneko gure arazoa da. Horregatik, prozesu iteratibo baterako prestatu dugu. Ez du beste modu batera funtzionatuko aplikazio handi bat baduzu eta hasiera batean berriro idazteko prest ez badago.

Zein metodo erabiltzen ditugu mikrozerbitzuak isolatzeko?

Lehenengo bidea β€” lehendik dauden moduluak zerbitzu gisa mugitu. Zentzu honetan, zortea izan dugu: dagoeneko erregistratuta zeuden zerbitzuak WCF protokoloa erabiliz funtzionatzen zutenak. Batzar bereizietan banatu ziren. Bereiz eraman ditugu, abiarazle txiki bat gehituz eraikuntza bakoitzean. Topshelf liburutegi zoragarria erabiliz idatzi zen, aplikazioa zerbitzu gisa zein kontsola gisa exekutatzeko aukera ematen duena. Hau komenigarria da arazketarako, ez baita proiektu gehigarririk behar soluzioan.

Zerbitzuak negozio-logikaren arabera konektatzen ziren, asanblada komunak erabiltzen baitzituzten eta datu-base komun batekin lan egiten zutelako. Nekez deitu litezke mikrozerbitzu hutsean. Hala ere, zerbitzu hauek bereizita eman genitzake, prozesu ezberdinetan. Honek bakarrik ahalbidetu zuen elkarrengan duten eragina murriztea, garapen paraleloarekin eta porrot puntu bakar batekin arazoa murriztuz.

Ostalariarekin muntatzea Programa klaseko kode lerro bat besterik ez da. Topshelf-ekin lana ezkutatu dugu klase laguntzaile batean.

namespace RBA.Services.Accounts.Host
{
   internal class Program
   {
      private static void Main(string[] args)
      {
        HostRunner<Accounts>.Run("RBA.Services.Accounts.Host");

       }
    }
}

Mikrozerbitzuak esleitzeko bigarren modua hau da: sortu itzazu arazo berriak konpontzeko. Aldi berean monolitoa hazten ez bada, hau bikaina da jada, eta horrek esan nahi du norabide egokian goazela. Arazo berriak konpontzeko, zerbitzu bereiziak sortzen saiatu gara. Aukera hori bazegoen, orduan beren datu-eredua guztiz kudeatzen duten zerbitzu "kanoniko" gehiago sortu genituen, datu-base bereizia.

Gu, asko bezala, autentifikazio eta baimen zerbitzuekin hasi ginen. Horretarako ezin hobeak dira. Independenteak dira, oro har, datu-eredu bereizia dute. Beraiek ez dute monolitoarekin elkarreragiten, haiengana jotzen dute arazo batzuk konpontzeko. Zerbitzu hauek erabiliz, arkitektura berri baterako trantsizioa has zaitezke, azpiegitura arazketa, sareko liburutegiekin lotutako zenbait ikuspegi probatu, etab. Gure erakundean ez dugu autentifikazio-zerbitzurik sortu ezin duten talderik.

Mikrozerbitzuak esleitzeko hirugarren moduaErabiltzen duguna apur bat espezifikoa da guretzat. Hau da negozio-logika IU geruzatik kentzea. Gure UI aplikazio nagusia mahaigaina da; backend-a bezala, C#-n idatzita dago. Garatzaileek aldian-aldian akatsak egiten zituzten eta backend-ean egon beharko luketen eta berrerabili behar ziren UI-ra transferitu zituzten logika zatiak.

UI zatiaren kodearen adibide erreal bati erreparatzen badiozu, ikus dezakezu soluzio honen gehienek negozio-logika erreala duela beste prozesu batzuetan erabilgarria dena, ez bakarrik UI inprimakia eraikitzeko.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Benetako UI logika azken lerroetan bakarrik dago. Zerbitzarira transferitu genuen berrerabili ahal izateko, eta horrela UI murriztuz eta arkitektura zuzena lortuz.

Mikrozerbitzuak isolatzeko laugarren eta garrantzitsuena, monolitoa murriztea posible egiten duena, prozesatzeko dauden zerbitzuak kentzea da. Dauden moduluak dauden moduan ateratzen ditugunean, emaitza ez da beti garatzaileen gustukoa izaten, eta baliteke negozio-prozesua zaharkituta egotea funtzionaltasuna sortu zenetik. Refactoring-arekin, negozio-prozesu berri bat onartzen dugu, negozio-eskakizunak etengabe aldatzen ari direlako. Iturburu-kodea hobetu dezakegu, ezagutzen diren akatsak kendu eta datu-eredu hobea sortu. Onura asko sortzen dira.

Zerbitzuak prozesamendutik bereiztea testuinguru mugatuaren kontzeptuari ezinbestean lotuta dago. Hau Domain Driven Design-eko kontzeptu bat da. Hizkuntza bakarreko termino guztiak modu berezian definitzen diren domeinu ereduaren atal bat esan nahi du. Ikus dezagun adibide gisa aseguruaren eta fakturen testuingurua. Aplikazio monolitikoa dugu, eta aseguruetan kontuarekin lan egin behar dugu. Garatzaileak lehendik dagoen Kontu klase bat beste asanblada batean aurkitzea espero dugu, Aseguru klasetik erreferentzia egin eta lan kodea izango dugu. DRY printzipioa errespetatuko da, zeregina azkarrago egingo da lehendik dagoen kodea erabiliz.

Ondorioz, kontuen eta aseguruen testuinguruak lotuta daude. Baldintza berriak agertzen diren heinean, akoplamendu honek garapena oztopatuko du, dagoeneko konplexua den negozio-logika konplexua areagotuz. Arazo hau konpontzeko, testuinguruen arteko mugak aurkitu behar dituzu kodean eta haien urraketak kendu. Esate baterako, aseguru-testuinguruan, oso posiblea da 20 zifrako Banku Zentraleko kontu-zenbakia eta kontua ireki zen data nahikoa izatea.

Testuinguru mugatu hauek elkarrengandik bereizteko eta mikrozerbitzuak soluzio monolitiko batetik bereizteko prozesua hasteko, aplikazioaren barruan kanpoko APIak sortzea bezalako ikuspegi bat erabili dugu. Moduluren bat mikrozerbitzu bihurtu behar dela bagenekien, prozesu barruan nolabait aldatuta, berehala deiak egiten genituen beste testuinguru mugatu bati dagokion logikara kanpoko deien bidez. Adibidez, REST edo WCF bidez.

Irmo erabaki genuen ez genuela saihestuko transakzio banatuak beharko lituzkeen kodea. Gure kasuan, nahiko erraza izan da arau hau jarraitzea. Oraindik ez dugu aurkitu banatutako transakzio zorrotzak benetan beharrezkoak diren egoerak - moduluen arteko azken koherentzia nahikoa da.

Ikus dezagun adibide zehatz bat. Orkestratzaile kontzeptua dugu: "aplikazioaren" entitatea prozesatzen duen kanalizazioa. Bezero bat, kontu bat eta banku-txartel bat sortzen ditu txandaka. Bezeroa eta kontua behar bezala sortzen badira, baina txartela sortzeak huts egiten badu, aplikazioa ez da "arrakastatsua" egoerara mugitzen eta "txartela sortu gabe" egoeran geratzen da. Etorkizunean, atzeko jarduerak jaso eta amaituko du. Aspalditik sistema inkoherentean egon da, baina, oro har, pozik gaude honekin.

Datuen zati bat koherentziaz gordetzea beharrezkoa denean egoeraren bat sortzen bada, ziurrenik zerbitzua sendotzera joko dugu prozesu batean prozesatzeko.

Ikus dezagun mikrozerbitzu bat esleitzeko adibide bat. Nola eraman dezakezu ekoizpenera nahiko seguru? Adibide honetan, sistemaren zati bereizi bat dugu: nomina-zerbitzuaren modulua, mikrozerbitzua egin nahiko genukeen kode-ataletako bat.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Lehenik eta behin, mikrozerbitzu bat sortzen dugu kodea berridatziz. Pozik ez geunden alderdi batzuk hobetzen ari gara. Bezeroaren negozio-eskakizun berriak ezartzen ditugu. API Gateway bat gehitzen dugu UI eta backendaren arteko konexioari, eta horrek deiak desbideratzeko aukera emango du.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Ondoren, konfigurazio hau martxan jartzen dugu, baina egoera pilotu batean. Gure erabiltzaile gehienek negozio-prozesu zaharrekin lan egiten dute oraindik. Erabiltzaile berrientzat, prozesu hori jada ez duen aplikazio monolitikoaren bertsio berri bat garatzen ari gara. Funtsean, pilotu gisa lan egiten duen monolito baten eta mikrozerbitzu baten konbinazioa dugu.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Pilotu arrakastatsu batekin, konfigurazio berria benetan egingarria dela ulertzen dugu, monolito zaharra kendu dezakegu ekuaziotik eta konfigurazio berria soluzio zaharraren lekuan utzi.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Guztira, dauden ia metodo guztiak erabiltzen ditugu monolito baten iturburu-kodea banatzeko. Horiek guztiek aukera ematen digute aplikazioaren zatien tamaina murrizteko eta liburutegi berrietara itzultzeko, iturburu-kode hobea eginez.

Datu-basearekin lan egitea


Datu-basea iturburu-kodea baino okerrago bana daiteke, egungo eskema ez ezik, metatutako datu historikoak ere baititu.

Gure datu-baseak, beste askok bezala, beste eragozpen garrantzitsu bat zuen: bere tamaina itzela. Datu-base hau monolito baten negozio-logika korapilatsuaren eta hainbat testuinguru mugatuen taulen artean metatutako harremanen arabera diseinatu zen.

Gure kasuan, arazo guztiak gainditzeko (datu-base handia, konexio asko, batzuetan taulen arteko mugak argitu gabe), proiektu handi askotan gertatzen den arazo bat sortu zen: partekatutako datu-base txantiloiaren erabilera. Datuak tauletatik atera ziren bistaren bidez, erreplikazioaren bidez, eta erreplikazio hori behar zen beste sistemetara bidaltzen ziren. Ondorioz, ezin izan ditugu taulak eskema bereizi batera eraman, aktiboki erabiltzen zirelako.

Kodeko testuinguru mugatuetan zatiketa berdinak bereizten laguntzen digu. Normalean datu-base mailan datuak nola banatzen ditugun jakiteko ideia ona ematen digu. Ulertzen dugu zein taula dagozkion testuinguru mugatu bati eta zein besteari.

Datu-baseak banatzeko bi metodo global erabili ditugu: lehendik dauden taulen partizioa eta prozesatzeko partizioa.

Lehendik dauden taulak banatzea metodo ona da datuen egitura ona bada, negozio-eskakizunak betetzen baditu eta denak pozik daude. Kasu honetan, lehendik dauden taulak eskema bereizi batean bereiz ditzakegu.

Tramitazioa duen sail bat behar da negozio eredua asko aldatu denean, eta taulak ez gaituzte batere asetzen.

Lehendik dauden taulak zatitzea. Zer bereiziko dugun zehaztu behar dugu. Ezagutza hori gabe, ezerk ez du funtzionatuko, eta hemen kodean mugatutako testuinguruak bereizteak lagunduko digu. Oro har, iturburu-kodean testuinguruen mugak ulertzen badituzu, argi geratzen da zein taula sartu behar diren saileko zerrendan.

Imajina dezagun soluzio bat dugula bi modulu monolito datu-base batekin elkarreragiten. Ziurtatu behar dugu modulu bakarrak elkarreragiten duela bereizitako taulen atalarekin, eta bestea APIaren bidez harekin elkarreragiten hasten dela. Hasteko, nahikoa da APIaren bidez grabaketa soilik egitea. Hau ezinbesteko baldintza da mikrozerbitzuen independentziaz hitz egiteko. Irakurtzeko konexioak egon daitezke arazo handirik ez dagoen bitartean.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Hurrengo urratsa da bereizitako taulekin lan egiten duen kodearen atala, prozesatuarekin edo gabe, mikrozerbitzu bereizi batean bereizi eta prozesu bereizi batean exekutatu dezakegula, edukiontzi batean. Zerbitzu bereizia izango da monolitoaren datu-basearekin eta zuzenean erlazionatuta ez dauden taula horiekin. Monolitoak oraindik ere elkarreragin egiten du irakurtzeko zati desmuntagarriarekin.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Geroago konexio hori kenduko dugu, hau da, bereizitako tauletatik aplikazio monolitiko bateko datuak irakurtzea ere APIra transferituko da.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Ondoren, datu-base orokorretik mikrozerbitzu berriak bakarrik funtzionatzen duten taulak hautatuko ditugu. Taulak eskema berezi batera eraman ditzakegu edo baita datu-base fisiko berezi batera ere. Oraindik irakurketa-konexio bat dago mikrozerbitzuaren eta monolito datu-basearen artean, baina ez dago ezer kezkatu, konfigurazio honetan denbora luzez bizi daiteke.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Azken urratsa konexio guztiak guztiz kentzea da. Kasu honetan, baliteke datu-base nagusitik datuak migratu behar izatea. Batzuetan, kanpoko sistemetatik errepikatutako datu edo direktorio batzuk berrerabili nahi ditugu hainbat datu-basetan. Hau aldian-aldian gertatzen zaigu.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Prozesatzeko saila. Metodo hau lehenengoaren oso antzekoa da, alderantzizko ordenan bakarrik. Berehala esleitzen ditugu datu-base berri bat eta API baten bidez monolitoarekin elkarreragiten duen mikrozerbitzu berri bat. Baina, aldi berean, etorkizunean ezabatu nahi ditugun datu-base-taulen multzo bat geratzen da. Jada ez dugu behar; eredu berrian ordezkatu dugu.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Eskema honek funtziona dezan, trantsizio aldi bat beharko dugu ziurrenik.

Orduan, bi planteamendu posible daude.

Lehenengoa: datu guztiak bikoizten ditugu datu-base berrietan eta zaharrean. Kasu honetan, datuen erredundantzia dugu eta sinkronizazio arazoak sor daitezke. Baina bi bezero ezberdin har ditzakegu. Batek bertsio berriarekin funtzionatuko du, besteak zaharrarekin.

Bigarren: datuak negozio irizpide batzuen arabera banatzen ditugu. Adibidez, sisteman 5 produktu genituen datu-base zaharrean gordeta. Seigarrena enpresa-zeregin berriaren barruan kokatzen dugu datu-base berri batean. Baina datu horiek sinkronizatuko dituen eta bezeroari nondik eta zertatik atera behar duen erakutsiko duen API Gateway bat beharko dugu.

Bi ikuspegiak funtzionatzen dute, egoeraren arabera aukeratu.

Dena funtzionatzen duela ziur egon ondoren, datu-base zaharren egiturekin lan egiten duen monolitoaren zatia desgaitu daiteke.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Azken urratsa datu-egitura zaharrak kentzea da.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Laburbilduz, datu-basearekin arazoak ditugula esan dezakegu: zaila da iturburu-kodearekin konparatuta lan egitea, zailagoa da partekatzea, baina egin daiteke eta egin behar da. Hori nahiko seguru egiteko aukera ematen diguten modu batzuk aurkitu ditugu, baina oraindik errazagoa da datuekin akatsak egitea iturburu-kodearekin baino.

Iturburu kodearekin lan egitea


Hau da iturburu-kodearen diagramak proiektu monolitikoa aztertzen hasi ginenean.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Gutxi gorabehera hiru geruzatan bana daiteke. Abiarazitako moduluen, pluginen, zerbitzuen eta banakako jardueren geruza bat da. Izan ere, soluzio monolitiko baten barneko sarrera puntuak ziren. Horiek guztiak ondo itxita zeuden geruza Komun batekin. Zerbitzuek partekatzen zuten negozio logika eta konexio asko zituen. Zerbitzu eta plugin bakoitzak 10 batzar arrunt edo gehiago erabiltzen zituen, haien tamainaren eta garatzaileen kontzientziaren arabera.

Bereiz erabil zitezkeen azpiegitura liburutegiak izan genituen zortea.

Batzuetan, ohiko objektu batzuk geruza horretakoak ez zirenean, azpiegitura liburutegiak zirenean sortzen zen. Hau izena aldatuz konpondu zen.

Kezkarik handiena testuinguru mugatuak ziren. Gertatu zen 3-4 testuinguru batzar komun batean nahasten zirela eta elkarren artean erabiltzen ziren negozio-funtzio berdinen barruan. Beharrezkoa zen ulertzea non banatu zitekeen eta zein mugetan, eta zer egin hurrengo zatiketa hori iturburu-kodeen muntaketetan mapatzearekin.

Kodea banatzeko prozesurako hainbat arau formulatu ditugu.

Lehenengo eta behin,: Jada ez genuen negozio-logika partekatu nahi zerbitzu, jardueren eta pluginen artean. Negozio-logika independentea egin nahi genuen mikrozerbitzuen barruan. Mikrozerbitzuak, berriz, guztiz independentean dauden zerbitzu gisa pentsatuta daude. Uste dut planteamendu hau xahutzailea dela, eta zaila dela lortzea, izan ere, adibidez, C#-ko zerbitzuak edozein kasutan liburutegi estandar baten bidez konektatuko dira. Gure sistema C#-n idatzita dago; oraindik ez dugu beste teknologiarik erabili. Hori dela eta, ohiko muntaia teknikoak erabiltzeko aukera genuela erabaki genuen. Gauza nagusia da ez dutela negozio-logika zatirik. Erabiltzen ari zaren ORMaren gainean erosotasun-bilgarri bat baduzu, zerbitzutik zerbitzura kopiatzea oso garestia da.

Gure taldea domeinuak gidatutako diseinuaren zalea da, beraz, tipula arkitektura oso egokia zen guretzat. Gure zerbitzuen oinarria ez da datuetarako sarbidearen geruza, domeinu-logika duen muntaia bat baizik, negozio-logika soilik daukana eta azpiegiturarekin loturarik ez duena. Aldi berean, domeinuaren muntaia modu independentean alda dezakegu, esparruekin lotutako arazoak konpontzeko.

Etapa honetan gure lehen arazo larria topatu genuen. Zerbitzuak domeinu-multzo bati erreferentzia egin behar zion, logika independentea egin nahi genuen eta DRY printzipioak asko oztopatu gintuen hemen. Garatzaileek ondoko asanbladetako klaseak berrerabili nahi zituzten bikoizketak saihesteko, eta, ondorioz, domeinuak elkarrekin lotzen hasi ziren berriro. Emaitzak aztertu eta arazoa iturburu-kodea biltegiratzeko gailuaren eremuan ere badagoela erabaki genuen. Iturburu-kode guztia biltzen zuen biltegi handi bat genuen. Proiektu osoaren irtenbidea oso zaila zen tokiko makina batean muntatzea. Hori dela eta, proiektuaren zatietarako soluzio txiki bereiziak sortu ziren, eta inork ez zuen debekatu komun edo domeinuen muntaia batzuk gehitzea eta berrerabiltzea. Hau egiten uzten ez zigun tresna bakarra kodea berrikustea izan zen. Baina batzuetan porrot ere egin zuen.

Ondoren, biltegi bereiziekin eredu batera pasatzen hasi ginen. Negozio-logika jada ez da zerbitzutik zerbitzura doa, domeinuak benetan independente bihurtu dira. Testuinguru mugatuak argiago onartzen dira. Nola berrerabiltzen ditugu azpiegitura liburutegiak? Bereizi biltegi batean bereizi genituen, gero Nuget paketeetan sartu, eta horiek Artifactory-n sartu genituen. Edozein aldaketarekin, muntaia eta argitalpena automatikoki gertatzen dira.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Gure zerbitzuak barne azpiegitura paketeei erreferentzia egiten hasi ziren kanpokoen modu berean. Nuget-etik kanpoko liburutegiak deskargatzen ditugu. Artifactory-rekin lan egiteko, non pakete hauek jarri genituen, bi pakete kudeatzaile erabili genituen. Biltegi txikietan Nuget ere erabili dugu. Zerbitzu anitz dituzten biltegietan, Paket erabili dugu, zeinak moduluen arteko bertsio koherentzia handiagoa eskaintzen du.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Horrela, iturburu-kodea landuz, arkitektura apur bat aldatuz eta biltegiak bereiziz, gure zerbitzuak independenteagoak egiten ditugu.

Azpiegitura arazoak


Mikrozerbitzuetara pasatzearen alde txar gehienak azpiegituren ingurukoak dira. Inplementazio automatizatua beharko duzu, liburutegi berriak beharko dituzu azpiegitura exekutatzeko.

Eskuzko instalazioa inguruneetan

Hasieran, inguruneetarako irtenbidea eskuz instalatu genuen. Prozesu hau automatizatzeko, CI/CD kanalizazio bat sortu dugu. Etengabeko entrega-prozesua aukeratu dugu, etengabeko hedapena oraindik ez delako onargarria guretzat negozio-prozesuen ikuspuntutik. Hori dela eta, funtzionatzeko bidalketa botoi baten bidez egiten da, eta probak egiteko - automatikoki.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Atlassian, Bitbucket erabiltzen ditugu iturburu kodea biltegiratzeko eta Bamboo eraikuntzarako. Cake-n eraikitzeko gidoiak idaztea gustatzen zaigu C#-ren berdina delako. Prest egindako paketeak Artifactory-ra iristen dira, eta Ansible automatikoki probako zerbitzarietara iristen da, ondoren berehala probatu ahal izateko.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Bereizi erregistroa


Garai batean, monolitoaren ideietako bat erregistro partekatua ematea zen. Diskoetan dauden erregistro indibidualekin zer egin ere ulertu behar genuen. Gure erregistroak testu fitxategietan idazten dira. ELK pila estandarra erabiltzea erabaki genuen. Hornitzaileen bidez ez genion ELKri zuzenean idatzi, baina erabaki genuen testu-erregistroak aldatuko genituzkeela eta haietan traza IDa idatziko genuela identifikatzaile gisa, zerbitzuaren izena gehituz, gero erregistro horiek analizatu ahal izateko.

Monolitotik mikrozerbitzuetarako trantsizioa: historia eta praktika

Filebeat erabiliz, gure erregistroak zerbitzarietatik biltzeko aukera dugu, gero eraldatzeko, Kibana erabili Interfaze Interfazeko kontsultak sortzeko eta deia zerbitzuen artean nola joan den ikusteko. Trace ID asko laguntzen du honekin.

Proba eta arazketa lotutako zerbitzuak


Hasieran, ez genuen guztiz ulertzen garatzen ari ziren zerbitzuak nola arazketa egin. Monolitoarekin dena sinplea zen; tokiko makina batean exekutatu genuen. Hasieran mikrozerbitzuekin gauza bera egiten saiatzen ziren, baina batzuetan mikrozerbitzu bat guztiz abiarazteko beste hainbat abiarazi behar dituzu, eta hori deserosoa da. Konturatu ginen eredu batera pasatu behar dugula, non tokiko makinan arakatu nahi ditugun zerbitzu edo zerbitzuak soilik uzten ditugun. Gainerako zerbitzuak prod-ekin konfigurazioarekin bat datozen zerbitzarietatik erabiltzen dira. Araztu ondoren, probak zehar, zeregin bakoitzerako, aldatutako zerbitzuak soilik igortzen zaizkio probako zerbitzariari. Horrela, irtenbidea etorkizunean ekoizpenean agertuko den moduan probatzen da.

Zerbitzuen ekoizpen bertsioak soilik exekutatzen dituzten zerbitzariak daude. Zerbitzari hauek beharrezkoak dira gorabeheren kasuan, hedatu aurretik entrega egiaztatzeko eta barne prestakuntzarako.

Proba prozesu automatizatu bat gehitu dugu Specflow liburutegi ezaguna erabiliz. Probak automatikoki egiten dira NUnit erabiliz Ansible-tik zabaldu eta berehala. Zereginen estaldura guztiz automatikoa bada, ez da eskuzko probarik behar. Batzuetan eskuzko proba osagarriak oraindik beharrezkoak diren arren. Jira-n etiketak erabiltzen ditugu arazo zehatz baterako zein proba egin behar diren zehazteko.

Gainera, karga probak egiteko beharra handitu egin da; lehenago kasu bakanetan bakarrik egiten zen. JMeter erabiltzen dugu probak egiteko, InfluxDB horiek gordetzeko eta Grafana prozesu grafikoak eraikitzeko.

Zer lortu dugu?


Lehenik eta behin, "askatu" kontzeptua kendu genuen. Desagertu dira koloso hau produkzio-ingurune batean zabaldu zeneko bi hilabeteko kaleratze izugarriak, negozio-prozesuak aldi baterako eten zituenean. Orain, batez beste, 1,5 egunean behin zabaltzen ditugu zerbitzuak, onartu ondoren martxan jartzen direlako taldekatuz.

Gure sisteman ez dago hutsegite larririk. Akats batekin mikrozerbitzu bat askatzen badugu, harekin lotutako funtzionaltasuna hautsiko da eta gainerako funtzionalitate guztiak ez dira eragingo. Horrek asko hobetzen du erabiltzailearen esperientzia.

Inplementazio eredua kontrolatu dezakegu. Zerbitzu-taldeak gainerako irtenbideetatik bereizita hauta ditzakezu, beharrezkoa bada.

Gainera, hobekuntza-ilara handi batekin arazoa nabarmen murriztu dugu. Gaur egun, zerbitzu batzuekin modu independentean lan egiten duten produktu talde bereiziak ditugu. Scrum prozesua dagoeneko ondo moldatzen da hemen. Talde zehatz batek produktuaren jabe bereizi bat izan dezake, eta zereginak esleitzen dizkiona.

Laburpena

  • Mikrozerbitzuak oso egokiak dira sistema konplexuak deskonposatzeko. Prozesuan, gure sisteman zer dagoen ulertzen hasten gara, zein testuinguru mugatu dauden, non dauden haien mugak. Horri esker, hobekuntzak modu egokian bana ditzakezu moduluen artean eta kodea nahastea saihesteko.
  • Mikrozerbitzuek antolakuntza-onurak eskaintzen dituzte. Askotan arkitektura gisa bakarrik hitz egiten da, baina edozein arkitektura behar da negozio beharrak konpontzeko, eta ez bere kabuz. Horregatik, esan dezakegu mikrozerbitzuak talde txikietan arazoak konpontzeko oso egokiak direla, Scrum oso ezaguna dela kontuan hartuta.
  • Bereizketa prozesu iteratiboa da. Ezin duzu aplikazio bat hartu eta mikrozerbitzuetan zatitu besterik gabe. Sortzen den produktua nekez izango da funtzionala. Mikrozerbitzuak dedikatzean, onuragarria da lehendik dagoen ondarea berridaztea, hau da, gustuko dugun kode bihurtzea eta negozioen beharrei hobeto erantzutea funtzionaltasun eta abiadura aldetik.

    Ohar txiki bat: Mikrozerbitzuetara pasatzearen kostuak nahiko garrantzitsuak dira. Denbora luzea behar izan da azpiegituren arazoa bakarrik konpontzeko. Beraz, eskalatze espezifikorik behar ez duen aplikazio txiki bat baduzu, zure taldearen arreta eta denborarako lehian bezero kopuru handi bat ez baduzu behintzat, baliteke mikrozerbitzuak gaur egun behar dituzunak ez izatea. Nahiko garestia da. Prozesua mikrozerbitzuekin hasten baduzu, hasieran kostuak handiagoak izango dira monolito baten garapenarekin proiektu bera hasten baduzu baino.

    PS Istorio hunkigarriagoa (eta pertsonalki zuretzat bezala) - arabera link.
    Hona hemen txostenaren bertsio osoa.

Iturria: www.habr.com

Gehitu iruzkin berria