ABONAMENTE VIDEO REDACȚIA
RO
EN
Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 88
Abonament PDF

E momentul să uitați de REST, pentru că gRPC este aici

Călin Bunea
Software Developer @ UIPath



PROGRAMARE


În ultimii trei ani și jumătate am avut șansa de a vizita frecvent un psiholog, ocazie cu care am reușit să înțeleg mai bine cum funcționează mintea umană, inclusiv a mea. Am învățat multe lucruri interesante despre modelele comportamentale pe care noi oamenii le avem și motivele din spatele acestor modele des întâlnite. Toate acestea au dus la o interacțiune mai bună cu oamenii din jurul meu.

Un lucru interesant pe care l-am învățat a fost acela că oamenii sunt de obicei rezistenți la schimbare. Acest lucru a devenit oarecum natural, deoarece de-a lungul evoluției noastre ca specie, orice schimbare majoră a mediului înconjurător era o adevărată amenințare pentru supraviețuire. Cu toate acestea, avem tendința de a uita că de fapt adaptabilitatea este cea mai mare calitate pe care o avem ca specie. Această calitate a jucat un rol crucial în supraviețuirea noastră ca specie până în ziua de azi.

Procesul decizional

Am vrut să expun această introducere din zona psihologiei evolutive, deoarece sunt convins că dacă mâine am întreba câțiva programatori:

"Dacă ai fi arhitectul unui proiect, ce tip de comunicare ai alege pentru aplicația de fațadă și micro serviciile din backend?"

Probabil că majoritatea ar răspunde REST fără să se gândească prea mult și fără să ceară informații adiționale. În opinia mea, nu există decizii arhitecturale "bune" sau "rele" ci doar decizii care vin cu "avantaje" și "dezavantaje". Cea mai mare provocare este -de fapt- aceea de a pune în balanță, într-un mod obiectiv, avantajele și dezavantaje bazate pe cerințele actuale. Pentru a acest lucru, eu gândesc în termeni de amortizare a investiției (ROI în limbă engleză). Trebuie să ne gândim cât timp adițional necesită o soluție față de cealaltă, care sunt potențialele beneficii aduse de fiecare soluție, și așa mai departe. Am auzit multă lume în jurul meu justificându-și alegerile prin prisma faptului că poate în viitor vor avea nevoie de funcționalitatea oferită de una dintre soluții.

Lumea în care trăim azi este într-o continuă schimbare produsă într-un ritm alert, drept urmare nu cred că este eficient să gândim astfel. Nu știm exact cum va arata viitorul, așa că nu are sens să investim mult timp în construcția unei mașini pregătită special pentru scenariul puțin probabil în care ar trebui să aselenizeze.

Detaliile tehnice din spatele cortinei

Revenind la REST, haideți să vedem care este, cu adevărat, problema? Discuția se învârte în jurul protocolului HTTP 1.1, folosit de obicei în comunicațiile de tip REST, la care se adaugă tipul de serializare a datelor, utilizând, de obicei, un serializator JSON. Conform Wikipedia, protocolul HTTP 1.1 a fost prima dată definit în anul 1997, în RFC 2068. Simplul fapt că un protocol de comunicare are o vechime de peste douăzeci de ani, nu ar trebui să fie un argument în alegerile tehnice pe care le facem. În schimb, viteza și cantitatea de resurse utilizate, ar trebui să fie luate în considerare atunci când cântărim opțiunile pe care le avem.

În rândurile următoare, realizăm o analiză sumară a modului cum funcționează protocolul HTTP 1.1. Clientul inițiază o conexiune TCP/IP cu serverul, de obicei pe portul 80 în cazul HTTP, respectiv 443 în cazul HTTP Securizat. Pentru inițializarea conexiunii TCP/IP există inițial un schimb de mesaje "syn" între client și server, în vederea confirmării conexiunii, schimb de mesaje care necesită timp. După ce conexiunea este stabilită, clientul poate să trimită o singură cerere către server, fiind apoi nevoit să aștepte răspunsul de la server înainte de a trimite următoarea cerere. Așadar, în perioada în care clientul așteaptă răspunsul de la server, conexiunea existentă nu poate fi (re)folosită pentru a transmite o altă cerere. E drept că, din punct de vedere tehnic, clientul poate să trimită mai multe cereri consecutive în cadrul unei conexiuni, fără să aștepte neapărat răspunsul de la server, dar serverul este obligat să răspundă cererilor în ordinea în care ele au fost trimise. Drept urmare, nu există un beneficiu real în a folosi această tehnică. În timp ce așteaptă un răspuns, clientul trebuie să inițializeze o nouă conexiune cu serverul de fiecare dată când dorește să facă o nouă cerere și deci, să treacă prin procesul inițial de schimb de mesaje de tip "syn".

Ar mai fi de menționat faptul că fiecare socket aferent unei conexiuni are nevoie de memorie alocată pentru bufferul de trimitere a datelor, memorie pentru bufferul de recepționare a datelor, un identificator prin care Sistemul de Operare să poată să gestioneze acel socket, informații despre conexiune cum ar fi IP-ul serverului, portul și așa mai departe. Ținând cont de faptul că în ziua de azi există telefoane mobile care au 12 GB memorie RAM, cantitatea de resurse/memorie folosită de către un socket este nesemnificativă. Dar ce se întâmplă atunci când pentru aplicația noastră web avem în spate zece microservicii cu care trebuie să comunicăm pentru fiecare cerere care vine de la un browser client? În cazul în care se folosește HTTP 1.1, aplicația noastră web e nevoită să deschidă în total zece conexiuni cu microserviciile din spate pentru a putea servi o cerere venită de la un client browser. În cazul în care există 500 de cerere simultane de la clienți browser, făcând un calcul matematic simplu, ajungem la concluzia că aplicația noastră web va avea 5000 conexiuni deschise cu microserviciile din spate, la care se adaugă încă 500 conexiuni cu clienții browser. În sistemul de operare Windows (sau în cazul aplicațiilor web din cloud-ul Azure), cel mai probabil aplicația noastră web va fi terminată de către sistemul de operare datorită atingerii limitei de 5000 de socketuri folosite. În plus, trebuie să adăugăm și timpul petrecut de către aplicația web pentru stabilirea conexiunilor (schimbul inițial de mesaje "syn").

Sursa: https://medium.com/@EmperorRXF/evaluating-performance-of-rest-vs-grpc-1b8bdf0b22da

Soluția pentru problema enunțată mai sus este să se facă multiplexarea cererilor folosind o singură conexiune TCP/IP. Folosind protocolul HTTP 2.0, această facilitate ne este oferită automat. În cadrul HTTP 2.0, mai multe cereri pot fi transmise către server folosind o singură conexiune, fără să fie nevoie să se aștepte un răspuns după fiecare cerere. Astfel, clientul va trimite mai multe cereri către server, iar acesta va răspunde în ordinea în care termină de procesat fiecare cerere. În momentul în care clientul primește un răspuns de la server, acel răspuns conține informații cu privire la cererea pentru care s-a transmis răspunsul. Deducem astfel că e cererea căreia îi aparține răspunsul, semnalând mai departe în aplicație faptul că răspunsul de la server a ajuns pentru cererea X.

Trebuie reținut faptul că din punct de vedere hardware, există un singur canal fizic pentru transmiterea datelor și un singur canal pentru recepționare. Prin urmare, dacă avem mai multe conexiuni deschise simultan cu un server, nu înseamnă că vom avea o viteză mai mare de transfer pe rețea a datelor, deoarece datele se trimit fizic bit cu bit. Atunci când există mai multe conexiuni, kernelul sistemului de operare împreună cu driverul, se ocupă de sincronizarea accesului la canalul fizic de transmisie/recepție a datelor.

Rapid, mai rapid, cel mai rapid

Motivul principal pentru care gRPC este mai rapid decât REST este dat de faptul că gRPC funcționează valorificând protocolul HTTP 2.0, pe când REST folosește în majoritatea cazurilor protocolul HTTP 1.1.

Un alt beneficiu oferit de gRPC este dat de serializatorul protobuf care este mai rapid decât orice alt serializator JSON/XML.

Probabil că în acest moment vă întrebați cum rămâne cu compatibilitatea între mai multe platforme și/sau limbaje de programare, compatibilitate care este oferită în mod tradițional de REST. Nu este cazul să vă faceți griji, deoarece gRPC oferă posibilitatea definirii unui fișier manifest, pe baza căruia se poate genera cu ajutorul unui utilitar, cod specific limbajului de programare dorit. Acel cod conține clasele proxy care facilitează interacțiunea cu serverul gRPC.

Un alt avantaj major la gRPC pe care aș dori să-l menționez este funcționalitatea de streaming. Desigur, funcționalitatea de streaming poate fi implementată și în comunicarea de tip REST, doar că implică muncă extra și cel mai probabil va fi nevoie să se intervină în componența care efectuează serializarea/deserializarea.

O veste bună este că gRPC este suportat deja în AKS (Azure Kubernetes Services). Așa că acei care utilizează sau plănuiesc să utilizeze în viitor infrastructura Azure Kubernetes, vor fi plăcut surprinși de faptul că pot să configureze cu ușurință politicile de failover și load balancing pentru gRPC în infrastructura AKS.

Concluzii

În încheiere, aș dori să menționez faptul că nu putem afirma că este bine sau rău să folosim gRPC în loc de REST sau invers, dar putem, totuși, spune că este greșit să folosim o tehnologie doar pentru că este azi în tendințe sau pentru că este mai populară decât cealaltă. În cele din urmă, trebuie să puneți în balanță cele doua opțiuni și să luați decizia care oferă cele mai multe avantaje din punct de vedere al returnării investiției (ROI) pentru problema pe care o aveți de rezolvat.

Nu trebuie să fii un adept al tendințelor, încearcă să fii un inovator.

LANSAREA NUMĂRULUI 149

Marți, 26 Octombrie, ora 18:00

sediul Cognizant

Facebook Meetup StreamEvent YouTube

NUMĂRUL 147 - Automotive

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects