Luna trecută am avut o discuție practică cu invitații noștri despre microservicii și arhitecturi serverless. Alături de noi au fost:
Adelina Burnete - Java Software Engineer @ Boatyardx,
Alexandra Petre - Solution Architect @ CodeCrafters by BT,
Mircea Girigan - Software Engineer @ BoatyardX,
Vlad Petrean - Senior Software Engineer @ Accesa,
Ovidiu Mățan: Vă invit să vă prezentați pe scurt.
Adelina Burnete: Sunt inginer backend la BoatyardX unde lucrez de cinci ani jumătate. Înainte de această poziție am lucrat încă patru ani în domeniu. Am lucrat cu Java în mai multe domenii: artă, asigurări, finanțe.
Mircea Girigan: Sunt de patru ani în BoatyardX. Anterior, am lucrat la Garmin. La bază sunt inginer Java. Mai recent, am cochetat și cu DevOps.
Vlad Petrean: Am șapte ani experiență în domeniu, din care ultimii șase ani sunt la Accesa. Am început cu Java, apoi am trecut la cloud computing. Momentan, lucrez la un proiect e-commerce.
Alexandra Petre: Lucrez la CodeCrafters by BT în domeniul bancar. În trecut, am lucrat la Accenture în domeniul travelling. Ulterior, am ajuns la Cognizant, și în cele din urmă la BT.
Care sunt avantajele și dezavantajele microserviciilor?
Vlad Petrean: Voi începe cu dezavantajele. Unul din ele ține de partea de mentenanță, deoarece administrezi mai multe lucruri în paralel. În cazul monoliților, ai toată aplicația într-un singur loc, ceea ce o face mai ușor de administrat pe termen lung. În ceea ce privește avantajele, aș menționa single point of failure. Dacă la monolit pică un server, totul se prăbușește. La microservicii, vei mai avea ceva care să funcționeze. Știu o poveste de la un coleg care lucra la o firmă unde aplicația era on premise. În fiecare vineri la ora 19, când nu mai era nimeni la birou, aplicația pica timp de 15 minute. Nu au reușit să își dea seama ce se întâmplă și au decis să rămână la birou după ora 19 ca să vadă ce se întâmplă. La ora aceea se făcea curat în sediu și doamnele scoteau calculatoarele din priză pentru a conecta aspiratorul.
Și eu am avut un proiect cu un server care trebuia să ducă câteva milioane de utilizatori. Era acum 15-20 de ani în apropierea Crăciunului. Aveam un coleg care testa zilnic performanța serverului. Colegul trimitea mesaje pe care nu le citea nimeni. În mod normal, dacă ceva nu merge, spui cuiva, nu trimiți mesaj. Un japonez a citit însă un mesaj înainte de Crăciun. În mod normal aveam vreo 200 de tranzacții pe secundă, dar de trei luni aveam o tranzacție pe secundă. Din acest motiv, am lucrat tot Crăciunul și după, ca să rezolvăm problema.
Mircea Girigan: Un avantaj al monoliților este că nu avem mai multe repositories de întreținut și nu avem pipeline-uri multiple. Pentru o echipă mică nu merită să realizezi o infrastructură de tip microservicii. Un avantaj al microserviciilor este potențialul incredibil de scalare.
Ce trebuie să avem în vedere când folosim serverless?
Adelina Burnete: În AWS, am folosit atât funcții Lambda, cât și ICS care este clusterul de care vă povesteam că este o soluție mult mai lightweight pentru Kubernetes, soluție bazată pe containere. La Lambda, trebuie avut în vedere cold startul, practic funcțiile nu sunt mereu disponibile. Devin indisponibile după o perioadă. Ele trebuie reactivate, ceea ce durează puțin. Se pot folosi soluții de warm-up, iar în ceea ce privește clusterul trebuie monitorizate serviciile. Taskurile sunt definite cu anumite resurse. Le definești CPU-urile, memoria. Nu ar trebui să faci deployment la servicii în containere mai mari sau care încearcă să realizeze procese de durată. Ar trebui lucrat cu unități reduse, iar containerele să poată fi restartate oricând.
Alexandra Petre: Principalul avantaj serverless este că nu te mai ocupi tu de infrastructură. Desigur, nu ar trebui să folosești serverless oricând, mai ales dacă te leagă tare de furnizorul tău de cloud și dacă simți că ești prea limitat la ceea ce îți poate oferi acest furnizor. Un alt beneficiu important al severlessului este că e foarte ieftin. Dacă am o aplicație unde știu că de două ori pe an am câteva requesturi de la partener, atunci am prefera să mergem pe un stack API Gateway Lambda serverless cu DynamoDB, pentru că sunt ieftine și sunt exact ceea ce ne trebuie nouă. Dacă ai nevoie să fii funcțional în permanență, cu zeci de mii de clienți pe secundă și cu cerința de a avea un timp de răspuns foarte bun, varianta anterioară nu este cea mai bună.
Din perspectiva arhitecturii, când ar trebui optat pentru monolit și când pentru microservicii?
Alexandra Petre: Nu cred că trebuie să facem o alegere de tip ori-ori. Soluția hibridă poate merge în multe cazuri. Atunci când trebuie să dezvolt foarte repede, echipa este foarte mică și nu se justifică mentenanța microserviciilor. În acest caz, aș opta pentru monoliți modulari. Dacă am nevoie de performanță și pot acoperi costurile de mentenanță și dacă doresc să scalez, aș opta pentru microservicii. Dar totul trebuie evaluat de la caz la caz. Poți scala și o variantă monolit modular.
Mircea Girigan: Mai există un factor care ne poate duce într-o zonă sau în alta - câtă informație de business avem când începem un proiect. Știm care sunt granițele între microservicii? Știm cum împărțim acel serviciu? Dacă nu avem aceste informații, merită început cu un monolit pe care în timp îl transformăm în microservicii.
Adelina Burnete: Noi am avut situația unui proiect unde am început cu microservicii. Cu timpul, ne-am dat seama că ar fi mai bine să avem monoliți modularizați, pentru că aveam mult de lucru când făceam deployment și aveam de făcut mici modificări în toate serviciile. Asta ducea la întărzieri. În schimb, dacă am fi avut un singur monolit ar fi fost mai ușor. Atunci când ai o echipă mică sau medie, poți lucra modularizat. La echipe mari, microserviciile sunt mai potrivite.
Ce limbaj preferați pe partea de server-side?
Adelina Burnete: Java
Alexandra Petre: Eu am la bază Java, dar pentru unele situații am o afinitate pentru Node. Decât să merg în AWS și să scriu o funcție Lambda ca să îmi demonstrez mie ceva, mai bine scriu în Node mai repede.
Mircea Girigan: Java.
Vlad Petrean: Depinde de complexitatea proiectului și de timpul disponibil pentru finalizare. Acum sunt la modă LLM-urile. Mi se pare mai ușor de făcut un backend în Python decât în Java cu Spring. E o variantă bună și pentru ceva rapid, și pentru producție. Acestea fiind zise, pe partea de e-commerce unde e nevoie de tranzacții rapide, aș merge pe Java cu Spring. Am avut și aplicații mai micuțe scrise în Python care veneau să completeze aplicațiile de bază realizate în Java.
Care este cel mai mare număr de tranzacții pe care un server de-al vostru le-a scalat?
Vlad Petrean: Avem un API care are în clusterul nostru de Kubernetes 8 POD-uri. Avem sute de apelări pe minut și undeva la 10GB de memorie RAM de consumat.
Mircea Girigan: La proiectele unde am avut o contribuție personală, am avut câteva sute de apelări pe minut, dar există și proiecte ale colegilor mei unde s-a ajuns la numere mai mari.
Adelina Burnete: Am avut proiecte cu date de la senzori unde aveam câteva mii de apelări pe minut. Acolo aveam nevoie de o scalare. Aveam 3 POD-uri per serviciu și, fiind totul atât de distribuit, aveam Kafka și KSQL integrat cu Kafka.
Alexandra Petre: În trecut am lucrat pe aplicații care trebuiau să deservească sute de mii de clienți, dar aveam doar mii de apelări pe minut. Eram pregătiți oricând să scalăm.
Puteți vorbi despre o problemă majoră din producție pe care ați rezolvat-o?
Alexandra Petre: Eu nu lucrez pe proiecte ce sunt în producție, dar pot menționa o problemă. Am primit un telefon de la colegă de Revelion acum 2-3 ani că a primit o alertă. Clienții, agenții de turism, nu puteau să facă rezervări, deoarece nu își vedeau diverse detalii. Agențiile doreau să facă rezervări la prima oră în 1 ianuarie. Mereu apar probleme de timezone. Era un serviciu cu care ne integram și ce aștepta date în PST, în timp ce noi aveam date în UTC. Datele ajungeau greșit. Temporar, am rezolvat detaliile prin API. Am rezolvat a doua zi sursa problemei, lecția fiind că datele de tip timezone ar trebui exprimate în UTC.
Adelina Burnete: Am avut o problemă care avea impact asupra producției. Aveam Kubernetes în fiecare mediu, cluster separat și încă un cluster unde aveam toolurile, Jenkins, Sonar etc. Trebuia să ajungem în producție și picase tot clusterul de tooling. Am reușit să mai punem un nod pe cluster, l-am repornit și am făcut curat. Ne-am dat seama că aveam teste automate care rulau și testau toată aplicația, dar nu exista un mecanism de curățare. Nici partea de auto-scaling nu era configurată corespunzător.
Mircea Girigan: Cea mai interesantă problemă a fost acum câteva luni în timpul unui upgrade de Kubernetes. În timpul procesului, toate POD-urile din acel cluster trebuiau să se restarteze, iar noi, în fiecare POD, injectam un agent care ar fi trebuit să monitorizeze acel POD. Acel solution provider a făcut push la o imagine Docker incompatibilă cu runtime-ul nostru. Noi ne așteptam la un Debian, dar era o altă distribuție de Linux. Noi făceam pull mereu la ultima versiune. Am prins problema înainte de a ajunge în producție.
Vlad Petrean: Nu am avut probleme majore până în acest moment. Am avut probleme mai mici. În timpul nopții, livrăm câteva fișiere clienților noștri. Proiectul este pe Google Platform și, într-o noapte, cei de la Google au făcut upgrade la DB, făcând totul inaccesibil o jumătate de oră. Din acest motiv, toate exporturile au crăpat. Am schimbat fereastra de mentenanță cloud cu o perioadă în care baza de date nu este afectată deloc. Ar mai fi un caz în care clienții pe care noi îi apelăm au schimbat parametrii unui API fără să ne anunțe.
Cum vedeți evoluția microservicii-monolit? Va apărea ceva nou?
Alexandra Petre: Nu cred că va apărea ceva nou. Monolitul va rămâne o opțiune viabilă.
Adelina Burnete: Avem cele două soluții. Probabil că se va merge pe o variantă hibridă în funcție de volume de date, de limbaj, de necesități.
Mircea Girigan: Ar putea să apară ceva nou, dar mi-e greu să estimez ce anume.
Vlad Petrean: Mă aștept să apară un serviciu care să îmi dea posibilitatea să aleg dacă doresc să fac deployment cu microservicii sau cu monolit.
de Ovidiu Mățan
de Timea Fodor
de Rareș Coantă