30 0 393KB
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/ {ContactListsId}
Adaugă un abonat într-o listă
GET
/api/Contact/{id}/ContactList/ Returnează toate liste în care se află un abonat
DELETE
/api/Contact/{id}/ContactList/ {ContactListsId}
Șterge un contact dintr-o listă
GET
/api/ContactList/{userId}/
Returnează toate listele de abonați ale unui user
GET
• •
20
/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/ {ContactId}
Ștege un contact dintr-o listă
PUT
/api/ContactLists/{id}/Contact/ {ContactId}
Adaugă un contact într-o listă
Evenimentele pe care le creează și sunt tratate de microserviciul EmailToSend sunt: UpdateContactEvent; DeleteContactEvent.
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 emailuri ș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