In questu articulu, parraraghju cumu u prughjettu chì u travagliu hà evolutu da un grande monolitu in un settore di microservizi.
U prugettu hà iniziatu a so storia assai tempu fà, in principiu di l'annu 2000. I primi versioni sò stati scritti in Visual Basic 6. À u tempu, hè diventatu chjaru chì u sviluppu in questa lingua seria difficiuli di sustene in u futuru, postu chì l'IDE è l'. lingua stessa si sviluppa pocu. À a fini di l'anni 2000, hè statu decisu di cambià à u C# più promettente. A nova versione hè stata scritta in parallelu cù a rivisione di u vechju, pocu à pocu più è più codice era in .NET. U backend in C # era inizialmente focu annantu à l'architettura di serviziu, in ogni modu, biblioteche cumuni cù logica sò state aduprate durante u sviluppu, è i servizii sò stati lanciati in un solu prucessu. U risultatu era una applicazione chì avemu chjamatu u "monolitu di serviziu".
Unu di i pochi vantaghji di un tali bundle era a capacità per i servizii di chjamà l'altri attraversu una API esterna. Ci era prerequisiti chjaru per a transizione à un serviziu più currettu, è in u futuru, l'architettura di microserviziu.
Avemu principiatu u nostru travagliu di descomposizione versu u 2015. Ùn avemu ancu ghjuntu à u statu ideale - ci sò parti di un grande prughjettu chì ùn pò micca esse chjamatu monoliti, ma ùn pare micca ancu microservizii. Tuttavia, u prugressu hè significativu.
Ne parleraghju in l'articulu.

Cuntenuti
Architettura è prublemi di a suluzione esistenti
Inizialmente, l'architettura pareva cusì: UI - una applicazione separata, a parte monolitica era scritta in Visual Basic 6, l'applicazione .NET era un settore di servizii cunnessi chì travagliavanu cù una basa di dati abbastanza grande.
Disvantages di a suluzione precedente
Unicu puntu di fallimentu
Avemu avutu un unicu puntu di fallimentu: l'applicazione .NET era in esecuzione in un prucessu. Se qualcunu di i moduli hà fallutu, l'applicazione sana hà fiascatu è hà da esse riavviatu. Siccomu automatizemu un gran numaru di prucessi per diversi utilizatori, per via di un fallimentu in unu di elli, tutti ùn puderanu micca travaglià per qualchì tempu. È cù un errore di software, a redundanza ùn hà micca aiutu ancu.
Fila di migliurà
Questa mancanza hè più organizativa. Ci sò parechji clienti in a nostra applicazione, è tutti volenu finalizà u più prestu pussibule. Nanzu, era impussibile di fà questu in parallelu, è tutti i clienti sò stati in linea. Stu prucessu hà causatu un negativu per l'affari, perchè avianu bisognu di pruvà chì u so compitu era di valore. È a squadra di sviluppu hà passatu u tempu à urganizà sta fila. Pigliò assai tempu è sforzu, è per via di u risultatu, u pruduttu ùn puderia micca cambià cusì rapidamente cum'è vuleriamu.
Usu suboptimal di risorse
Quandu i servizii di hosting in un solu prucessu, avemu sempre copiatu cumplettamente a cunfigurazione da u servitore à u servitore. Vulemu separà i servizii più carichi per separatamente per ùn spreche risorse, è per ottene un cuntrollu più flexibleu di u nostru schema di implementazione.
Difficile à implementà e tecnulugia muderni
Un prublema familiar à tutti i sviluppatori: ci hè un desideriu di introduci tecnulugii muderni in u prugettu, ma ùn ci hè micca manera. Cù una grande suluzione monolitica, ogni aghjurnamentu di a biblioteca attuale, per ùn dì micca a transizione à una nova, si trasforma in un compitu piuttostu micca trivial. Ci vole assai tempu per dimustrà à u capu di a squadra chì questu avarà più bonus chì i nervi perditi.
Difficultà à emette cambiamenti
Questu era u prublema più seriu - avemu publicatu versioni ogni dui mesi.
Ogni liberazione hè diventata un veru disastru per a banca, malgradu i testi è i sforzi di i sviluppatori. L'affari hà capitu chì alcune di e funziunalità ùn anu micca travagliatu per questu à u principiu di a settimana. È i sviluppatori anu capitu chì una settimana di incidenti gravi l'aspittava.
Tutti avianu un desideriu di cambià a situazione.
Aspettative da i microservizi
Emissione di cumpunenti quandu pronti. Emissione di cumpunenti cum'è sò pronti da decomposing la suluzione è siparari differente prucessi.
Picculi squadre di produttu. Questu hè impurtante perchè u grande squadra chì travaglia nantu à u vechju monolitu era difficiule di gestisce. Un tali squadra era furzatu à travaglià secondu un prucessu strettu, ma vulianu più creatività è indipendenza. Solu i picculi squadre puderanu permette.
Isolamentu di servizii in prucessi separati. Idealmente, mi piacerebbe isolà lu in container, ma un gran numeru di servizii scritti in .NET Framework funzionanu solu sottu WindowsI servizii basati annantu à .NET Core stanu cumparendu avà, ma ci sò sempre pochi.
Flessibilità di implementazione. Mi piacerebbe cumminà i servizii cumu avemu bisognu, è micca a manera chì u codice forze.
Usu di e tecnulugia novi. Questu hè di interessu à qualsiasi programatore.
Problemi di transizione
Di sicuru, se sparte un monolitu in microservizi era faciule, ùn ci saria micca bisognu di parlà in cunferenze è scrive articuli. Ci sò parechje trappule in stu prucessu, discriverà i principali chì ci anu impeditu.
U primu prublema tipicu per a maiò parte di i monoliti: cunnessione di logica cummerciale. Quandu scrivimu un monolitu, vulemu reutilizà e nostre classi per ùn scrive micca codice extra. È quandu si move à i microservizi, questu diventa un prublema: tuttu u codice hè abbastanza strettu, è hè difficiule di separà i servizii.
À u mumentu di l'iniziu di u travagliu, u repository avia più di 500 prughjetti è più di 700 mila linee di codice. Questa hè una suluzione abbastanza grande. secondu prublema. Ùn era micca pussibule di piglià solu è dividite in microservizii.
Terzu prublema - Mancanza di infrastruttura necessaria. In fatti, eramu impegnati in a copia manuale di u codice fonte à i servitori.
Cumu passà da u monolitu à i microservizi
Allocazione di microservizi
Prima, avemu immediatamente determinatu per noi stessi chì a separazione di i microservizi hè un prucessu iterativu. Ci hè sempre statu dumandatu à sviluppà i travaglii di cummerciale in parallelu. Cumu implementemu questu tecnicamente hè digià u nostru prublema. Dunque, avemu preparatu per un prucessu iterativu. Ùn funziona micca di manera diversa si avete una grande applicazione, è ùn hè micca inizialmente pronta per esse riscritta.
Chì metudi usemu per isolà i microservizi?
U primu modu - per sguassà i moduli esistenti cum'è servizii. In questu sensu, avemu avutu furtunatu: ci era digià servizii furmali chì travagliavanu secondu u protocolu WCF. Sò stati siparati in assemblei separati. L'avemu purtatu separatamente, aghjunghjendu un picculu lanciatore à ogni custruzzione. Hè statu scrittu cù a maravigliosa biblioteca Topshelf, chì permette di eseguisce l'applicazione sia cum'è serviziu sia cum'è cunsola. Questu hè utile per debugging perchè ùn sò micca necessarii prughjetti supplementari in a suluzione.
I servizii sò stati cunnessi da a logica cummerciale, cum'è anu utilizatu assemblei cumuni è travagliavanu cù una basa di dati cumuni. Era difficiule di chjamà microservizi in a so forma più pura. Tuttavia, pudemu emette sti servizii per separatamente, in diversi prucessi. Questu hà digià permessu di riduce a so influenza nantu à l'altri, riducendu u prublema cù u sviluppu parallelu è un puntu unicu di fallimentu.
L'assemblea di l'ospiti hè solu una linea di codice in a classa Program. Avemu ammucciatu u travagliu cù Topshelf in una classa ausiliaria.
namespace RBA.Services.Accounts.Host
{
internal class Program
{
private static void Main(string[] args)
{
HostRunner<Accounts>.Run("RBA.Services.Accounts.Host");
}
}
}
U sicondu modu per isolà i microservizi: creanu per risolve novi prublemi. Se à u stessu tempu u monolitu ùn cresce micca, questu hè digià eccellente, chì significa chì andemu in a direzione ghjusta. Per risolve novi prublemi, avemu pruvatu à creà servizii separati. S'ellu ci era una tale opportunità, allora avemu creatu più servizii "canonichi" chì gestiscenu cumplettamente u so mudellu di dati, una basa di dati separata.
Avemu, cum'è parechji altri, cuminciamu cù servizii di autentificazione è d'autorizazione. Sò perfetti per questu. Sò indipindenti, in regula, anu un mudellu di dati separatu. Iddi stessi ùn interagisce micca cù u monolitu, solu si riferisce à elli per risolve certi prublemi. Nantu à questi servizii, pudete inizià a transizione à una nova architettura, debug l'infrastruttura nantu à elli, pruvate alcuni approcci ligati à e biblioteche di rete, etc. Ùn ci hè micca squadre in a nostra urganizazione chì ùn puderanu micca fà un serviziu di autentificazione.
U terzu modu per isolà i microservizi, chì avemu usatu, hè un pocu specificu per noi. Questa hè a rimuzione di a logica cummerciale da a capa UI. A nostra applicazione UI principale hè desktop, cum'è u backend, hè scrittu in C #. I sviluppatori periòdicamenti fecenu errori è anu pigliatu parte di a logica nantu à l'UI chì duverebbe esse esistita in u backend è riutilizate.
Se guardate un veru esempiu da u codice di a parte UI, pudete vede chì a maiò parte di sta suluzione cuntene una vera logica cummerciale, chì hè utile in altri prucessi, micca solu per custruisce una forma UI.

A vera logica di l'UI ci hè solu l'ultimi dui linii. L'avemu trasferitu à u servitore in modu chì puderia esse riutilizatu, riducendu cusì l'UI è ottene l'architettura curretta.
Quartu, u modu più impurtante per isolà i microservizi, chì vi permette di riduce u monolitu, hè a rimuzione di i servizii esistenti cù trasfurmazioni. Quandu sguassate i moduli esistenti cum'è sò, i sviluppatori ùn anu micca sempre piace u risultatu, è u prucessu di cummerciale puderia esse obsoletu da a creazione di e funziunalità. Attraversu a refactoring, pudemu sustene un novu prucessu cummerciale perchè i bisogni di l'affari cambianu constantemente. Pudemu migliurà u codice fonte, sguassate i difetti cunnisciuti, creà un mudellu di dati megliu. Ci sò parechji benefici per esse acquistatu.
I servizii di decoupling cù rework và in manu cù u cuncettu di cuntestu limitatu. Questu hè un cuncettu da u disignu orientatu à u duminiu. Significa una rùbbrica di u mudellu di duminiu in quale tutti i termini di una sola lingua sò definiti unicu. Cunsiderate u cuntestu di l'assicuranza è i bills cum'è un esempiu. Avemu una applicazione monolitica, è hè necessariu di travaglià cù u contu in l'assicuranza. Aspittemu u sviluppatore per truvà a classa di Account esistente in un altru assemblea, fate un riferimentu à questu da a classa d'Assicuranza, è uttene u codice di travagliu. U principiu DRY serà osservatu, u compitu serà fattu più veloce usendu codice esistenti.
In u risultatu, risulta chì i cuntesti di cunti è assicuranza sò cunnessi. Cum'è e novi esigenze venenu, sta relazione interferiscenu cù u sviluppu, aghjunghjendu cumplessità à una logica cummerciale digià cumplessa. Per risolve stu prublema, avete bisognu di truvà e fruntiere trà i cuntesti in u codice è caccià e so violazioni. Per esempiu, in u cuntestu di l'assicuranza, hè abbastanza pussibule chì u numeru di 20 cifri di u cuntu di u Bancu Centrale è a data di apertura di u contu serà abbastanza.
Per separà questi cuntesti limitati l'una di l'altru è inizià u prucessu di estrazione di microservizi da una soluzione monolitica, avemu usatu un approcciu cum'è a creazione di API esterni in l'applicazione. Se sapemu chì qualchì modulu duverebbe diventà un microserviziu, in qualchì modu cambià in u prucessu, allora avemu immediatamente fattu chjama à a logica chì appartene à un altru cuntestu limitatu per via di e chjama esterne. Per esempiu, attraversu REST o WCF.
Avemu decisu fermamente per noi stessi chì ùn evitemu micca u codice chì avaristi bisognu di transacciones distribuite. In u nostru casu, hè diventatu abbastanza faciule per seguità sta regula. Finu a ora, ùn avemu micca scontru tali situazioni quandu e transazzioni difficiuli sò veramente necessarii - a cunsistenza finale trà i moduli hè abbastanza.
Fighjemu un esempiu specificu. Avemu u cuncettu di un orchestrator - un pipeline chì processa l'essenza di l'"applicazione". Crea un cliente, un contu, è una carta bancaria in turnu. Se u cliente è u contu sò creati bè, ma a creazione di a carta falla, l'applicazione ùn entra in u statutu di "successu" è ferma in u statutu di "carta micca creata". In u futuru, l'attività di fondo a ripiglià è finisce. U sistema hè stata in un statu di incongruenza per qualchì tempu, ma in generale simu soddisfatti di questu.
In l'eventu chì una situazione si presenta ancu quandu serà necessariu di salvà in modu coherente una parte di e dati, probabilmente andemu per l'allargamentu di u serviziu per processà questu in un prucessu.
Cunsiderate un esempiu di assignà un microserviziu. Cumu pò esse relativamente sicuru per portà à a produzzione? In questu esempiu, avemu una parte separata di u sistema - un modulu di serviziu di pagamentu, una di e sezioni di codice di quale vulemu fà microserviziu.

Prima di tuttu, creemu un microserviziu riscriviendu u codice. Migliuremu certi punti chì ùn ci cunvene micca. Implementemu novi esigenze di cummerciale da u cliente. Aghjunghjemu à u bundle trà l'UI è u backend di l'API Gateway, chì furnisce l'inviu di chjama.

Dopu, liberemu sta cunfigurazione in opera, ma in un statu pilotu. A maiò parte di i nostri utilizatori sò sempre travagliendu cù i prucessi di cummerciale vechji. Per i novi utilizatori, sviluppemu una nova versione di l'applicazione monolitica chì stu prucessu ùn cuntene più. In fatti, avemu un munzeddu di monoliti è microservizi chì travaglianu in forma di pilotu.

Cù un pilotu successu, avemu capitu chì a nova cunfigurazione funziona veramente, pudemu sguassà u vechju monolitu da l'equazioni è lascià a nova cunfigurazione in u locu di a vechja suluzione.

In tuttu, usemu quasi tutti i metudi esistenti per separà u codice fonte di un monolitu. Tutti ci permettenu di riduce a dimensione di parti di l'appiecazione è traduce in biblioteche novi, facendu un codice fonte megliu.
U travagliu cù a basa di dati
A basa di dati si presta à a separazione peghju di u codice fonte, postu chì cuntene micca solu u schema attuale, ma ancu i dati storichi accumulati.
A nostra basa di dati, cum'è parechji altri, hà avutu un altru svantaghju impurtante - a so grande dimensione. Questa basa di dati hè stata cuncepita secondu l'intricata logica cummerciale di un monolitu, è e relazioni sò accumulate trà e tavule di diversi cuntesti limitati.
In u nostru casu, sopra à tutti i prublemi (una grande basa di dati, assai rilazioni, à volte cunfini incomprensibili trà e tavule), ci era un prublema chì si trova in parechji prughjetti grandi: l'usu di u mudellu di basa di dati cumuni. I dati sò stati pigliati da e tavule à traversu viste, attraversu a replicazione è spedite à altri sistemi induve sta replicazione hè necessaria. In u risultatu, ùn pudemu micca spustà e tavule in un schema separatu, perchè eranu attivamente utilizati.
In a divisione, a stessa divisione in cuntesti limitati in u codice ci aiuta. Di solitu ci dà una idea abbastanza bona di cumu si sparghje i dati à u livellu di a basa di dati. Capemu quali tavule appartenenu à un cuntestu limitatu è quale à un altru.
Avemu applicatu dui modi glubale per sparte a basa di dati: split tables esistenti è split with processing.
A separazione di e tavule esistenti hè una bona pratica per aduprà se a struttura di dati hè bona, risponde à i bisogni di l'affari, è tutti sò cuntenti. In questu casu, pudemu attribuisce e tavule esistenti in un schema separatu.
Un ramu cù trasfurmazioni hè necessariu quandu u mudellu di cummerciale hà cambiatu assai, è i tavulini ùn ci satisfanu più in tuttu.
Separazione di tavule esistenti. Avemu bisognu di determinà ciò chì separemu. Senza sta cunniscenza, nunda ùn hà da travaglià, è a separazione di cuntesti limitati in u codice ci aiuterà quì. Comu regula, se pudete capisce i cunfini di i cuntesti in u codice fonte, diventa chjaru chì e tavule deve esse incluse in a lista per a separazione.
Imagine chì avemu una suluzione induve dui moduli monoliti interagiscenu cù a stessa basa di dati. Avemu bisognu di assicurà chì solu un modulu interagisce cù a seccione di tavule separati, è l'altru cumencia à interagisce cù l'API. Per principià, hè abbastanza chì solu a registrazione hè realizata attraversu l'API. Questa hè una cundizione necessaria per chì pudemu parlà di l'indipendenza di i microservizii. I ligami di leghje ponu stà sempre chì ùn ci hè micca un grande prublema.

Cum'è u prossimu passu, pudemu digià separà a rùbbrica di codice chì travaglia cù tavule staccabile, cù o senza trasfurmazioni, in un microserviziu separatu è eseguite in un prucessu separatu, un containeru. Questu serà un serviziu separatu cù una cunnessione à a basa di dati monolitu è quelli tavule chì ùn sò micca direttamente ligati à questu. U monolitu interagisce sempre cù a parte staccabile per a lettura.

In seguitu, sguassemu sta cunnessione, vale à dì, trasfereremu ancu a lettura di e dati di l'applicazioni monolitiche da e tavule staccate à l'API.

In seguitu, selezziunate e tavule da a basa di dati cumuni chì solu u novu microserviziu travaglia. Pudemu spustà e tavule à un schema separatu o ancu à una basa di dati fisica separata. Ci hè una cunnessione per a lettura trà u microserviziu è a basa di dati monolitu, ma ùn ci hè nunda di preoccupari, in questa cunfigurazione pò campà per un bellu pezzu.

L'ultimu passu hè di sguassà cumplettamente tutti i ligami. In questu casu, pudemu avè bisognu di migrà dati da a basa di dati principale. A volte vulemu riutilizà certi dati o cartulari replicati da sistemi esterni in parechje basa di dati. Avemu questu da u tempu à u tempu.

Dipartimentu di trasfurmazioni. Stu metudu hè assai simili à u primu, solu si và in inversu. Avemu immediatamente una nova basa di dati è un novu microserviziu chì interagisce cù u monolitu attraversu l'API. Ma questu lascia un inseme di tabelle di basa di dati chì vulemu sguassà in u futuru. Ùn avemu più bisognu, l'avemu rimpiazzatu in u novu mudellu.

Per chì stu schema funziona, probabilmente avemu bisognu di un periodu di transizione.
Dopu, ci sò dui approcci pussibuli.
U primu: duplichemu tutte e dati in e basa di dati novi è vechji. In questu casu, avemu a redundanza di dati, pò esse prublemi cù a sincronizazione. Ma poi pudemu piglià dui clienti diffirenti. Unu hà da travaglià cù a nova versione, l'altru cù a vechja.
U sicondu: separazione di dati secondu qualchì attributu cummerciale. Per esempiu, avemu avutu 5 prudutti in u sistema, chì sò guardati in a basa di dati antica. U sestu, in u quadru di u novu travagliu cummerciale, mettimu in una nova basa di dati. Ma avemu bisognu di un API Gateway chì sincronizza questi dati è mostra à u cliente induve è ciò chì piglià.
I dui approcci funzionanu, sceglite secondu a situazione.
Dopu avemu assicuratu chì tuttu u travagliu, a parte di u monolitu chì travaglia cù l'antica struttura di basa di dati pò esse disattivata.

L'ultimu passu hè di sguassà i vechji strutture di dati.

In riassuntu, pudemu dì chì avemu prublemi cù a basa di dati: hè difficiule di travaglià cun ellu cumparatu cù u codice fonte, hè più difficiuli di separà, ma pò è deve esse fattu. Avemu trovu qualchi modi chì vi permettenu di fà stu abbastanza sicuru, ma hè più faciuli à fà un sbagliu cù i dati cà cù u codice fonte.
U travagliu cù u codice fonte
Hè ciò chì u diagrama di u codice fonte pareva quandu avemu cuminciatu à analizà u prughjettu monoliticu.

Pò esse divisu cundizionalmente in trè strati. Questa hè una strata di eseguite moduli, plugins, servizii è attività individuali. In fatti, questi eranu punti d'entrata in una suluzione monolitica. Tutti sò stati stretti stretti cù a strata cumuna. Avia una logica cummerciale chì era sparta trà servizii è assai relazioni. Ogni serviziu è plugin utilizatu finu à 10 o più assemblei cumuni, secondu a so dimensione è a cuscenza di i sviluppatori.
Eramu furtunati, avemu avutu biblioteche infrastrutturali chì puderanu esse usatu separatamente.
Calchì volta una situazione hè ghjunta quandu certi ughjetti cumuni ùn appartenenu micca veramente à sta strata, ma eranu biblioteche infrastrutturali. Questu hè stata risolta da rinominà.
I cuntesti cunfinati eranu a più grande preoccupazione. Hè accadutu chì i cuntesti 3-4 sò stati mischiati in una assemblea cumuna è utilizati l'un l'altru in e stesse funzioni cummerciale. Era necessariu di capiscenu induve si pò esse divisu è longu chì cunfini, è ciò chì da fà dopu cù a mappa di sta separazione à l'assemblee di codice fonte.
Avemu formulatu parechje regule per u prucessu di splitting code.
U primu: Ùn vulemu più sparte a logica cummerciale trà servizii, attività è plugins. Vulemu rende a logica cummerciale indipendente in i microservizi. Per d 'altra banda, i microservizi, idealmente, sò percepiti cum'è servizii chì esistenu in modu completamente indipendente. Pensu chì questu approcciu hè un pocu sprecu, è difficiule da ottene, perchè, per esempiu, i servizii C# seranu cunnessi da a biblioteca standard in ogni modu. U nostru sistema hè scrittu in C #, altre tecnulugii ùn sò ancu stati utilizati. Dunque, avemu decisu chì pudemu permette di utilizà custruzzioni tecniche cumuni. A cosa principal hè chì ùn cuntenenu micca frammenti di logica cummerciale. Sè vo avete un bellu wrapper intornu à l'ORM chì avete aduprà, hè assai caru per copià da u serviziu à u serviziu.
A nostra squadra hè un fan di u disignu orientatu à u duminiu, cusì l'architettura di cipolla era una grande adatta per noi. A basa in i nostri servizii ùn era micca a capa d'accessu di dati, ma una assemblea cù a logica di u duminiu, chì cuntene solu a logica di l'affari è hè priva di ligami à l'infrastruttura. À u listessu tempu, pudemu raffinà indipindentamente l'assemblea di u duminiu per risolve i prublemi assuciati cù frameworks.
À questu stadiu, avemu scontru u primu prublema seriu. U serviziu avia da riferite à una assemblea di duminiu, vulemu fà a logica indipindente, è u principiu DRY interferiscenu cun noi quì. I sviluppatori vulianu riutilizà e classi da l'assemblee vicine per evità a duplicazione, è in u risultatu, i duminii cuminciaru à cumunicà cù l'altri. Avemu analizatu i risultati è decisu chì forse u prublema si trova ancu in l'area di u dispositivu di repository di codice fonte. Avemu avutu un grande repository chì cuntene tutti i codici fonte. A suluzione per tuttu u prughjettu era assai difficiuli di custruisce nantu à una macchina lucale. Per quessa, sò stati creati solu suluzioni chjuchi separati per parte di u prugettu, è nimu hà pruibitu di aghjunghje un assemblea cumuna o di duminiu è riutilizà. L'unicu strumentu chì ùn ci hà micca permessu di fà questu era u codice di rivisione. Ma qualchì volta hà ancu sbuchjatu.
Allora avemu cuminciatu à passà à un mudellu cù repositori separati. A logica cummerciale hà cessatu di flussu da u serviziu à u serviziu, i duminii sò veramente diventati indipendenti. I cuntesti delimitati sò supportati più esplicitamente. Cumu riutilicemu e biblioteche di l'infrastruttura? L'avemu separatu in un repository separatu, poi i mette in pacchetti Nuget, chì avemu messu in Artifactory. Cù ogni cambiamentu, l'assemblea è a publicazione si faci automaticamente.

I nostri servizii cuminciaru à riferite à i pacchetti di infrastruttura interna in listessa manera di quelli esterni. Scarichemu biblioteche esterne da Nuget. Per travaglià cù Artifactory, induve mettemu sti pacchetti, avemu usatu dui gestori di pacchetti. In picculi repositori, avemu ancu usatu Nuget. In i repositori cù parechji servizii, avemu usatu un Paket chì furnisce più cunsistenza di versione trà i moduli.

Cusì, travagliendu in u codice fonte, cambiendu un pocu l'architettura è separà i repositori, facemu i nostri servizii più indipendenti.
Problemi di infrastruttura
A maiò parte di i svantaghji di a migrazione à i microservizi anu da fà cù l'infrastruttura. Averete bisognu di implementazione automatizata, avete bisognu di novi biblioteche per eseguisce l'infrastruttura.
Installazione manuale in ambienti
Inizialmente, avemu installatu a suluzione nantu à l'ambienti manualmente. Per automatizà stu prucessu, avemu creatu un pipeline CI/CD. Avemu sceltu u prucessu di spedizione cuntinuu, perchè l'implementazione cuntinua hè sempre inaccettabile per noi da u puntu di vista di i prucessi di cummerciale. Per quessa, u mandatu in u funziunamentu hè realizatu da un buttone, è per a prova - automaticamente.

Utilizemu Atlassian, Bitbucket per u almacenamentu di fonte, è Bamboo per e custruzzioni. Ci piace à scrive script di creazione in Cake perchè hè u listessu C #. I pacchetti pronti venenu à Artifactory, è Ansible ghjunghje automaticamente à i servitori di prova, dopu chì ponu esse pruvati immediatamente.

Logging separatu
À un certu tempu, una di l'idee di u monolitu era di furnisce logging spartutu. Avemu ancu bisognu di capisce ciò chì fà cù logs individuali chì sò nantu à i dischi. I logs sò scritti in i schedarii di testu. Avemu decisu di utilizà a pila standard ELK. Ùn avemu micca scrittu à ELK direttamente à traversu i fornituri, ma hà decisu chì avemu da finalizà i logs di testu è scrivite l'ID di traccia in elli cum'è identificatore, aghjunghjendu u nome di serviziu in modu chì questi logs puderanu esse analizati.

Cù Filebeat simu capaci di raccoglie i nostri logs da servitori, poi trasfurmalli, aduprate Kibana per custruisce query in l'interfaccia utente, è vede cumu a chjama hè stata instradata trà i servizii. L'ID di traccia sò assai utili per questu.
Pruvate è debugging servizii cunnessi
Inizialmente, ùn avemu micca capitu bè cumu pudemu debug i servizii chì avemu sviluppatu. Tuttu era simplice cù u monolitu, l'avemu eseguitu nantu à a macchina lucale. À u principiu, anu pruvatu à fà u listessu cù i microservizi, ma qualchì volta, per lancià cumplettamente un microserviziu, avete bisognu di lancià parechji altri, è questu hè inconveniente. Avemu capitu chì hè necessariu di passà à u mudellu quandu abbandunemu solu u serviziu o servizii chì vulemu debug in a macchina locale. I servizii rimanenti sò usati da i servitori chì currispondenu à a cunfigurazione cù prod. Dopu a debugging, durante a prova, per ogni compitu, solu i servizii cambiati sò emessi à u servitore di teste. Cusì, a suluzione hè pruvata in a forma in quale serà in vendita in u futuru.
Ci sò servitori chì sò installati solu versioni di produzzione di servizii. Questi servitori sò necessarii per incidenti, per i cuntrolli di consegna pre-implementazione, è per a furmazione interna.
Avemu aghjustatu un prucessu di teste automatizatu utilizendu a famosa biblioteca Specflow. I testi sò eseguiti automaticamente da NUnit appena sò implementati da Ansible. Se a copertura di u compitu hè cumplettamente automaticu, ùn ci hè micca bisognu di teste manuale. Ancu s'è qualchì volta una prova manuale supplementaria hè sempre necessaria. Per determinà quali teste per eseguisce per un prublema particulare, usemu tag in Jira.
Inoltre, a necessità di teste di carica hè cresciuta, prima era realizatu solu in casi rari. Avemu aduprà JMeter per eseguisce e teste, InfluxDB per almacenà, è Grafana per tracciate u prucessu.
Chì avemu ottinutu?
Prima, avemu liberatu di u cuncettu di "liberazione". E versioni monstruose di dui mesi sò sparite quandu stu colossu hè statu implementatu in un ambiente di produzzione, rompendu i prucessi di cummerciale per un tempu. Avà sparghjemu servizii in media ogni 1,5 ghjorni, raggruppendu, perchè entranu in opera dopu l'appruvazioni.
Ùn ci sò micca crash fatali in u nostru sistema. Se liberemu un microserviziu cù un bug, allora a funziunalità assuciata à questu serà rotta, è tutte e altre funziunalità ùn saranu micca affettate. Questu migliurà assai l'esperienza di l'utilizatori.
Pudemu cuntrullà u schema di implementazione. Pudete separà gruppi di servizii separatamente da u restu di a suluzione, se ne necessariu.
Inoltre, avemu riduciutu significativamente u prublema cù una grande fila di migliure. Avemu squadre di produttu separati chì travaglianu cù alcuni di i servizii indipindentamente. Questu hè induve u prucessu Scrum hè utile. Una squadra specifica pò avè un pruprietariu di u produttu separatu chì assigna compiti à ellu.
Resumen
- I microservizi sò adattati per a decomposizione di sistemi cumplessi. In u prucessu, cuminciamu à capisce ciò chì hè in u nostru sistema, chì sò i cuntesti limitati, induve sò i so cunfini. Questu permette di distribuisce currettamente e migliorie à i moduli è impedisce l'obfuscazione di codice.
- I microservizi furniscenu benefici organizzativi. Sò spessu riferiti solu cum'è architettura, ma ogni architettura hè necessariu per risolve i bisogni di l'affari, è micca in sè stessu. Dunque, pudemu dì chì i microservizi sò adattati per risolve i prublemi in picculi squadre, postu chì Scrum hè assai populari avà.
- A separazione hè un prucessu iterativu. Ùn pudete micca piglià una applicazione è solu split it in microservices. U pruduttu risultatu hè improbabile di travaglià. Quandu mette in risaltu i microservizi, hè benefiziu per riscrive u legatu esistente, vale à dì, trasfurmà in codice chì ci piace è megliu risponde à i bisogni di l'affari in termini di funziunalità è rapidità.
Picculu avvertimentu: I costi di migrazione à i microservizi sò abbastanza significativi. Pigliò assai tempu per risolve u prublema di l'infrastruttura. Dunque, sè vo avete una piccula applicazione chì ùn hà micca bisognu di una scala specifica, se ùn ci hè micca un gran numaru di clienti chì si battenu per l'attenzione è u tempu di a vostra squadra, allora forsi i microservizi ùn sò micca ciò chì avete bisognu oghje. Hè abbastanza caru. Sè avete principiatu u prucessu cù i microservizi, i costi à u principiu seranu più di più chè se u stessu prughjettu principia cù u sviluppu di un monolitu.
PS Una storia più emotiva (è cum'è per voi personalmente) - da .
Eccu a versione completa di u rapportu.
Source: www.habr.com
