1.1 Arhitectura aplicației

Acest curs este conceput pentru începători, deoarece nu veți proiecta arhitectura unei aplicații serioase pentru o lungă perioadă de timp. Dar nu vă faceți griji, arhitectura bună este mai degrabă excepția decât regula. Este foarte dificil să alegeți arhitectura corectă a aplicației înainte de a construi aplicația.

Exemple de arhitecturi populare pentru aplicații de server mari:

  • Arhitectură stratificată (Layered Architecture).
  • Arhitectură pe etaje.
  • Arhitectură orientată pe servicii (SOA).
  • Arhitectura de microservicii (Arhitectura de microservicii).

Fiecare dintre ele are avantajele și dezavantajele sale. Dar studiul lor nu vă va oferi nimic. Arhitectura este răspunsul la întrebarea „cum se organizează interacțiunea a mii de obiecte în cadrul sistemului” . Și până când nu veți experimenta întreaga complexitate a problemei, nu veți putea înțelege întreaga versatilitate a soluției.

Toate aplicațiile folosesc un fel de arhitectură, sau cel puțin pretind că o fac. Prin urmare, cunoașterea abordărilor populare ale proiectării aplicației vă va permite să înțelegeți rapid și mai bine cum funcționează aplicația. Și asta înseamnă să faci modificări exact acolo unde ai nevoie.

Ce înseamnă „a face schimbări acolo unde este necesar”? Există locuri în care nu trebuie să faceți modificări? Exact.

Pentru a fi concret, să presupunem că lucrați la un proiect de backend mediu . Este scris de 5 ani de o echipă de 20 de oameni. Proiectul a durat 100 de ani-om și conține aproximativ 100 de mii de linii de cod. În total, este format din două mii de clase, care sunt împărțite în 10 module de diferite dimensiuni.

Și adaugă o realitate dură. Logica unor sarcini este răspândită pe mai multe module. De asemenea, logica de afaceri poate fi în frontend (scrisă în JavaScript) și/sau scrisă ca procedură stocată direct în baza de date. Sunteți încă sigur că puteți determina imediat locul în care să faceți modificări ?

Acesta nu este un coșmar pe care l-am inventat ca să te sperii. Acesta este un proiect tipic. Se întâmplă și mai rău. De ce se întâmplă asta? Pot exista o mulțime de motive, dar aproape întotdeauna există astfel:

  • Mulți oameni lucrează la proiect - fiecare dintre ei îl vede puțin diferit.
  • De 5 ani, 10 persoane s-au schimbat în proiect, nou-veniți nu prea l-au înțeles.
  • Crearea de software este o realizare constantă de schimbări care schimbă constant totul.
  • Acum cinci ani, când ne-am hotărât asupra arhitecturii, ideea proiectului era oarecum diferită.

Dar principalul lucru este că, indiferent de arhitectura proiectului, toți programatorii care lucrează la el au aderat la aceeași înțelegere a modului în care funcționează acest proiect. Să începem cu cel mai simplu concept - arhitectura client-server.

1.2 Conceptul de interacțiune client-server

Acum vom înțelege conceptul care stă la baza arhitecturii client-server și vă va permite să înțelegeți mai bine cum este organizată interacțiunea a milioane de programe pe Internet.

După cum sugerează și numele, acest concept implică două părți: client și server . Totul este ca în viață aici: clientul este clientul cutare sau acel serviciu, iar serverul este furnizorul de servicii. Clientul și serverul sunt programe fizice , de exemplu, un client tipic este un browser .

Următoarele exemple pot fi date ca server:

  • Servere web precum Tomcat.
  • Servere de baze de date precum MySQL.
  • Gateway-uri de plată precum Stripe.

Clientul și serverul comunică de obicei prin Internet (deși pot funcționa în aceeași rețea locală și, în general, în orice alte tipuri de rețele). Comunicarea are loc prin protocoale standard, cum ar fi HTTP, FTP, sau protocoale de nivel inferior, cum ar fi TCP sau UDP.

Protocolul este de obicei ales în funcție de tipul de serviciu pe care îl oferă serverele. De exemplu, dacă este un apel video, atunci se utilizează de obicei UDP.

Vă amintiți cum funcționează Tomcat și servleturile sale? Serverul primește un mesaj HTTP, îl despachetează, extrage toate informațiile necesare de acolo și îl transmite servlet-ului pentru procesare. Apoi rezultatul procesării este împachetat înapoi într-un răspuns HTTP și trimis clientului.

Aceasta este interacțiunea tipică client-server. Browserul este clientul web și Tomcat este serverul web. Tomcat este chiar numit server web.

Dar dacă te gândești bine, nu numele este important, ci esența - distribuția rolurilor între programe. Scriptul dvs. JS care rulează într-o pagină HTML ar putea fi numit client , iar servlet-ul dvs. un server . La urma urmei, ei lucrează în perechi în cadrul conceptului client-server .

1.3 O nuanță importantă

De asemenea, este de remarcat faptul că interacțiunea client-server se bazează pe principiul că o astfel de interacțiune este inițiată de client : serverul răspunde doar clientului și raportează dacă poate furniza serviciul clientului și, dacă da, în ce condiții. .

Nu contează unde este situat fizic clientul și unde este serverul. Software-ul client și software-ul server sunt de obicei instalate pe mașini diferite, dar pot rula și pe același computer.

Acest concept a fost dezvoltat ca un prim pas spre simplificarea unui sistem complex. Ea are aceste puncte forte:

  • Simplificare logică : serverul nu știe nimic despre client și despre cum își va folosi datele în viitor.
  • Pot exista clienți slabi : toate sarcinile consumatoare de resurse pot fi transferate pe server.
  • Dezvoltare independentă a codului client și a codului serverului.
  • O mulțime de clienți diferiți, de exemplu Tomcat și diferite browsere.

Cea mai simplă versiune a interacțiunii dintre client și server este prezentată în imagine:

client server

Este important de menționat două detalii aici. În primul rând, imaginea arată că mulți clienți pot accesa un singur server. În al doilea rând, ei îl pot accesa în același timp. Aceasta este, de asemenea, o parte importantă a serverului.

De obicei, un client interacționează cu un utilizator, așa că adesea nici măcar autorizarea nu este necesară acolo. Cu toate acestea, serverul procesează solicitările de la mii de clienți și, atunci când dezvoltați codul pentru acesta, trebuie să fiți capabil să distingeți între autorizare și autentificare.

De asemenea, este important ca serverul să proceseze mii de solicitări în paralel. Și asta înseamnă că atunci când dezvoltați codul backend, va trebui să vă gândiți în mod constant la sarcina de acces concurent la resurse. De asemenea, codul serverului are o probabilitate foarte mare de stare de cursă (cursa firelor), blocaj (blocarea reciprocă a firelor).

Ciclul de viață al obiectelor importante trebuie monitorizat:

Nu puteți să începeți un fir nou pe server prin new Thread().start(). În schimb, trebuie să aveți un ThreadPool care să partajeze între toate firele de execuție.

De asemenea, nu puteți începe doar o sarcină asincronă, deoarece acestea sunt, de asemenea, executate în fire separate. Când creați o astfel de sarcină, ar trebui să știți întotdeauna ce grup de fire de execuție o execută și ce se va întâmpla dacă un astfel de pool depășește.

Toate lucrările cu fișiere și directoare trebuie efectuate prin intermediul resurselor de încercare. Dacă într-o aplicație normală ați uitat să închideți un flux sau un fișier, aceasta este o problemă? Se va închide singur când ieși din program. Dar dacă ați uitat să închideți un fișier de pe server undeva în cod și serverul dvs. rulează de luni de zile... În curând, mii de astfel de fișiere neînchise se vor acumula, iar sistemul de operare nu va mai deschide fișiere noi pentru citire (lucrați cu fișiere este controlat de sistemul de operare). Teamlead nu te va bate pe cap...

1.4 Arhitectura client-server

un alt punct important. Arhitectura client-server definește doar principiile generale de interacțiune între computere , detaliile interacțiunii sunt determinate de diverse protocoale.

Acest concept (client-server) ne spune că trebuie să împărțim mașinile din rețea în mașini client, care au întotdeauna nevoie de ceva, și mașini server, care oferă ceea ce au nevoie. În acest caz, clientul începe întotdeauna interacțiunea, iar regulile prin care are loc interacțiunea sunt descrise de protocol.

Există două tipuri de arhitectură de interacțiune client-server: primul se numește arhitectură client-server cu două niveluri, al doilea este arhitectura client-server cu mai multe niveluri (uneori numită arhitectură cu trei niveluri sau arhitectură cu trei niveluri, dar acesta este un caz special).

Principiul de funcționare al arhitecturii pe două niveluri a interacțiunii client-server este că procesarea unei cereri are loc pe un server fără a se face referire la alte servere în procesul acestei procesări.

Modelul de interacțiune client-server pe două niveluri poate fi desenat ca o diagramă simplă.

arhitectură client-server pe două niveluri

Aici puteți vedea că primul nivel este tot ceea ce privește clientul, iar al doilea nivel este tot ceea ce privește serverul.