Computers are hard - interviu DHH

Un interviu cu DHH (Ruby on Rails creator)

Cateva idei interesante din articol:

So the problem with those methodologies is they put too much focus on estimating, which is inherently impossible with software?

I’d go even further and say that estimation is bullshit. It’s so imprecise as to be useless, even when you’re dealing with fixed inputs. And you’re not. No one is ever able to accurately describe what a piece of software should do before they see the piece of software.

The magic really is in shifting your mindset from estimates to budgets. Don’t think about how long something takes. Think about how long are you willing to give something. This flips the entire idea.

I wanted to go back to microservices. One of the engineers I spoke to earlier talked about them as a response to the monolithic software becoming too complex to maintain. What’s your beef with microservices?

Let’s start with the premise. Monolithic software becoming so complicated… what is this ‘becoming’? Is this just happening to us? Are we completely innocent bystanders? The complexity is just rolling over us and there’s nothing we can do? That is a bullshit assumption that we need to refute. Complete and utter nonsense. You don’t have to let complexity roll over you. You choose to. And once you’ve chosen to be flooded with complexity, then a natural response is to try shove that complexity into more different boxes because you just can’t handle it all at once, right?

If you are unable to contain the complexity of a monolithic application, what on earth makes you think you are competent to distribute that complexity across a fleet of services that now have to interact and deal with network unreliability, retries, two-phase commits, and all these other complexities that simply do not exist when you deal with method calls, parameters, and the basics of running a singular process.

9 Likes

E suparat rau pe microservicii, dar le blameaza pe nedrept pentru ca ele au aparut nu doar ca nevoia de a sparge o structura monolitica ci si pentru (sau mai ales) ca sunt furnizori externi de servicii care le fac mult mai bine decat le-ar face o singura companie. Asa poti acum sa construiesti o platforma sarind peste munca de a tine o baza de date cu utilizatori, securizata si accesibila in cloud, si sa te concentrezi pe ce trebuie rezolvat. Securitate, stocare, cautare, autentificare, etc, toate sunt acum disponibile ca servicii.

E un caz clasic de a folosi scula potrivită pentru problema potrivită.

Așa cum nu bați cuie cu cleștele și nu scoți cuie cu ciocanul, așa e și cu nemuritoarea poveste monolith vs microservices.

Trebuie să știi să separi logica, să știi ce merge unde, iar pentru asta trebuie să ai o vedere largă și experiență multă.

Nu e nimic rău nici cu a fi monolith, nici cu a fi microservicii, doar să știi unde să le pui.

Un monolith prea mare, care devine foarte scump de întreținut și adăugat noi features clar trebuie spart în bucăți mai mici, dar asta trebuie făcut de cineva care se pricepe, care înțelege problemele și slăbiciunile microserviciilor, și le introduce acolo unde e cât mai simplu de compensat pentru acele slăbiciuni de care zice el.

2 Likes

Pentru asta s-a inventat tesla :crazy_face: :smirk: (și nu cea a lui Musk :))

Acum, n-am avut ocazia sa lucrez pe proiect real cu microservicii, am urmărit câteva tutoriale dar îmi pare exagerat crearea de serviciu pentru fiecare domeniu în parte.

Ce mi s-a întâmplat mie, pe un proiect unde am primit cerințe una după alta și nimic concret de la inceput, am ajuns sa am un monolit cu funcționalități care n-aveau nici o legătură între ele. Asa am ajuns sa le scot în alte servicii (chiar librarii diferite folosite pt optimizare, ca acum am posibilitatea asta), dar care sunt consumate de acel monolit. Practic am redus aplicatia principala (aproape) la stadiul de punte între clienți (web apps) si cele câteva servicii.

Ce am facut eu îmi pare o struto-camila, dar se pliază mult mai bine pe aplicatia respectiva, decât un monolit sau 100% microservicii.

Mie mi-a placut ca a spus asta: “daca nu esti in stare sa proiectezi si sa mentii un monolith pe termen lung, ce te face sa crezi ca esti in stare sa proiectezi si sa mentii o arhitectura bazata pe microservicii?”
Da, microserviciile suna misto si toti vorbim despre ele in ultima vreme, dar cati ati construit cu adevarat microservicii?

De ceva vreme (2-3 ani) sunt adeptul Domain Driven Design, Onion/Clean Architecture, CQRS (Command Query Responsibility Segregation) si, desi incerc sa separ domeniile aplicatiei (acele Bounded Contexts din DDD), nu construiesc microservicii, ci tot un fel de monolith. Doar ca incerc sa separ lucrurile mai bine decat intr-o arhitectura clasica n-tier (sau “data-driven architecture”).

Teoretic un microserviciu trebuie sa fie un “independent deployable unit” (sau un “vertical slice of your system”), iar chestia asta creeaza multe probleme/provocari pe care nu le ai intr-un monolith.

Nu stiu daca poti numi microservices faptul ca te conectezi la niste servicii externe de autentificare, stocare, cautare, etc. Adica, de ce sunt microservicii si nu simplu, servicii (externe)?
Poti sa ai un monolith intern si sa ai integrare cu diversi provideri de autentificare sau cautare, asta nu inseamna ca TU faci microservicii.

Sigur ca se tot pot descoperi gloante de argint.


Doar ca de obicei sunt gloante oarbe si nu se refera (mai) deloc la functionalitatea esentiala.

Nu trebuie sa construiesti decat unul. E monolotic, face o treaba si o face bine.

E mai cool, altfel nu are sens.

Cel mai bun video pe tema asta l-am văzut de cineva de la Netflix.

In cazul lor o arhitectura de genul are sens pentru că funcția de browsing a conținutului e complet deconectată de cea de streaming efectiv.

Apoi, colectarea de informații de la useri, gen dacă pun pe pauză sau altele, e complet deconectat de streaming sau browsing.

Fiecare poate bine mersi exista fără celălalt.

E mult hype pe temă, nu neg, dar sunt cazuri unde se poate aplica și unde chiar are sens.

Eu am participat in vreo 3 proiecte in care sau folosit microservicii si nu mi-a placut in nici un caz rezultatul final (am scris despre asta parca pe un alt thread).

Pana la microservicii sunt o multime de variante de solutii scalabile care fac o treaba buna si la costuri rezonabile. Sa incepi un proiect direct cu micro-servicii din punctul meu de vedere e aiurea, cel mai ok sa pornesti la drum cu o arhitectura cat mai simpla si pe urma adaugi complexitate functie de nevoi.

2 Likes

Am lucrat si eu in cadrul unui proiect foarte mare in care s-a facut spargerea domeniilor in bucati mai mici, fiecare rezultand intr-un REST API separat, DAR baza de date era una gigantica si comuna tuturor serviciilor.

Microserviciile vin cu niste provocari foarte mari, un prieten foarte experimentat mi-a zis: “Eu nu as construi o arhitectura cu microservicii fara sa am o armata de DevOps in spate”.
Astfel cred ca microserviciile se preteaza la proiecte foarte mari care au in spate o echipa numeroasa si un buget pe masura, altfel poti adauga prea multa complexitate si va fi dificil de mentinut pe termen lung.

aici am si eu o intrebare :grin: Daca fiecare serviciu ajunge sa fie un rest api, nu complici frontendul? asta considerand ca acesta ramane un mamut/monolit , un SPA consumator. In functie de nevoi, vei trimite requesturi catre 7 api-uri, in loc de unul singur. Lasand deoarte ideea ca si SPA-ul poate fi modularizat ca microserviciile, fiecarui modul in parte revenindu-i cate un rest api.

Eu ma gandeam ca exista un rest api central care face legatura intre frontend si microservicii, care contine doar rutele acestora, Front-ul nici nu trebuie sa stie ca in spate exista aceste divizari atat timp cat el comunica cu Api-ul central.

Toate REST API-urile erau oricum hostate la acelasi domeniu, fiecare REST API era un subdomeniu (https://api-root/api1/, https://api-root/api2/).
Din punctul de vedere al frontendului API-urile sunt doar url-uri pe care oricum trebuie sa le construiesti in functie de resursele pe care vrei sa le accesezi.

Apoi nu cred ca in frontend ai un singur “data service” care se conecteaza la toate endpointurile necesare. De regula se pastreaza impartirea pe resurse, domenii, asa ca nu vad nicio problema.

Totusi, poti sa folosesti un reverse-proxy ca sa para ca ai un singur API. De fapt, cred ca chiar aveam asa ceva in proiectul respectiv, dar nu era un alt API central, ci doar o tabela de rutare.

3 Likes

Exista mai multe lucruri in proiectele unde am lucrat:

  1. API gateway - un punct central prin care trec toate microserviciile care verifica securitatea de baza (valid jwt), routeaza requesturile intern la fiecare microserviciu in parte si alte lucruri (tracking de sesiune pentru debuging).

  2. Serviciile vin pe doua layere - la baza sunt microserviciile care sunt cele mai simple (de obicei crud-uri) peste care vine un layer de business services care vor executa actiuni mai complexe (care necesita interactiunea cu mai multe micro-servicii).

Mie mi se pare cam bizara arhitectura asta in care zici ca microserviciile sunt la baza, iar peste ele exista un alt layer de business services. Sau termenul de microservicii este folosit gresit aici.
De regula un microserviciu inseamna un slice vertical al intregului sistem care poate fi deployat independent si, uneori, scalat pe orizontala (deployat in mai multe instante).

De exemplu, intr-un sistem de shopping online, poti sa ai ca microservicii: OrdersService, CustomersService, PaymentsService. Serviciile astea sunt de sine statatoare, au propriul storage intern si sunt “owner” pe domeniul lor, iar comunicatia cu alte servicii se face DOAR prin REST APIs sau, de multe ori, printr-un event/message bus pentru decuplare totala si pentru a asigura functionarea partiala a sistemului chiar si atunci cand un microserviciu este down.

1 Like

Fac referire la un articol ca probabil ca nu explic eu bine

Tu faci referire doar la layerul cel mai de jos care e atomic/izolat/domeniu etc…

Am auzit de foarte multe ori repetata aceasta afirmatie si din experienta mea e falsa. Problema este ca multe din microservicii sunt pe critical path, asta inseamna ca functionalitati critice din sistem nu sunt utilizabile fara alea. Sa zicem in exemplul de shopping platform ce te faci daca nu merge:

  • product
  • user
  • order
  • payment

Ce anume ramane la un astfel de sistem pe non critical path, din experienta mea raman foarte putine micro servicii.

1 Like

Poti face o comanda fara sa o platesti (primesti factura ulterior + un link de plata). Poti sa iti vezi comenzile anterioare chiar daca nu merg comenzile. Poti vedea produsele daca nu merg comenzile.

In teorie ar merge. Daca “se separa” functionalitatea in asa fel incat totul e legat atunci nu.

1 Like

Deciizia asta o ia product/busines owner-ul si din experienta mea cele listate vor fi considerate ca si critice.

1 Like

Design patternul pe care il cauti este denumit backend-for-frontend.

2 Likes

Pare ca e cel mai folosit pattern, adica eu cel putin, fara sa stiu cum se numeste, asa am invatat programare :))) un singur rest api, monolit consumat de un singur client, UI-ul, in cazul meu un spa. Iar pentru mobile apps, cu totul altele.

cum spunea @pghoratiu, la api gateway incercam sa fac referire :crazy_face:

in spate Rest1, Rest2, … RestN, in fata clientul (un web app), iar intre ele API Gatewayul care pentru mine, tot un Rest api este (lipsa experienta aici) ce doar apeleaza serviciile rest. Nu e tocmai ok, ca pierde viteza, trimitand request si asteptand un raspuns. in loc de directul Client -> Rest, o sa fie Client -> Gateway (ruta, controller, conexiune servicii) -> Rest

edit: am gasit acest articol, unde explica mai bine api gateway si backend-for-frontend (bff).

1 Like

Un api gateay ofera mai multe beneficii, printre care token validation si chiar refreshul acestuia. Dar cel mai des folosit e https offloading — in spatele gatewayului poti folosi http simplu, asta inseamna network trafic mult mai mic.

5 Likes