Sunteți pe pagina 1din 28

Figura 1: Stabilirea conexiunii TCP

(https://upload.wikimedia.org/wikipedia/commons/thum
b/5/55/TCP_CLOSE.svg/375px-TCP_CLOSE.svg.png)

Figura 2: Interconectarea dintre ap


UNIVERSITATEA TEHNICĂ „Gheorghe Asachi” din IAȘI
FACULTATEA DE AUTOMATICĂ ȘI CALCULATOARE
DOMENIUL: CALCULATOARE ȘI TEHNOLOGIA
INFORMAȚIEI
SPECIALIZAREA: SISTEME DISTRIBUITE ȘI
TEHNOLOGII WEB

Microservicii
LUCRARE DE DISERTAȚIE

Coordonator științific,
Șef Lucrări Dr. Cristian Buțincu
Absolvent,
George-Sorin Botezat

Iași, 2018
DECLARAȚIE DE ASUMARE A AUTENTICITĂȚII
LUCRĂRII DE DISERTAȚIE

Subsemnatul, BOTEZAT GEORGE-SORIN, legitimat cu seria SV, nr. 898441,


CNP 1930609330559, autorul lucrării MICROSEVICII, elaborată în vederea susținerii
examenului de finalizare a studiilor de disertație organizat de către Facultatea de
Automatică și Calculatoare din cadrul Universității Tehnice „Gheorghe Asachi” din Iași,
sesiunea IUNIE a anului universitar 2017-2018, luând în considerare conținutul Art. 34
din Codul de etică universitară al Universității Tehnice „Gheorghe Asachi” din Iași
(Manualul Procedurilor, UTI.POM.02 – Funcționarea Comisiei de etică universitară),
declar pe proprie răspundere, că această lucrare este rezultatul propriei activități
intelectuale, nu conține porțiuni plagiate, iar sursele bibliografice au fost folosite cu
respectarea legislației române (legea 8/1996) și a convențiilor internaționale privind
drepturile de autor.

Data Semnătura

Iași, 2018
Cuprins

Introducere.......................................................................................................................................1
Capitolul 1. Serviciu, microserviciu, monolit..................................................................................2
1.1. Ce este arhitectura bazată pe microservicii?........................................................................2
1.1. Serviciu................................................................................................................................2
1.2. Microserviciu.......................................................................................................................3
1.3. Monolit.................................................................................................................................5
Capitolul 2. Apariția microserviciilor.............................................................................................7
Capitolul 3. Pincipii de proiectare..................................................................................................9
3.1. Introducere...........................................................................................................................9
3.2. Coeziune ridicată..................................................................................................................9
3.3. Autonomie............................................................................................................................9
3.4. Toleranța la defecte............................................................................................................10
3.5. Automatizarea...................................................................................................................10
3.6. Observabil.........................................................................................................................10
Capitolul 4. Proiectare microservicii.............................................................................................12
4.1. Introducere.........................................................................................................................12
4.2. Comnicarea sincronă.........................................................................................................12
4.3. Comunicarea asincronă......................................................................................................14
4.4. Containere.........................................................................................................................15
4.5. Scalabilitatea......................................................................................................................15
4.6. Caching..............................................................................................................................16
4.7. API Gateway......................................................................................................................16
Capitolul 5. Tehnologii utilizate...................................................................................................18
5.1. .Net Core............................................................................................................................18
5.2. RabbitMQ...........................................................................................................................18
5.3. JSON Web Tocken.............................................................................................................18
5.4. Microsoft SQL Server........................................................................................................18
5.5. Azure CosmosDB...............................................................................................................19
Capitolul 6. Proiectarea aplicației..................................................................................................20
6.1. Microserviciul Contact.......................................................................................................20
6.2. Email Template..................................................................................................................21
6.3. Celelalte microservicii.......................................................................................................21
6.4. Identity Service..................................................................................................................21
6.5. API Gateway......................................................................................................................21
Capitolul 7. Viitoare direcții de dezvoltare....................................................................................22
7.1. Creare unei aplicații client WEB........................................................................................22
7.2. Crearea unei aplicații mobile.............................................................................................22
7.3. Utilizarea containerelor......................................................................................................22
7.4. SMS....................................................................................................................................22
Concluzii........................................................................................................................................23
Bibliografie....................................................................................................................................24

Iași, 2018
Introducere
Obiectivul acestei lucrări este de a studia principiile care stau la baza microserviciilor și
de a implementa un astfel de proiect urmărind respectarea tuturor principiilor respective.
Pentru a-mi putea atinge obiectivul am ales să dezvolt o aplicație cu ajutorul căreia un
utilizator poate să trimită newsletter-e abonaților săi. Astfel, am definit mai multe module
specilizate: Contact, EmailTemplate, EmailToSend, ReplaceCostumField, LinkTracking,
SendEmail, EmailStatics.
Pe lăngă microserviciile enumerate mai sus, am dezvoltat un serviciu de autentificare și
autorizare de tipul Oauth, un mecanism de monitorizare al microserviciilor, un API Gateway și o
aplicație desktop cu ajutorul căreia email-urile vor fi expediate la data dorită de utilizator.

Figura 3:Arhitectura aplicației

1
George-Sorin Botezat

Capitolul 1. Serviciu, microserviciu, monolit

1.1. Ce este arhitectura bazată pe microservicii?


Arhitectura bazată pe microservicii constă în dezvoltarea unei singure aplicații ca o suită
de servicii de mici dimensiuni, fiecare având rolul său, dar care comunică prin mecanisme
simple, cum este protocolul HTTP. Aceste servicii sunt construite în funcție de capacitățile firmei
și pot fi implementate în mod automat.
Microserviciile reprezintă o alternativă pentru sistemul monolitic de dezvoltare a
aplicațiilor. Acesta presupune dezvoltarea unei aplicații ca o singură unitate. În cazul unei
aplicații monolitice toate componentele sunt puternic interconectate și astfel aplicația devine
greu de modificat, de întreținut, dar și de mutat într-un mediu de tip cloud. Orice modificare
adusă aplicației va determina un proces de creare unei alte versiuni de sistem.
Modelul arhitecturii orientate pe servicii are la baza două concepte fundamentale: unități
desfășurate separat (separately deployed units) și arhitectură distribuită.

1.1. Serviciu
Un serviciu este o piesă de software care oferă funcționalitate altor piese de software din
cadrul sistemului. Celelalte piese de software ar putea fi orice, de la un site web la o aplicație
mobilă, o aplicație desktop sau chiar un alt serviciu care utilizează un alt serviciu pentru a realiza
un anumit tip de funcționalitate. Deci, oferă practic funcționalitate acestor aplicații. De exemplu,
în contextul unui site de cumpărături, atunci când un utilizator plasează o comandă pe site, acesta
comunică cu un serviciu, iar serviciul efectuează de fapt crearea, actualizarea, ștergerea și
recuperarea a ceea ce există în baza de date, astfel încât acesta să ofere funcționalitate aplicației
web. Comunicarea dintre componentele software și serviciu se întâmplă în mod normal într-o
rețea utilizând un fel de protocol de comunicare. De exemplu, o aplicație mobilă poate comunica
cu un serviciu prin internet. Un sistem care utilizează un serviciu sau mai multe servicii în acest
mod este cunoscut a avea o arhitectură orientată spre servicii și aceasta este în mod normal
abreviată SOA, iar ideea principală din spatele SOA este că, în loc de a folosi modulele de
pachete în cadrul fiecărei aplicații client, mai degrabă utilizezi un serviciu pentru a oferi
funcționalitate aplicațiilor clientului și acest lucru permite utilizarea mai multor aplicaţii client
folosind aceeaşi funcţionalitate.
Practic, pe viitor se pot adăuga clienți noi sau diferiți care se conectează la același
serviciu reutilizând această funcție. Aceasta ne permite să creștem software-ul atunci când crește
cererea, permițându-ne să avem o copie a serviciului pe mai multe servere, astfel că atunci când
traficul intră, un load balancer va redirecționa cererea către o anumită instanță a serviciului și noi
putem avea multiple instanțe ale serviciului, așa încât odată ce cererea crește, noi doar creștem
numărul de instanțe ale serviciului care rulează pe servere.
SOA oferă reutilizabilitate. De exemplu, funcția de a crea o comandă pe un site web
poate avea aceeași funcţionalitate ca și cea de pe o aplicație mobilă din serviciul nostru. Deci,
este același cod care creează comanda pe site-ul web și pe aplicația mobilă, motiv pentru care ne
permite nouă să reutilizăm funcționalitatea.
O altă caracteristică cheie a SOA este ideea de a avea contracte sau interfețe
standardizate. Când aplicația client apelează un serviciu, a apelat la acel serviciu, apelând o
metodă. Semnătura metodei în mod normal nu se modifică atunci când se schimbă serviciul,
deci putem actualiza serviciul nostru fără a fi nevoie să ne actualizăm clienții, atât timp cât
contractul, interfața sau semnătura metodei nu se schimbă.
2
O altă caracteristică a unui serviciu este faptul că nu are stare. Adică, atunci când există o
cerere de la un site web către serviciul nostru, acea instanță a serviciului nu trebuie să-și
amintească cererea anterioară de la clientul respectiv. În principiu, are toate informațiile de care
are nevoie pentru a prelua toate datele asociate cu cererea anterioară, astfel încât un serviciu să
nu fie nevoit să-și amintească toate apelurile pe care clientul l-a făcut pentru acea instanță
particulară a serviciului. Este fără stare, prin urmare orice instanță a serviciului poate onora orice
cerere venită de la un client, deoarece nu trebuie să-și amintească nici o interacțiune anterioară
cu o oricare altă instanță a unui serviciu.
Acum, când știm ce este un serviciu și care este arhitectura orientată spre servicii, putem
începe să vorbim despre arhitectura bazată pe microservicii.
Arhitectura bazată pe microservicii reprezintă o versiune îmbunătățită a arhitecturii
orientate spre servicii, prin urmare împărtășește toate caracteristicile cheie ale acesteia precum
scalabilitate, reutilizabilitate și contracte standardizate în interfață pentru compatibilitate inversă,
dar și ideea de a avea un serviciu care nu are stare.

1.2. Microserviciu
Arhitectura bazată pe microservicii reprezintă o evoluție a arhitecturii orientate spre
servicii. Microserviciile au introdus un nou set de principii de design care arată cum să
dimensionezi un serviciu corect, fiind util deoarce nu a existat nici o îndrumare în trecut cu
privire la modul de dimensionare a unui serviciu și ce să includă mai exact un serviciu.
SOA tradiţională a dus la servicii mari monolitice, motiv pentru care au devenit
ineficiente pentru a crește și a modifica într-un mod fiabil. Serviciile mai mici, adică
microserviciile, în principiu, oferă servicii care sunt mai scalabile, fiind mai flexibile. Putem
oferi performanțe ridicate în domeniile în care este necesară performanța.
O aplicație bazată pe microservicii este în mod normal o aplicație care este alimentată de
mai multe microservicii. Fiecare microserviciu va oferi un set de funcții conexe pentru o anumită
parte a aplicației. Un microserviciu oferă un set de funcții ascociate pentru toate aplicațiile,
aplicațiile client și serviciile clienților, deoarece microserviciul are în mod obișnuit un singur
focus.
Arhitectura bazată pe microservicii utilizează un mecanism de comunicare ușoară între
clienți și servicii, dar și între serviciu și serviciu. Mecanismul de comunicare trebuie să fie ușor
și rapid, deoarece atunci când se efectuează o tranzacție într-un sistem de arhitectură
microservicii, ea va fi o tranzacție distribuită, completată de mai multe servicii. Prin urmare,
serviciile trebuie să comunice reciproc într-un mod rapid și eficient în rețea. Interfața de aplicație
pentru un microserviciu trebuie să fie o tehnologie agnostică. Acest lucru înseamnă că serviciul
trebuie să utilizeze un protocol de comunicare deschis, astfel încât să nu dicteze tehnologia pe
care aplicația client trebuie să o folosească. Un exemplu de protocol cu comunicare deschisă
este HTTP rest, cu ajutorul lui am putea avea o aplicație client .NET care va comunica cu un
microserviciu bazat pe Java.
Într-un serviciu monolit există o bază de date centrală care permite accesul la date între
aplicații și servicii. În arhitectura bazată pe microservicii, fiecare microserviciu are propria baza
de date.
O altă caracteristică a unui microserviciu este că poate fi schimbat independent. Poţi
actualiza, îmbunătăți sau repara un anumit microserviciu fără să fii nevoit să schimbi vreun
client sau serviciu din cadrul sistemului. Și pentru că microserviciile se pot modifica
independent, ele trebuie, de asemenea, să poată fi implementate independent prin modificarea
unui singur microserviciu. Practic, ar trebui să pot implementa acea schimbare în cadrul

3
George-Sorin Botezat

sistemului, independent de orice altceva, fără a modifica nimic altceva.


Am menționat deja faptul că atunci când efectuezi o tranzacție într-un sistem de
arhitectură bazat pe microservicii, tranzacția este cel mai probabil finalizată de mai multe servicii
care sunt distribuite și, prin urmare, aceasta este o tranzacție distribuită. Deoarece acesta are atât
de multe părți în mișcare, este nevoie de un instrument centralizat pentru gestionarea
microserviciilor.
Acum să aruncăm o privire la o diagramă pentru un sistem de microservicii. Acesta este
un exemplu al unui sistem tipic de comerț electronic și după cum puteți vedea ( Figura 4:
Exemplu Arhitectura bazată pe microservicii ) , pe partea stângă, în browser-ul clientului rulează
un site de cumpărături. Browser-ul se conectează la site-urile noastre de cumpărături prin
intermediul internetului, iar site-ul nostru de cumpărături ar putea fi un site ASP.NET MVC care
rulează pe IIS. Toate procesele necesare pentru toate interacțiunile cu site-ul web este de fapt
efectuată de un număr de microservicii care rulează în fundal. Fiecare microserviciu are un
singur focus sau un singur set de funcții, precum şi propriul spațiu de stocare, putând fi schimbat
şi implementat independent.
Ca exemplu, se poate actualiza serviciul de comenzi fără a actualiza orice altă parte din
sistem. De altfel, ar putea să existe multiple instanțe pentru fiecare tip de microserviciu. Dacă
serviciul comandă este solicitat, am putea avea câteva instanțe ale serviciului comenzi pentru a
satisface cererea, iar pentru a direcționa solicitarea de pe site-ul de cumpărături către instanța
corectă a unui serviciu de comenzi apelăm la API Gateway.
Astfel, atunci când clientul plasează o comandă, site-ul pentru cumpărături poate utiliza
mai multe servicii și funcții pentru a satisface tranzacția. De aceea, într-o arhitectură de
microservicii, o tranzacție este în mod normal o tranzacție distribuită, deoarece tranzacția este de
fapt satisfăcută de mai multe părţi de software, adică microservicii, pentru a finaliza tranzacția.
De aici și necesitatea utilizării unei comunicări între microservicii care să fie super rapidă și
ușoară pentru a finaliza tranzacția într-un mod rapid.

4
Figura 4: Exemplu Arhitectura bazată pe microservicii

1.3. Monolit
Monolitul este în esență tipul de sistem care a venit înainte de microservicii. Acesta este
un sistem mare care face aproape opusul a ceea ce microserviciile încearcă să realizeze. Sistemul
tipic monolit este, în principiu, aplicația tipică pentru întreprinderi. Această aplicație ar putea fi
sub forma unui site web cu toate modulele ambalate într-un singur pachet sau ar putea fi sub
forma unui serviciu care comunică cu un site web, iar serviciul în sine este un serviciu mare, cu
toate modulele ambalate, formând o entitate.
Ca și caracteristică principală, cu cât adaugi lucruri în aplicație, aceasta continuă să
crească. Nu există nici o restricție în dimensiune. Există practic întotdeauna un pachet care
conține în esență totul și prin urmare sfârşeşti cu un proiect imens care ar putea lua mai mult
timp pentru a dezvolta noi funcționalități în cadrul aplicației. S-ar putea ca codul să fie atât de
interconectat încât este dificil să se facă o schimbare fără a afecta alte părți ale sistemului, motiv
pentru care timpul de testare se prelungește.
Implementarea unui sistem de mari dimensiuni poate fi o provocare, deoarece chiar și
pentru a repara un bug mic ești nevoit să implementezi o nouă versiune a întregului sistem și,
prin urmare, acest lucru creează un risc mai mare. Pentru că există atât de mult cod care la rândul
lui este și foarte interconectat, chiar dacă ar putea exista funcționalitate într-unul din modulele
noastre din cadrul pachetului nostru global care ar putea fi util unui sistem extern, nu poate fie
expus prin serviciu deoarece este ascuns într-o aplicație monolit, practic devine inaccesibil. Fiind
un proiect imens, suntem blocați de un set de tehnologie care ar putea fi dezvoltată cu o nouă
tehnologie. Toate cele expuse fac ca sistemul nostru global să fie mai puțin competitiv, deoarece
nu putem adopta cu ușurință noi tehnologii care ne-ar putea oferi un avantaj competitiv.
Tot codul se află într-un singur pachet mare existând posibilitatea unui nivel ridicat de
cuplare, ceea ce înseamnă, în principiu, că dacă se schimbă o parte a sistemului, ar putea afecta o

5
George-Sorin Botezat

altă parte a sistemului, deoarece codul este interconectat. Acest tip de cuplare ar putea fi prezent
între module sau între diferite tipuri de servicii. Deci, un serviciu mare ar putea fi interconectat
cu un alt serviciu la fel de mare deoarece dacă schimbăm semnătura unui serviciu, acesta
afectează un alt serviciu. Fiind un pachet, dacă o parte din sistem eşuează, ar putea afecta tot
sistemul, ceea ce ar putea degrada performanța întregului serviciu.
Chiar și scalarea acestui serviciu este destul de ineficientă. Acest lucru ne determină să
cumpărăm servere mai puternice de fiecare dată când trebuie să creștem, pentru că suntem forțați
să creştem întreaga gamă de servicii, nu doar partea care are trebui să se extindă. Iar pentru că
amprenta aplicației este atât de mare, este posibil să avem nevoie și de resurse mai puternice
pentru a rula întreaga aplicație. S-ar putea să fim nevoiți să plasăm serviciul pe un singur server
mereu. Atunci când facem o schimbare a codului la serviciul actual, timpul pentru a compila
întreaga aplicație va fi, de asemenea, mai lung, deoarece există mai mult cod și mai multe teste.
Singurul avantaj pe care un sistem monolit îl are asupra unui sistem de microservicii este
faptul că poţi rula întreagul cod pe o singură mașină, deci atunci când dezvolţi și testezi codul ai
doar un singur lucru de replicat și de configurat.

6
Capitolul 2. Apariția microserviciilor
În acest capitol vom analiza de ce o arhitectură bazată pe microservicii este folositoare
acum și care sunt beneficiile acesteia.
Unul dintre motivele pentru care arhitectura bazată pe microservicii este necesară acum
este dată de nevoia de a răspunde la schimbare într-un mod rapid. Piața software-ului este foarte
competitivă în zilele noastre. Dacă produsul tău nu oferă o caracteristică care este în cerere, va
pierde foarte repede cota de piață. Microserviciile pot împărți un sistem mare în mai multe
subsisteme motiv pentru care putem dezvolta și îmbunătăți subsistemele individual în
conformitate cu nevoile pieței. Deci, nu numai că trebuie să schimbăm o parte a unui sistem
rapid, ci și să le schimbăm într-un mod fiabil pentru a menține piața fericită, iar microserviciile
oferă această fiabilitate prin faptul că împarte un sistem în mai multe părți, avantajul fiind dacă o
parte din sistemul eșueză, nu va eșua întregul sistem.
Un alt motiv pentru care arhitectura bazată pe microservicii este acum posibilă se
datorează existenței instrumentlor automate de testare. Am prezentat deja că într-o arhitectură
bazată pe microservicii tranzacțiile noastre sunt distribuite și, prin urmare, o tranzacție va fi
procesată de mai multe servicii înainte de a fi finalizată. Deci, integrarea între aceste servicii
trebuie să fie testată.
Atât lansarea, cât și implementarea microserviciilor, poate fi complexă, deoarece avem
mai multe servicii pe care trebuie să le copiem pe servere sau pe cloud individual, de altfel pot fi
și mai multe instanțe pe care trebuie să le operăm în același timp. Avantajul este că pentru lansare
și implementare avem instrumente centralizate care pot îndeplini această funcție.
Faptul că are atât de multe părți în mișcare nu mai este o problemă deoarece le putem
găzdui folosind tehnologie la cerere. Putem solicita ca mașinile virtuale să găzduiască
microserviciile noastre la cerere. De fapt, nu mai trebuie să lansăm software-ul nostru pe servere
fizice. În schimb, putem avea doar un provider care oferă un cloud de mașini virtuale și putem
doar să clonăm aceste mașini virtuale și să lansăm microserviciile pe acestea la cerere, fără a
trebui să se facă vreo configurare a serviciului pentru o mașină virtuală nouă.
Un alt motiv pentru nevoia de a folosi o arhitectură bazată pe microservicii este
necesitatea de a adopta noi tehnologii, deoarece sistemul nostru este alcătuit din mai multe părți
mobile. Putem de altfel schimba cu ușurință un singur microserviciu dintr-o tehnologie într-o altă
tehnologie pentru a obține un avantaj competitiv.
Comunicarea asincronă reprezintă un alt avantaj al utilizării unei arhitecturi bazate pe
microservicii. Atunci când utilizăm tranzacții distribuite, ele ar putea utiliza mai multe servicii
până când operația va fi finalizată. Utilizând comunicarea asincronă, tranzacția distribuită nu
trebuie să aștepte ca serviciile individuale să-și finalizeze sarcinile.
Arhitectura bazată pe microservicii crește securitatea. Într-un sistem monolit, este posibil
să aveți o singură bază de date centrală, cu un singur sistem care o accesează și, prin urmare, tot
ce trebuie să faceți este să spargeți acel sistem pentru a avea acces la date. În arhitectura bazată
pe microservicii, fiecare microserviciu are o bază de date proprie și fiecare microserviciu poate
avea și propriul mecanism de securitate, făcând astfel datele distribuite mai sigure. Arhitectura
bazată pe microservicii oferă creșterea timpului de funcționare, deoarece atunci când vine vorba
de modernizarea sistemului, se va rescrie un microserviciu la un moment dat fără a afecta restul
sistemului.
Sistemul este împărțit în domenii de business și funcții de business, iar atunci când apare
o problemă, putem identifica rapid care serviciu este responsabil pentru acea funcție eronată și,
prin urmare, rezolvăm problema în cadrul acelui microserviciu.

7
George-Sorin Botezat

Microserviciile fac sistemul foarte scalabil și îi oferă o performanță mai bună. Atunci
când există o anumită parte a sistemului care are un numar mare de cereri, putem să scalăm acel
microserviciu în loc să scalăm întregul sistem.
De asemenea, putem da dreptul de dezvoltare asupra unui microserviciu unei anumite
echipe, astfel încât să existe o responsabilitate și cunoștință mai mare despre acel microserviciu.
Am menționat deja că microserviciile ne permit să folosim tehnologia potrivită pentru anumite
componente ale sistemului, iar pentru că fiecare microserviciu este separat, are propriul cod și nu
împărtășește aceleași baze de date, puteți avea cu ușurință posibilitatea de a lucra microservicii
simultan și distribuit pe mai multe echipe.

8
Capitolul 3. Pincipii de proiectare

3.1. Introducere
În aceast capitol voi descrie principiile de proiectare care fac un serviciu să fie
microserviciu. Am rezumat principiile de proiectare în cinci principii de proiectare. Astfel, pentru
ca serviciul să fie un microserviciu, acesta trebuie să aibă o coeziune ridicată, să fie autonom,
tolerant la defecte și observabil, iar automatizarea să fie utilizată pe tot parcursul procesului
de dezvoltare. Mai departe voi acoperi fiecare dintre aceste principii de proiectare în detaliu și
voi explica mai exact ce înseamnă ele.

3.2. Coeziune ridicată


Un microserviciu trebuie să aibă coeziune ridicată, asta înseamnă că atât conținutul, cât și
funcționalitatea microserviciului, în ceea ce privește intrarea și ieșirea, trebuie să fie coerente. În
principiu, trebuie să aibă un singur focus. Această idee a unui microserviciu de a avea un singur
obiectiv sau o singură responsabilitate este de fapt preluată de la principiile de codare solide.
Principiul responsabilității unice afirmă că o clasă se poate schimba doar pentru un singur motiv,
acesta se aplică și la microservicii. Este un principiu util, deoarece ne permite să controlăm
dimensiunea serviciului și nu vom crea din greșeală un serviciu monolit prin adăugarea altor
componente, care nu sunt legate de acel focus.
Coeziunea ridicată este, de asemenea, ca și principiul de încapsulare din vechile noastre
principii de programare. Luăm toate datele și funcționalitatea și le ambalăm într-un singur
pachet, care este microserviciul, deoarece principiul coeziunii ridicate controlează dimensiunea
microserviciului și domeniul de aplicare al acestuia. Microserviciul este ușor de rescris, deoarece
este posibil să avem puțin cod scris, deci vor exista mai puține linii de cod de rescris, fiindcă
microserviciul va fi de dimensiuni mici.
În ansamblu, dacă toate microservicele noastre au o coeziune ridicată și vor face sistemul
nostru este extrem de scalabil, flexibil și fiabil. Sistemul este mai scalabil, deoarece putem
extinde microserviciile individual care au număr de cereri crescute, în loc de a scala întregul
sistem. În același timp, sistemul este mai flexibil, deoarece putem schimba, actualiza sau
modifica funcționalitatea anumitor funcții sau domenii de activitate din cadrul sistemului nostru.
Și apoi avem fiabilitate, deoarece în general schimbăm anumite componente mici în sistem fără a
afecta alte părți ale sistemului.

3.3. Autonomie
Microserviciile trebuie să fie autonome.
Prin autonomie înțelegem că un microserviciu nu ar trebui să fie subiectul unei schimbări
atunci când apare o modificare la nivelul unui sistem extern cu care interacționează, dar nici când
apare o modificare la un sistem extern care interacționează cu acesta. Asta ar însemna că ar
trebui să existe o legătură slabă între microservicii, dar și între microservicii și clienți. Prin
legătură slabă se înţelege că o schimbare la un microserviciu nu ar trebui să forțeze alte
microservicii sau alți clienți să se schimbe. Aceasta înseamnă că microserviciile trebuie să
onoreze contractele și interfețele cu alte servicii și cu alți clienți, adică modul în care intrările și
ieșirile sunt formate pentru un microserviciu nu ar trebui să se schimbe între versiuni.
Un microserviciu ar trebui să fie, de asemenea, fără stare. Nu ar trebui să îşi amintească
interacțiunile anterioare pe care clienții le-au avut cu acest serviciu sau cu alte instanțe de

9
George-Sorin Botezat

serviciu pentru a efectua cererea actuală. Deoarece microserviciile onorează contractele și


interfețele cu alte servicii și clienți, ele trebuie să fie implementate şi schimbate independent.
Acestea ar trebui doar să se întoarcă înapoi în sistem după o schimbare sau o îmbunătățire, chiar
dacă are o versiune mai nouă decât oricare dintre celelalte componente ale sistemului. Acest
lucru arată că serviciul nostru este întotdeauna compatibil înapoi.
Există contracte clar definite între servicii, motiv pentru care pot fi dezvoltate simultan de
mai multe echipe. Deoarece există o definiție clară a intrărilor și ieșirilor la nivelul unui
microserviciu, echipe separate pot lucra pe microservicii separate. Atât timp cât aceștia onorează
contractele, dezvoltarea ar trebui să funcţioneze.

3.4. Toleranța la defecte


Un alt principiu important pentru designul microserviciilor este toleranța la defecte.
Defectul ar putea fi sub forma unui serviciu care nu răspunde la cererea serviciului tău sau ar
putea fi un terț care nu răspunde. Oricare ar fi tipul de defect, microserviciile trebuie să se
adapteze la acest eșec prin degradarea funcționalității sau prin utilizarea unei funcționalității
implicite. Un alt mod de a face microserviciile mai tolerante la defecte este prin utilizarea de
instanțe de microservicii, astfel încât acestea se înregistrează la start și, dacă oricare dintre ele
eșuează, se anulează înregistrarea, astfel încât sistemul nostru sau load balancer-ul să nu trimită
cereri către microserviicile căzute.
Trebuie, de asemenea, să conștientizăm că există diferite tipuri de eșecuri. De exemplu, ar
putea fi excepții sau erori în cadrul unui microserviciu, ar putea să existe întârzieri în a răspunde
la o solicitare sau o indisponibilitate completă a acestuia, moment în care trebuie să decidem
dacă am avea nevoie de funcționalitatea implicită.

3.5. Automatizarea
De asemenea, trebuie să luăm in calcul automatizarea în arhitectura noastră de
microservicii, și anume automatizarea sub formă de instrumente, cum ar fi cele de reducere a
testelor. Testarea automată scade timpul necesar testării manuale, timpul necesar pentru a testa
integrarea dintre servicii și clienți, dar și timpul necesar înființării mediilor de testare. Într-o
arhitectură bazată pe microservicii, sistemul nostru este alcătuit din mai multe părți în mișcare,
motiv pentru care testarea poate fi destul de complexă, de aici necesitatea de a utiliza instrumente
de testare pentru a automatiza unele dintre aceste teste. Avem nevoie instrumente automate de
testare care oferă feedback rapid.

3.6. Observabil
Un principiu de design cheie pe care trebuie să-l construim în arhitectura bazată pe
microservicii este ideea ca sistemul nostru să fie observabil. Avem nevoie de o modalitate de a
observa sănătatea sistemului nostru în ceea ce-l privește, jurnalele, adică activitatea care se
desfășoară în prezent în sistem și erorile care au apărut.
Acest tip de monitorizare și logare trebuie să fie centralizat, astfel încât să existe un
singur loc în care să căutăm aceste informații. Este nevoie de acest nivel de monitorizare și
logare într-un loc centralizat mai ales că avem tranzacții distribuite. Pentru ca o tranzacție să se
finalizeze, ea trebuie să treacă prin rețea și să utilizeze mai multe servicii. Prin urmare,
cunoașterea stării de sănătate a sistemului este vitală și acest tip de date ar fi de asemenea util
10
pentru rezolvarea rapidă a problemelor.
Întregul sistem este distribui și avem nevoie de o cale rapidă de a afla unde se află
problema noastră potențială. Pentru că folosim și unelte automatizate pentru implementare, ceea
ce înseamnă că implementarea noastră va fi foarte rapidă, avem de asemenea nevoie de o cale la
fel de rapidă de a obține feedback ca răspuns la implementare, astfel încât dacă există probleme,
le putem vedea dintr-un loc centralizat. Datele colectate pot fi utilizate și pentru extinderea
sistemului nostru. Deci, dacă vedem că există un număr mare de cereri undeva în cadrul
sistemului nostru pentru un anumit microserviciu, putem scala aceast microserviciu. Aceste date
pot fi utile pentru a determina ce părți ale sistemului nostru sunt utilizate efectiv.

Figura 5: Microservicii observabile

11
George-Sorin Botezat

Capitolul 4. Proiectare microservicii

4.1. Introducere
În acest capitol voi prezenta despre tehnologiile de comunicare sincronă și asincronă,
cum scalăm sistemul de microservicii, dar și despre containere, caching și API Gateway.

4.2. Comnicarea sincronă


Când utilizăm comunicarea sincronă între microserviciile noastre practic aplicăm niște
cereri la care apoi așteptăm răspunsuri. Acest tip de comunicare se regăsește între aplicațiile
clienților noștri și serviciile noastre, în comunicarea dintre servicii sau între serviciu și un sistem
extern. Deci, în exemplul nostru ( Figura 6: Comunicarea sincronă), serviciul unu face un apel la
serviciul doi. Apoi, serviciul doi primește această cerere ca o instrucțiune, iar pe baza acelei
instrucțiuni, serviciul doi efectuează un task și apoi, odată ce serviciul este complet, serviciul doi
răspunde către serviciul unu. Aşadar, această comunicare este sincronă, deoarece atunci când
serviciul unu face apel la serviciul doi, trebuie să aștepte serviciul doi pentru a-și termina task-ul
înainte de a primi răspuns.

Figura 6: Comunicarea sincronă

Una dintre tipurile de tehnologii care poate fi utilizat pentru a face acest tip de
comunicare se numește remote procedure call (RPC). Acesta permite crearea de programe
distribuite client-server, iar bibliotecile RPC ascund faptul că comunicați și efectuați apeluri prin
intermediul unei rețele.
Atunci când programezi RPC este aproape ca și cum ai face apel la o metodă internă în
cadrul clientului însuși. Bibliotecile RPC protejează în esență toate detaliile privind protocoalele
de rețea și protocoalele de comunicare. Este ca şi cum ai apelat o metodă funcțională locală, dar,

12
de fapt ai apelat o metodă sau o funcție aflată la distanță pe un serviciu. Cu toate acestea, RPC-ul
este sensibil la schimbare ( Figura 7: Comunicarea sincronă cu ajutorul RPC).

Figura 7: Comunicarea sincronă cu ajutorul RPC

O altă tehnologie care poate fi utilizată pentru cerere-răspuns în comunicarea sincronă


este HTTP.
HTTP este un protocol de comunicare care este folosit peste web. Atunci când soliciţi
pagini într-un browser web, utilizezi practic o comunicare HTTP pentru a vorbi cu serverul Web
și pentru a prelua pagina. Același protocol de comunicare poate fi utilizat între microservicii
pentru a efectua apeluri de comunicare sincrone la cerere. Iar pentru că funcționează pe web se
poate utiliza şi firewall-ul. Este, în esență, un protocol de comunicare cu care arhitecturile de
rețea sunt obişnuite. Prin urmare, firewall-ul poate fi configurat destul de ușor pentru a permite
traficul HTTP.
Un alt tip de protocol de comunicare care poate fi folosit peste HTTP pentru a furniza
comunicarea sincronă a răspunsului la cerere este REST.
Atunci când se utilizează REST, entitățile din sistemul nostru pot fi accesate practic
folosind endpoints URLs. Nu numai că pot să primesc înregistrări, dar pot de asemenea să creez,
actualizez și să șterg înregistrări utilizând verbele HTTP: POST, PUT, GET și DELETE, care
practic sunt mapate la operațiile curente.
Astfel, în exemplul nostru actual, pot face multiple sarcini precum: crearea unui cont
utilizând POST, actualizarea unui cont cu ajutorul PUT, recuperarea unui cont folosind GET, dar
și ștergerea unui cont utilizând DELETE. ( Figura 8: Comunicare sincronă folosind REST).

13
George-Sorin Botezat

Figura 8: Comunicare sincronă folosind REST

REST oferă și decuplarea deoarece datele returnate sunt întotdeauna în format JSON sau
XML, acesta este în mod normal diferit de reprezentarea internă a acelei entități. REST este un
protocol deschis de comunicare prin faptul că nu dictează ce tehnologii folosesc clientul și
server-ul. Aceste caracteristici, de decuplare şi de comunicare deschisă, fac sistemul REST ideal
pentru microservicii.
Principala problemă cu comunicarea sincronă este că ambele părți trebuie să fie
disponibile în timpul comunicării. Serviciul unu trebuie să aștepte serviciul doi să răspundă
înainte ca serviciul unu să facă alte operaţii, iar în arhitectura bazată pe microservicii avem
tranzacții distribuite folosind multe servicii. O încetinire a unui serviciu ar încetini întreaga
tranzacție. De asemenea, performanța sistemului nostru și a tranzacțiilor noastre este supusă
calității rețelei, deoarece este posibil să nu fie serviciul care rulează încet ci reţeaua, motiv pentru
care răspunsurile din partea serviciilor sosesc încet.
O altă problemă pe care o avem cu comunicarea sincronă este că serviciul discută direct
cu un alt serviciu sau cu un sistem şi trebuie să cunoască locația respectivului serviciu. Totuși,
această problemă poate fi rezolvată prin utilizarea modelelor de înregistrare și descoperire a
serviciilor, precum și a altor componente din rețea, cum ar fi load balancer.

4.3. Comunicarea asincronă


În acest subcapitol voi analiza modul de comunicare asincronă ce poate fi utilizat de către
microservicii.
Comunicarea asincronă într-un context de microservicii înseamnă comunicarea bazată pe
evenimente. Atunci când un serviciu are nevoie de un alt serviciu pentru a îndeplini o sarcină, în
loc să apelze direct la acel serviciu, el creează un eveniment, iar serviciile care pot efectua
această sarcină vor selecta automat acel eveniment și, prin urmare, în acest tip de comunicare
asincronă, nu este nevoie ca clientul și serverul să comunice direct. În principiu decuplează
clientul și serviciul.
Acest tip de comunicare folosește în mod normal un protocol de așteptare a mesajelor,
unde evenimentele create de serviciu sunt văzute ca mesaje. Serviciul care creează aceste mesaje
este văzut ca un publisher, iar serviciul care efectuează sarcini ca răspuns la aceste mesaje este
văzut ca un subscriber. Aceste mesaje sunt în mod normal stocate de un broker de mesaje până
când un subscriber preia aceste mesaje în ordine. Atât publisher-ul, cât și subscriber-ul știu doar
de broker-ul de mesaje și, prin urmare, sunt decuplate unele de altele. Prin urmare, subscriber-ul
14
și publisher-ul nu trebuie să cunoască locația celuilalt.
În cadrul arhitecturii bazate pe microservicii, acest protocol de comunicare va fi perfect
pentru că putem lansa noi versiuni de microservicii și noi exemple de microservicii, motiv pentru
care nu este nevoie ca fiecare dintre ele să își cunoască locația, deoarece toți comunică folosind
un protocol de așteptare a mesajelor. De asemenea, există posibilitatea de a avea mai mulți
subscriberi care acționează același mesaj. Există mulți furnizori care oferă un protocol de
așteptare a mesajelor, printre aceștia se enumeră Microsoft cu Microsoft Message Queuing,
RabbitMQ, dar și ATOM, care folosește HTTP pentru a propaga evenimente.
Problema cu comunicarea asincronă bazată pe evenimente este complicată, mai ales
atunci când se utilizează tranzacții distribuite și evenimente pentru a finaliza o tranzacție
distribuită. O altă problemă este că sistemul se bazează pe un broker de mesaje. Acesta este o
componentă suplimentară din cadrul sistemului pe care se bazează și un alt potențial punct de
eșec. Vizibilitatea tranzacțiilor poate fi, de asemenea, o problemă. Trebuie să ne asigurăm că
coada de mesaje este gestionată corect și că performanța sistemului nu este afectată dacă aveți
probleme de așteptare.
În concluzie, pentru o arhitectură bazată pe microservicii este bine să se utilizeze atât
cominicarea sincronă, cât și cea asincronă.

4.4. Containere
O opțiune de găzduire pentru microservicii este utilizarea de containere.
Containerele sunt un tip de virtualizare. Cu toate acestea, spre deosebire de mașinile
virtuale, nu rulează un întreg sistem de operare în interiorul acestuia. Ele reprezintă o modalitate
bună de a izola serviciile reciproc, pentru ca fiecare serviciu să fie mai stabil și mai sigur. Este,
de asemenea, o practică obișnuită de a rula doar un serviciu, un microserviciu într-un container.
Am menționat deja faptul că acestea sunt diferite de mașinile virtuale, deoarece nu conțin un
întreg sistem de operare. În schimb, ele au minimum pentru a rula un microserviciu și, prin
urmare, ele folosesc mai puține resurse decât mașina virtuală. Această resursă poate fi sub forma
utilizării procesorului, a memoriei și a utilizării discului de pe mașina gazdă și, prin urmare,
probabil că avem mai multe containere care rulează pe o mașină gazdă decât numărul de mașini
virtuale care pot utiliza mașina gazdă.
Containerele au tendința să ruleze mai rapid decât mașinile virtuale și au tendința de a
porni mult mai repede decât mașinile virtuale, deoarece containerele sunt atât de rapide, este mai
rapid crearea de noi instanțe pentru a satisface cererea. Datorită acestor caracteristici,
containerele se văd a fi viitorul aplicațiilor găzduite, iar suportul platformei cloud pentru ele este
în creștere. Așadar, suportul din partea serviciilor Azure si Amazon Web crește.
De-a lungul timpului, tehnologia containerelor se va standardiza și, în viitor, va juca un
rol esențial în arhitectura microserviciilor. Exemple de tehnologii pentru containere sunt Docker,
Rocker și Glassware.

4.5. Scalabilitatea
Într-un sistem de microservicii atunci când cerințele de performanță cresc sau
performanța se degradează, în mod normal, abordăm acest lucru prin scalarea sistemului. Acest
lucru se întâmplă în mod normal prin creșterea numărului de instanțe ale microserviciilor aflate
în cerere sau prin adăugarea de resurse suplimentare gazdei care rulează un anumit serviciu.
Deci, acest lucru ar putea fi sub forma creșterii numărului de nuclee ale procesorului care sunt

15
George-Sorin Botezat

disponibile pentru un serviciu, fie cantitatea de memorie disponibilă unui serviciu, fie cantitatea
de disc sau de lățime de bandă disponibilă unui serviciu. Modul în care se creşte numărul de
instanțe ale unui serviciu sau cantitatea de resurse disponibilă unui serviciu ar putea fi
automatizată sau la cerere.
Serviciile bazate pe cloud, cum ar fi serviciile Microsoft Azure și Amazon Web, sunt
cunoscute pentru a oferi opțiuni de scalare automată. Astfel, atunci când cererea crește, sistemul
se scalează într-un mod automat. Scalarea automată și la cerere este posibilă numai datorită
tehnologiilor care utilizează virtualizarea și containerele. Creșterea numărului de maşini gazdă în
scopul creșterii este în prezent considerată drept o opțiune mai lentă. Virtualizarea și containerele
sunt văzute ca o modalitate rapidă de creștere a numărului de gazde virtuale care rulează
serviciile noastre.
Odată ce am scalat sistemul nostru prin creșterea numărului de instanțe ale unui anumit
serviciu, următorul lucru de care avem nevoie este un load balancer. Acesta poate fi sub forma
unui API gateway, ceea ce implică în esență preluarea tuturor cererilor ale unui serviciu care apoi
va distribui cererile între instanțele acelui serviciu, adică va echilibra încărcarea în sistem pentru
a îmbunătăți performanța.

4.6. Caching
O altă modalitate de îmbunătățire a performanței unui sistem care folosește microservicii
este utilizarea cache-ului.
Caching-ul este o modalitate de a detecta faptul că apeluri multiple solicită același lucru
și în loc să onorăm fiecare cerere, vom onora o cerere, preluăm datele și apoi utilizăm aceleași
date pentru a satisface toate celelalte solicitări. Prin urmare, cache-ul îmbunătățește performanța
prin reducerea apelurilor clienților la un serviciu, a apelurilor la servicii către o bază de date și a
serviciilor pentru a efectua apeluri.
Locația ideală pentru a implementa caching-ul într-un sistem arhitectural de tip
microservicii este fie nivelul API Gateway, fie la nivelul serverului proxy, astfel încât
implementarea cache-ului este invizibilă pentru orice altceva, iar la acest nivel nu numai că va
reduce numărul de apeluri către serviciile noastre și bazele noastre de date, dar va reduce și
traficul din rețeaua noastră.
În ceea ce privește cerințele, dorim ca sistemul nostru de caching să fie simplu de
configurat și gestionat, deoarece într-un sistem complex de microservicii, cache-ul trebuie să fie
simplu și ușor de implementat. O altă preocupare a caching-ului este deterioarea datelor. Nu
vrem să prezentăm în mod accidental datele greșite la un apel.

4.7. API Gateway


În această subcapitol voi prezenta modul în care API gateway-urile pot fi utilizate pentru
a îmbunătăți performanța microserviciilor.
Astfel, API gateway-urile sunt punctul central de intrare în sistemul nostru pentru
aplicațiile client și, prin urmare, pot fi utilizate pentru a îmbunătăți performanța prin
funcționalitatea de echilibrare a încărcării și prin funcționalitatea de cache. Deoarece acestea sunt
punctul central de intrare, ele simplifică implementarea încărcării și cache-ului. Restul sistemului
poate să nu țină seama de faptul că avem load balancer și caching implementate, ceea ce face ca
API gateway-urile să fie atât de utile.
De asemenea, ele oferă o interfață pentru multe servicii. Am putea crește numărul de

16
microservicii sau să mutam locația microserviciilor, dar aplicația clientul nu va realiza, deoarece
punctul principal de intrare al acestuia este API Gateway-ul și ascunde toate detaliile în ceea ce
privește localizarea microserviciilor din cadrul sistemului. Deci, ajută la localizarea dinamică a
serviciilor. Căile de acces API pot fi, de asemenea, configurate pentru a direcționa apeluri
specifice către o anumită instanță a unui serviciu. De exemplu, toate apelurile de la clienții
europeni ar putea fi direcționate spre microservicii care se află în Europa.
Acesta poate fi, de asemenea, folosit pentru a asigura securitatea sistemului global prin
furnizarea de autentificare și autorizare. El ar putea avea un serviciu dedicat în fundal, care să
ofere toate datele de care are nevoie în ceea ce privește securitatea.
Așadar, API Gateway reprezintă un mijloc central de punere în aplicare a securității. Se
poate alege între a avea securitate și autorizare atât la nivelul API Gateway, cât și la nivelul de
microserviciu individual. După cum se observă, API gateway-urile nu ajută doar la performanță,
ci pot ajuta la simplificarea arhitecturii generale a microserviciilor.

17
George-Sorin Botezat

Capitolul 5. Tehnologii utilizate

5.1. .Net Core


.NET Core este un set de componente runtime, de bibliotecă și de compilator care poate
fi utilizat în configurații diferite pentru sarcini de lucru din mediul cloud sau de pe dispozitive.
.NET Core, o platformă multiplă și de tip open-source, oferă un model simplu de
dezvoltare și flexibilitatea de a lucra cu o serie de platforme de sisteme de operare și instrumente
de dezvoltare.
.NET Core este disponibil în GitHub, sub licență MIT.
.NET Core se referă la mai multe tehnologii, inclusiv .NET Core, ASP.NET Core și
Entity Framework Core.

5.2. RabbitMQ
RabbitMQ este un sistem de mesje open source, care permite integrarea aplicațiilor
împreună folosind schimburi și cozi. RabbitMQ este disponibil de la rabbitmq.com.
RabbitMQ implementează protocolul AMQP, care reprezintă Advanced Message
Queuing Protocol.
Serverul RabbitMQ este un broker de mesaje care acționează ca un coordonator de
mesaje pentru aplicațiile pe care se dorește de integrat împreună. Aceasta înseamnă că se poate
oferi sistemelor o platformă comună pentru trimiterea și primirea de mesaje.
RabbitMQ conține multe caracteristici pentru a face integrarea sistemului cât mai ușor
posibil. Acestea includ fiabilitatea, unde RabbitMQ fiind construit cu ajutorul limbajului Erlang,
brokerul de mesaje este construit pe o fundație solidă, de înaltă performanță, fiabilă și durabilă.
Mesajele pot fi persistente pe disc, pentru a se proteja de pierderi în cazul în care serverul este
repornit și se pot trimite confirmări de livrare a mesajelor unui expeditor, astfel încât să poți fi
sigur că mesajul a fost primit și stocat.

5.3. JSON Web Tocken


JSON Web Token (JWT) este un standard deschis (RFC 7519) care definește un mod
compact și autonom pentru transmiterea sigură a informațiilor între părți ca obiect JSON. Aceste
informații pot fi verificate și sunt de încredere deoarece sunt semnate digital.
JWT-urile pot fi semnate folosind o cheie secretă (cu algoritmul HMAC) sau o pereche
de chei publice / private utilizând RSA sau ECDSA.

5.4. Microsoft SQL Server


Microsoft SQL Server este un sistem de management al bazelor de date relaționale, sau
RDBMS, care suportă o mare varietate de aplicații de procesare a tranzacțiilor, de business
intelligence și de analiză în mediile IT corporative. Ca și alte programe RDBMS, Microsoft SQL
Server este construit peste SQL, un limbaj de programare standardizat pe care administratorii de
baze de date și alți profesioniști IT îl folosesc pentru a gestiona bazele de date și pentru a
interoga datele pe care le conțin. SQL Server este legat de Transact-SQL (T-SQL), o
implementare a SQL de la Microsoft care adaugă un set de extensii de programare proprietare la
18
limbajul standard.

5.5. Azure CosmosDB


Comos DB este un serviciu de baze de date care este distribuit global. Acesta permite să
gestionezi datele chiar dacă le păstrezi în centre de date care sunt împrăștiate în întreaga lume. El
oferă instrumentele necesare pentru a mări atât modelul de distribuție globală, cât și resursele de
calcul, iar aceste instrumente sunt furnizate de Microsoft Azure.
Poate suporta mai multe modele de date folosind un backend, adică, poate fi folosit
pentru modele de documente, valori cheie, relaționale și grafice. Este mai mult sau mai puțin o
bază de date NoSQL deoarece nu se bazează pe nicio schemă. Cu toate acestea, deoarece
utilizează un limbaj de interogare similar cu SQL și poate susține cu ușurință tranzacțiile ACID,
unele persoane l-au clasificat ca tip de bază de date NewSQL. Ceea ce o deosebește de alte baze
de date NewSQL este totuși că nu are un model de date relațional.

19
George-Sorin Botezat

Capitolul 6. Proiectarea aplicației

6.1. Microserviciul Contact


Microserviciul Contact este serviciul cu ajutorul căruia utilizatorul poate să își gestioneze
abonații la newsletter și gestionarea listelor de abonați. Un abonat poate să aparțină mai multor
liste sau poate să nu aparțină de nici o listă.
Metodele expuse de aces microserviciu sunt:

Verb HTTP LINK Descriere


GET /api/Contact/{userId}/ Returnează toți abonații unui user
GET /api/Contact/{userId}/{id} Returnează un abonat specific
POST /api/Contact/{userId}/ Creează un nou abonat pentru un user
PUT /api/Contact/{userId}/{id} Modifică un abonat
DELETE /api/Contact/{userId}/{id} Șterge un abonat
PUT /api/Contact/{id}/ContactList/ Adaugă un abonat într-o listă
{ContactListsId}
GET /api/Contact/{id}/ContactList/ Returnează toate liste în care se află un
abonat
DELETE /api/Contact/{id}/ContactList/ Șterge un contact dintr-o listă
{ContactListsId}
GET /api/ContactList/{userId}/ Returnează toate listele de abonați ale
unui user
GET /api/ContactLists/{userId}/{id} Returnează o lista de contacte specifică
POST /api/ContactLists/{userId}/ Adaugă o listă de contacte
DELETE /api/ContactLists/{userId}/{id} Șterge o listă de contacte
PUT /api/ContactLists/{userId}/{id} Modifică o listă de contacte
GET /api/ContactLists/{id}/Contact/ Returnează toți abonații dintr-o listă
DELETE /api/ContactLists/{id}/Contact/ Ștege un contact dintr-o listă
{ContactId}
PUT /api/ContactLists/{id}/Contact/ Adaugă un contact într-o listă
{ContactId}

Evenimentele pe care le creează și sunt tratate de microserviciul EmailToSend sunt:


• UpdateContactEvent;
• DeleteContactEvent.

20
6.2. Email Template
Email Template este serviciul prin care utilizatorul își gestionează template-urile de email
ce vor fi expediate.
Metodele expuse sunt:

Verb HTTP LINK Descriere


GET api/EmailTemplate/{userId} Returnează template-urile unui
user
GET api/EmailTemplate/{userId}/{id} Returnează un template specific
POST api/EmailTemplate/{userId} Creează un nou template
PUT api/EmailTemplate/{userId}/{id} Modifică un template
DELETE api/EmailTemplate/{userId}/{id} Șterge un template

Evenimentele pe care le creează și sunt tratate de microserviciul EmailToSend sunt:


• UpdateEmailTemplateEvent;
• DeleteEmailTemplateEvent.

6.3. Celelalte microservicii


EmailStatics este microserviciul în care se stochează email-urile trimise abonaților,
numărul de citiri și link-urile accesate de acestea.
EmailToSend este microserviciul în care se stochează ce email-uri vor trebui trimise și
când să fie trimise.
ReplaceCustomTag este microserviciul cu ajutorul căruia se face înlocuire la câmpurile
dinamice aflate în email template. Ele sunt de forma #[FirstName].
LinkTracking este serviciul care parsează template-ul pentru a găsi toate link-urile aflate
în el și le înlocuiește cu alte link-uri cu ajutorul cărora utilizatorul poate urmări ce link-uri a
accesat abonatul.
SendEmail este microserviciul care primește contactul și template-ul de email modificat,
pe care îl trimite cu ajutorul serviciul SendGrid.

6.4. Identity Service


IdentiyServer4 l-am utilizat pentru a realiza autentificarea și autorizarea. Este un
framerwork gratuit pentru ASP.NET Core și folosește OpenID Connect și OAuth2.0. Se poate
folosi și ca un server central de autentificare pentru mai multe aplicații.

6.5. API Gateway


Când am proiectat aplicația bazată pe microservicii am luat în considerare și principiul
API Gateway, cunoscut și sub numele de „backend for frontend”, deoarece este singurul punct de
intrare în arhitectura de microservicii. Este situat între client și microservicii, oferind, de
asemenea, autentificarea utilizatorilor.

21
George-Sorin Botezat

Capitolul 7. Viitoare direcții de dezvoltare

7.1. Creare unei aplicații client WEB


Implementarea unei aplicații client este necesară și pentru utilizatorii care nu cunosc
programare. Am gândit această aplicație ca un API folosit de programatori pentru a trimite email-
uri și a consulta statistica.

7.2. Crearea unei aplicații mobile


Device-urile mobile sunt, în ziua de azi, companionii noştri principali, un soi de MVP,
aflându-se permanent în geantă, în mână sau în buzunar. Deci este mai rapid să accesăm aplicația
mobile, să aflăm starea unor campanii sau să trimitem în cel mai scurt timp un email către un
abonat.

7.3. Utilizarea containerelor


Toți programatorii doresc uneori ca algoritmul să fie scris o singură dată și să-l poată rula
pe diferite sisteme de operare și independente. Soluția Docker pornește de la aceeași premisă
exceptând faptul că în loc de a scrie cod, poate configura servere într-un mod personalizat,
începând de la alegerea sistemului de operare, configurarea customizată a unor fișiere, instalarea
de anumite programe. Cu ajutorul lui Docker putem scala foarte rapid microserviicile atunci
când numărul de cereri este în creștere.

7.4. SMS
Datorită răspândirii și utilizării într-un mod atât de intensiv al telefoanelor mobile,
activitatea de Promoții Mobile sau SMS Marketing a devenit o exigență fundamentală pentru
orice companie, în orice domeniu de activitate care își dorește să transmită ceva într-un timp
foarte scurt și la un număr cât mai mare de clienți, indiferent de locul în care se află. Deci
dezvoltarea unor microservicii de expediere de SMS-uri ar fi foarte folositoare utilizatorilor
platformei.

22
Concluzii
Soluția propusă în această lucrare a fost studierea principiilor care stau la baza
microserviciilor, realizarea unei platforme de trimitere a email-urilor, urmărind rezolvarea
problemelor de arhitecturare a unei aplicații, prin utilizarea de microservicii.
În secțiunea introductivă am discutat despre ce este un serviciu și diferența dintre o
aplicație bazată pe microservicii și o aplicație monolită.
În următorul capitol s-au prezentat beneficiile utilizării unei arhitecturi bazate pe
microservicii.
În capitolul trei am prezentat tehnologiile de comunicare sincrone și asincrone, cum
scalăm sistemul de microservicii, dar și despre containere, caching și API Gateway.
În capitolul patru am descris tehnologiile utilizate în crearea aplicație: .NetCore,
RabbitMQ, Microsft Sql Server, Azure CosmosDb și JSON Web Tocken.
În următorul capitol am prezentat aplicația dezvoltată în care am pus în practică
princiipile unei arhitecturi bazate pe microservicii, iar în final am prezentat viioare direcții de
dezvoltare.
Dezvoltarea acestei aplicații a implicat studierea unor noi concepte, algoritmi și
protocoale. Aplicația este funcțională și pe termen mediu se dorește extinderea ei cu noi
protocoale.

23
George-Sorin Botezat

Bibliografie
1. Azure CosmosDB, https://docs.microsoft.com/en-us/azure/cosmos-db/introduction ,
2. De la monolit la microservicii folosind DDD și metoda Mikado din Numărul 55 al revistei Today
Software Magazin,
3. .Net Core, https://docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-2.1
4. Cursul Microservices Arhitectural Design Pattern Playbook, Rag Dhiman, https://www.pluralsight.com

24

S-ar putea să vă placă și