# Drumul Shoprocket către microservicii, partea 1: ce am greșit când am vrut să sparg monolitul

> Articol al echipei de inginerie din primii ani Shoprocket, despre prima încercare de a extrage un serviciu dintr-un monolit PHP. De ce am ales primul serviciu greșit, ce m-a învățat cuplarea strânsă și sfatul lui Newman pe care ar fi trebuit să-l urmez mai devreme.

Winston Berty  - 17 martie 2016 - 5 min de citit

La câteva luni după ce am început la Shoprocket, începusem să mă frustrez. Aveam o aplicație PHP la care lucra o echipă mică de dezvoltatori competenți, răspândiți pe tot globul, iar mie mi se părea că remedierea unor bug-uri producea alte bug-uri, că integrarea funcțiilor noi nu era la fel de simplă cum ar fi trebuit, iar lansările erau rare și stresante. Motivul: cod puternic cuplat.

Aveam o aplicație monolitică, aproape în întregime într-un singur depozit GitHub. Actualizările sau remedierile pentru o funcție cereau adesea modificări în mai multe locuri. Pentru testare aveam un proces de peer review în care cel puțin alți doi dezvoltatori trebuiau să aprobe un branch înainte să fie integrat în master și lansat. Toate acestea făceau ca, atunci când se strecura un bug, să fie adesea greu de găsit modificarea care stricase ceva. După ce o găseam, remedierea trecea prin același proces, iar întreaga aplicație trebuia lansată din nou.

Fiind un dezvoltator tânăr și nerăbdător, mereu în căutare de noutăți, când am dat peste microservicii am crezut că o să ne rezolve toate problemele.

## Ce credeam eu că sunt microserviciile

Nu există o definiție oficială a microserviciilor, dar din ce am citit am înțeles că arhitectura de microservicii este o metodă de a proiecta aplicații software ca sisteme distribuite de servicii independente, fiecare foarte specializat și cu propriul ciclu de viață. Pentru o introducere detaliată, [articolul](https://martinfowler.com/articles/microservices.html) lui Martin Fowler este excelent.

Două aspecte m-au prins. Primul: ideea de a împărți aplicația în servicii cu granițe stricte. Asta reduce riscul ca logica specifică unui context de business să se scurgă între componente, pentru că interfețele dintre granițe trebuie planificate cu grijă. Nu e la fel de simplu ca niște apeluri locale de funcții. Al doilea: fiecare componentă poate avea propriul ciclu de viață independent. Echipele își pot deține codul și pot folosi stack-ul cel mai potrivit pentru serviciul lor, iar modificările pot fi lansate câte un serviciu pe rând și anulate fără să afecteze restul.

Eram convins. Shoprocket avea să spargă monolitul. Aceasta este partea 1 dintr-o serie scurtă care urmărește acest drum. Sper ca cititorii care plănuiesc sau parcurg o tranziție similară să învețe din reușitele și eșecurile noastre.

## Prima provocare a fost una umană, nu tehnică

A trebuit să le vând ideea celorlalți din echipă. Erau curioși, dar nu împărtășeau entuziasmul și nu voiau să cedeze ore de dezvoltare într-o etapă atât de timpurie a vieții produsului. Din fericire, CTO-ul voia să mă uit la gestionarea sesiunilor, așa că am profitat de moment: l-am convins că pot separa un serviciu de sesiuni.

Privind în urmă, a fost o alegere proastă pentru primul serviciu. Produsul nostru include un widget JavaScript care [activează comerțul online pe orice site](https://v3.shoprocket.io/ro/functionalitati/vinde-pe-orice-site.md). Tratăm sesiunile ca pe o resursă și salvăm informațiile de sesiune în baza de date pentru a analiza coșurile abandonate și alți indicatori. Dar această resursă nu e la fel de tangibilă ca ceva precum comenzile sau liniile de comandă, iar sesiunile le foloseam la aproape fiecare schimbare a stării aplicației. Asta însemna că serviciul avea să comunice inevitabil foarte mult cu restul aplicației, lucru pe care nu-l prevăzusem și care mi-a îngreunat sarcina.

## Ce am învățat construindu-l de fapt

Mi-am intensificat documentarea. Pe lângă Fowler, **Building Microservices** de Sam Newman s-a dovedit o resursă indispensabilă.

Sfatul lui Newman, privind retrospectiv, era sfatul pe care ar fi trebuit să-l urmez: mai întâi restructurează aplicația existentă în module care reflectă contextele delimitate ale domeniului. Abia după ce dezvoltatorii sunt mulțumiți de granițe, *atunci* separi modulele în servicii proprii. Motivul este că e mult mai ușor să desfaci și să rescrii module cu granițe proaste decât să desfaci și să rescrii servicii întregi, cu tot codul lor de infrastructură suplimentar și cu resursele lor persistente.

Nu am urmat sfatul acesta. Nerăbdător să construiesc o componentă a mea, am mers mai departe cu serviciul de sesiuni.

Am ales un stack diferit doar marginal de cel al monolitului și am început să construiesc. Serviciul în sine a prins formă repede: câteva săptămâni pentru o aplicație de sine stătătoare cu un API REST. Partea grea nu era acolo. Partea grea a fost să-l fac să comunice cu monolitul.

Gestionarea sesiunilor s-a dovedit a fi puternic cuplată cu restul codului. Înlocuirea apelurilor de funcții cu apeluri API a fost o muncă lentă. Pentru că serviciul de sesiuni și monolitul aveau scheme de baze de date separate, a trebuit să rescriu orice logică din monolit care folosea resursele de sesiune din vechea bază de date, restructurând datele la granița aplicației ca să rămână compatibili clienți precum widgetul nostru JavaScript.

Integrarea a durat mai mult decât construirea. Și asta fără majoritatea costurilor suplimentare pe care le aduc în mod obișnuit microserviciile: descoperirea serviciilor, logarea, monitorizarea, urmărirea distribuită. Mai rău, cuplarea strânsă făcea ca modificările să se răspândească în multe zone ale codului. Cum echipa lucrase în paralel în tot acest timp, integrarea și lansarea în producție a serviciului de sesiuni ar fi cerut mult mai multă coordonare decât estimasem.

## Evaluarea sinceră

Serviciul ar putea ajunge curând în producție. Dar acum simt că ar fi trebuit să urmez sfatul lui Newman și să-mi concentrez efortul pe modularizarea aplicației existente. Beneficiul unui singur serviciu care trăiește de unul singur este marginal. Beneficiul real vine din spargerea întregului, cel puțin în servicii cu granularitate mare, care comunică cât mai puțin între ele. Asta cere granițe de componente bine gândite, iar noi nu ajunseserăm încă acolo.

Încă mai cred în microservicii ca idee. Văd încercarea mea ca pe un experiment util. Am învățat enorm despre arhitectura aplicațiilor, modelarea domeniului și principiile REST, iar lecțiile acestea au avut efecte și în alte părți ale codului nostru.

Pentru oricine se gândește la o tranziție similară, recomandările mele sincere:

- Documentează-te cât mai mult pe subiect înainte să te angajezi
- Amână lucrarea până când ești cu adevărat sigur pe codul existent și pe modelul tău de domeniu
- Ține minte că există și alte moduri de a aduce stabilitate și reziliență unui monolit. Testele unitare și funcționale automate ajută enorm. Dezvoltarea ghidată de teste reduce regresiile. Scalarea orizontală face lansările mai puțin dureroase
- Începe prin a modulariza monolitul înainte de a extrage servicii

Shoprocket își va continua drumul. Partea 2 e cea în care lucrurile devin mai interesante.

---

*Publicat inițial ca primul dintr-o serie scurtă care documentează migrarea timpurie a Shoprocket de la un monolit PHP. Întregul parcurs, inclusiv greșelile corectate în iterațiile ulterioare, a continuat de-a lungul fiecărei rescrieri majore a platformei de atunci.*

---

- HTML version: https://v3.shoprocket.io/ro/blog/drumul-shoprocket-spre-microservicii-partea-1-ce-am-gresit-cu-monolitul
- Language: Română (ro)
- Also in: [العربية](https://v3.shoprocket.io/ar/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Deutsch](https://v3.shoprocket.io/de/blog/shoprocket-microservices-teil-1-monolith-zerlegen-fehler.md), [Ελληνικά](https://v3.shoprocket.io/el/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [English](https://v3.shoprocket.io/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Español](https://v3.shoprocket.io/es/blog/shoprocket-microservicios-parte-1-lo-que-hice-mal-monolito.md), [Français](https://v3.shoprocket.io/fr/blog/shoprocket-vers-les-microservices-partie-1-decouper-le-monolithe.md), [עברית](https://v3.shoprocket.io/he/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [हिन्दी](https://v3.shoprocket.io/hi/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Bahasa Indonesia](https://v3.shoprocket.io/id/blog/perjalanan-shoprocket-menuju-microservices-bagian-1-salah-memecah-monolit.md), [Italiano](https://v3.shoprocket.io/it/blog/viaggio-di-shoprocket-verso-i-microservizi-parte-1-cosa-ho-sbagliato-sul-monolite.md), [日本語](https://v3.shoprocket.io/ja/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Lietuvių](https://v3.shoprocket.io/lt/tinklarastis/shoprocket-kelione-i-mikropaslaugas-1-dalis.md), [Norsk](https://v3.shoprocket.io/nb/blogg/shoprockets-vei-mot-mikrotjenester-del-1-hva-jeg-tok-feil-av.md), [Nederlands](https://v3.shoprocket.io/nl/blog/shoprocket-microservices-deel-1-monoliet-opknippen.md), [Polski](https://v3.shoprocket.io/pl/blog/droga-shoprocket-do-mikroserwisow-czesc-1-rozbijanie-monolitu.md), [Português](https://v3.shoprocket.io/pt/blog/jornada-do-shoprocket-para-microsservicos-parte-1-o-que-errei-ao-quebrar-o-monolito.md), [Русский](https://v3.shoprocket.io/ru/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [ไทย](https://v3.shoprocket.io/th/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Türkçe](https://v3.shoprocket.io/tr/blog/shoprocket-mikroservis-yolculugu-1-monoliti-parcalarken-yanlis-yaptiklarim.md), [中文](https://v3.shoprocket.io/zh/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md)
