Durant set mòduls hem anat construint peces: límits i dades (mòdul 2), contractes i esdeveniments (3), codi (4), desplegament (5), operació (6) i seguretat (7). A cadascuna hi apareixia TechCorp com a exemple, però mai no hem explicat la història sencera en ordre: què va fer l'equip primer, què després, què es va torçar pel camí i amb quin resultat. Aquesta lliçó és aquest relat, el que el tancament del mòdul 7 anunciava: com es va executar la migració pas a pas. És un cas d'estudi, no una lliçó de tècnica: quan una fase faci servir l'strangler fig, l'outbox o el canary, remetrem a la lliçó on s'explica en lloc de repetir-la, i no escriurem codi (els serveis que falten s'implementen a 08-02 i el sistema complet es desplega a 08-03).
Recorrerem els ~13 mesos ficticis de la migració (juliol de 2025 a agost de 2026): la fase 0 dels deures previs, les sis fases d'extracció en l'ordre decidit a 02-02 (catàleg, inventari, notificacions, pagaments, comandes, clients), l'apagada del monòlit, una taula cronològica, les mètriques abans i després, els costos reals i tres ensopegades que convé conèixer per no repetir-les. Totes les dates, xifres i noms són inventats, però versemblants per a una botiga de 3.000 comandes diàries i 25 tècnics.
Contingut
- Punt de partida i pla (juliol de 2025)
- Fase 0: els deures previs (juliol–setembre de 2025)
- Fase 1: catàleg, la primera extracció i el primer Black Friday (setembre–novembre de 2025)
- Fase 2: inventari, el primer consumidor d'esdeveniments (desembre de 2025–gener de 2026)
- Fase 3: notificacions, el correu fora del procés (febrer de 2026)
- Fase 4: pagaments, diners i cautela (març–abril de 2026)
- Fase 5: comandes, la saga substitueix la transacció (maig–juliol de 2026)
- Fase 6: clients i l'apagada del monòlit (juliol–agost de 2026)
- Taula cronològica de la migració
- Mètriques abans i després
- Costos reals i el que va sortir malament
- L'arquitectura final
- Punt de partida i pla (juliol de 2025)
El juliol de 2025 la Marta presenta a direcció el pla que va sortir de l'anàlisi de 01-04 i 01-05: techcorp-shop és un monòlit Node.js/Express sobre una única PostgreSQL amb cinc problemes mesurables (desplegaments de dijous amb 4 de 12 reversions, 50 minuts sense vendre al Black Friday anterior, un 20 % del temps en coordinació, la fuita de memòria del correu que va tombar els cobraments i la taula atributs_producte). La proposta no és "reescriure la botiga", sinó extreure sis serveis un a un, amb la botiga venent, en l'ordre de 02-02: catàleg → inventari → notificacions → pagaments → comandes → clients.
Tres condicions que la Marta posa i que governen tot el que ve després:
| Condició | Conseqüència pràctica |
|---|---|
| La botiga no s'atura. Cap tall planificat de més d'uns minuts; cap campanya en risc. | Tot es fa amb strangler fig i branch by abstraction (02-02) i amb marxa enrere per configuració. |
| Cada fase aporta valor visible en menys d'un trimestre. | El catàleg va primer perquè resol el problema més car (les caigudes de campanya) amb el mínim risc. |
| Màxim dues tecnologies de base de dades i un sol llenguatge. | PostgreSQL + MongoDB (02-04); Node.js 20 a tots els serveis (04-01). |
I una regla del Luis que apareixerà a cada fase: "si es fa més d'un cop per servei, s'automatitza abans del segon" (04-01, 05-03). És la que converteix una migració de sis serveis en una cosa que un equip de 25 persones pot sostenir.
- Fase 0: els deures previs (juliol–setembre de 2025)
La primera decisió important va ser no extreure res durant tres mesos. Els quatre prerequisits de 01-04 (CI/CD, contenidors, observabilitat, cultura de propietat) no existien, i extreure un servei sense ells hauria produït un monòlit distribuït operat a mà. El que es va fer:
- Organització. Els equips "back-end / front-end / sistemes" es van reorganitzar en els quatre equips de 02-01: Experiència de compra (catàleg i clients), Comandes (comandes i inventari, amb el Luis), Pagaments i comunicacions (pagaments i notificacions) i Plataforma (gateway, Kubernetes, CI/CD, observabilitat). Cada equip, amo de les seves àrees dins del monòlit des del primer dia: la llei de Conway aplicada abans de tocar el codi.
- CI per al monòlit. El
ci.ymlde 05-03 en la seva versió mínima: proves a cada PR, imatge Docker del monòlit (Dockerfilemulti-stage de 05-01) publicada aghcr.io/techcorp/techcorp-shop:sha-…. La suite de 40 minuts es va paral·lelitzar fins a 12. Encara es desplegava els dijous, però amb una imatge reproduïble. - Kubernetes i el gateway. Plataforma va aixecar el clúster (05-02), hi va desplegar el monòlit (tres rèpliques, sondes de 03-05) i va posar el gateway del port 8080 al davant amb totes les rutes apuntant al monòlit (03-04). Durant sis setmanes el gateway no va fer res més que reenviar i registrar: és el requisit de l'strangler fig de 02-02, "la façana existeix abans de la primera extracció".
- Observabilitat mínima. Logs estructurats amb pino enviats a Loki, mètriques RED del gateway i del monòlit a Prometheus, un panell a Grafana (06-01). Encara sense traces.
- El monòlit modular. La matriu taula × àrea de 02-02 havia destapat que
crearComandaescrivia aestoci apagamentssense ser-ne l'amo. Abans de moure res, l'equip del Luis va crear dins del monòlit els mòdulsmagatzem.reservar()/magatzem.alliberar()ipagaments.registrarCobrament(), icrearComandava passar a invocar-los en lloc d'escriure SQL aliè. Va ser la feina menys vistosa de la migració i la que més la va accelerar: quan van arribar les fases 2 i 4, la costura ja estava feta. @techcorp/comu-httpv0.1 (04-01): logger,X-Request-Id, errors RFC 7807, rutes de salut. Es va adoptar primer al monòlit, perquè el primer servei nasqués amb la mateixa cara.
Resultat de la fase 0 (30 de setembre de 2025): cap servei extret, cap problema de negoci resolt encara… i una plataforma sobre la qual les sis fases següents es recolzarien sense tornar a discutir eines.
- Fase 1: catàleg, la primera extracció i el primer Black Friday (setembre–novembre de 2025)
servei-cataleg (3001, MongoDB) es va construir tal com es veu a 04-02, amb la plantilla plantilla-servei-node acabada de crear. La seqüència va ser la de 02-04 §6, i val la pena veure-la amb dates perquè és el motlle de totes les altres:
| Setmana | Pas | Tècnica (lliçó) |
|---|---|---|
| 1–3 (set) | Servei amb GET /v1/productes en les seves tres formes i contracte OpenAPI. Proves de component i de contracte. |
04-02, 04-05 |
| 4 | Càrrega inicial amb scripts/migrar-cataleg.js (idempotent, upsert): 41.000 productes i els seus atributs clau-valor convertits en documents. |
02-04 §6 |
| 5–6 (oct) | Sincronització: el monòlit publica producte.actualitzat a RabbitMQ (el seu primer esdeveniment) i Catàleg el consumeix. RabbitMQ entra en producció aquí. |
03-02 |
| 7 | Comparació en ombra: el monòlit llegeix de les dues fonts i registra discrepàncies. Es van trobar 212 productes amb preu diferent (arrodoniment de l'script) i 3 esdeveniments perduts per un reinici: es va corregir l'script i es va tornar a llançar (idempotent). |
02-04 §6 |
| 8 | Tall de lectures: el gateway encamina /api/v1/productes/* a Catàleg (strangler) i crearComanda passa a RepositoriProductesHTTP amb CATALEG_REMOT=true al 10 %, 50 %, 100 % en tres dies. |
02-02 §4, 03-04 |
| 9 (nov) | Tall d'escriptures: el panell d'administració de productes passa a servei-cataleg; el monòlit deixa d'escriure a productes. |
02-04 |
| 10–13 | La taula productes queda en només lectura; retirada el 15 de desembre, després de confirmar que només un informe mensual la feia servir (es va reescriure sobre una vista de només lectura exportada per Catàleg; a la fase 6 passaria a la BD de lectura de l'apartat 8). |
02-04 §6 |
El primer desplegament canary de TechCorp va ser el de Catàleg (05-04): 10 % de trànsit durant dues hores mirant el panell RED. I el primer HPA també (06-04): minReplicas: 2, maxReplicas: 20, amb la memòria cau Redis de 30 s davant de MongoDB.
L'examen va arribar el 28 de novembre de 2025. Amb el catàleg separat i autoescalat, el Black Friday va transcórrer així: navegació ×22 respecte d'un dia normal, Catàleg va passar de 2 a 14 rèpliques en 12 minuts, p95 de GET /v1/productes en 140 ms, i la creació de comandes i els cobraments —encara al monòlit— no van notar res: 0 minuts sense vendre davant dels 50 de l'any anterior. La Marta va portar aquesta dada a direcció i la migració va deixar de discutir-se. Va ser també el moment en què va quedar clar que el catàleg era el 70 % del cost d'infraestructura de la campanya anterior: escalar només el que se satura va costar un terç que replicar el monòlit a deu servidors.
- Fase 2: inventari, el primer consumidor d'esdeveniments (desembre de 2025–gener de 2026)
servei-inventari (3006, PostgreSQL) va ser el primer servei amb estat de negoci delicat i el primer que consumeix esdeveniments. El que va canviar respecte del catàleg:
- Model de reserves. El monòlit només tenia
estoc.reservat; el servei neix amb les taulesestoc,reserves(ambexpira_en) ilinies_reservade 02-04 §7.2. La reserva passa de ser un comptador a ser una entitat amb estats ACTIVA/CONSUMIDA/ALLIBERADA (02-03) i amb caducitat als 900 s. - Branch by abstraction de la reserva. El mòdul
magatzemcreat a la fase 0 va rebre la seva segona implementació (ReservaEstocHTTP→POST /v1/reservesde 03-01) i el flagINVENTARI_REMOT. Durant tres setmanes el monòlit va reservar per HTTP; elSENSE_ESTOCcontinuava sent un409síncron acrearComanda. - El primer consumidor. Com que el monòlit ja publicava esdeveniments des de la fase 1, Inventari va començar a consumir
comanda.confirmadaicomanda.cancelladade la cuainventari.comandesper consumir o alliberar la reserva (03-02). Amb això van arribar la primera DLQ amb missatges (unacomanda.cancelladad'una comanda la reserva de la qual s'havia fet encara per la via SQL antiga: missatge verinós, sense reserva a alliberar) i la primera versió deprocessarUnCopfora de Comandes. - La regla del Luis en acció. L'outbox i la idempotència de consumidors s'havien escrit a Comandes (encara dins del monòlit) per publicar
comanda.confirmada; en necessitar-los a Inventari, es van moure a@techcorp/comu-http(missatgeria/outbox,missatgeria/idempotencia) en lloc de copiar-los. És la versió que fan servir els quatre serveis de 08-02. - KEDA (06-04) va aparèixer aquí: escalar Inventari per la longitud d'
inventari.comandesva ser més útil que fer-ho per CPU.
Les rebaixes de gener (7 de gener de 2026) van ser la prova de càrrega: comandes ×3,5, Inventari de 2 a 6 rèpliques, cap incidència. La migració de dades d'estoc (12.000 files) va ser trivial comparada amb la del catàleg: càrrega inicial, doble lectura en ombra durant una setmana, tall.
- Fase 3: notificacions, el correu fora del procés (febrer de 2026)
L'extracció més curta (quatre setmanes) i una de les més agraïdes. serveis/correu.js i les seves plantilles es van convertir en servei-notificacions (3005), sense base de dades tret de la taula enviaments per no reenviar (02-04 §7.4). Consumeix comanda.confirmada i comanda.cancellada de notificacions.comandes; el monòlit va deixar de cridar correu.enviar() a crearComanda i va passar a confiar en l'esdeveniment.
Dos efectes immediats:
- La fuita de memòria del correu va deixar de ser un problema del monòlit. La fallada del proveïdor de correu va tornar a passar el 3 de març de 2026 (connexions acumulades): aquest cop el pod de Notificacions va ser reiniciat per la seva
livenessProbedues vegades, els missatges van esperar a la cua i anotificacions.comandes.reintent(06-03), i cap cobrament no se'n va veure afectat. L'incident 4 de 01-05, tancat per disseny. - La resposta de
crearComandava baixar 300 ms de mitjana: l'enviament SMTP ja no era dins de la petició.
Va ser també la fase en què Notificacions va estrenar els reintents diferits amb TTL i la DLQ tal com van quedar a 06-03, perquè un proveïdor de correu retorna 503 sovint: reintentar de seguida era inútil.
- Fase 4: pagaments, diners i cautela (març–abril de 2026)
servei-pagaments (3003, PostgreSQL) es va endur serveis/passarellaPagament.js i devolucionsControlador.js. Va ser l'extracció amb més revisió i menys pressa, i la que més peces de seguretat va estrenar:
pagaments.registrarCobrament()→servei-pagamentsamb branch by abstraction i flag; el monòlit continuava sent qui demanava cobrar (síncron, dins decrearComanda), però qui parlava amb la passarel·la ja era el servei.- Tokenització i abast PCI (07-03): el formulari de targeta va passar a parlar directament amb la passarel·la; TechCorp només rep
tok_…. L'abast PCI DSS va quedar reduït al servei i al seu Secretpagaments-passarella. - Webhook signat
POST /v1/webhooks/passarellaamb HMAC, finestra temporal iwebhooks_rebuts(07-02 §9): la passarel·la confirma cobraments i devolucions de manera asíncrona. - Auditoria (07-03 §9): taula
auditoriade només inserció per a canvis manuals d'estat de pagament i reemborsaments. UNIQUE (comanda_id)apagamentsi clau d'idempotència =comandaIdcap a la passarel·la (06-03 ex. 1): la garantia d'"una comanda, un cobrament" va passar de la transacció del monòlit a dues restriccions explícites.- Desplegament canary obligatori (05-04) amb revisió humana del PR de promoció (05-03 §8), com correspon a un servei que mou diners.
Una dada: l'equip va dedicar una setmana sencera a la prova de resiliència (06-03 §11) contra la passarel·la fictícia —503, timeouts, respostes duplicades— abans de moure un cèntim real. Cap cobrament duplicat en producció des de llavors.
- Fase 5: comandes, la saga substitueix la transacció (maig–juliol de 2026)
La fase central, la més llarga (onze setmanes) i la que dona sentit a les anteriors. Quan va arribar, Catàleg, Inventari, Notificacions i Pagaments ja eren serveis i el monòlit ja publicava i consumia esdeveniments: crearComanda continuava sent una funció que cridava els altres per HTTP i coordinava amb la seva transacció local. El que va canviar:
servei-comandes(3002) tal com es va construir a 04-04: agregatComanda, màquina d'estats de 02-05,POST /v1/comandes→202, outbox amb relay, consumidorscomandes.sagaicomandes.clients.- La saga per coreografia va substituir la transacció: Inventari va passar a reaccionar a
comanda.creada(en lloc de rebrePOST /v1/reservessíncron), Pagaments aestoc.reservat(en lloc de la crida del monòlit), Comandes apagament.confirmat. El flagSAGA_ASINCRONAal monòlit va permetre, durant dues setmanes, que un percentatge de comandes seguís la via nova mentre la resta feia servir l'antiga; el panell "Saga de comandes" (06-01) comparava totes dues. - El canvi de contracte visible:
POST /comandesva deixar de respondre201 CONFIRMADAi va passar a202 PENDENT+ polling amb ETag (03-01). Va ser l'únic canvi de la migració que va exigir coordinació amb l'equip de front-end i amb l'app mòbil (a través delbff-mobil, 03-04): dos sprints d'avís, capçaleraDeprecationa la ruta antiga (03-06). - El vigilant de
TIMEOUT_PAGAMENT(06-03 §9) i elCronJob reconciliar-reserveses van escriure abans del tall, no després d'un incident: la saga per coreografia sense vigilant és una saga que s'encalla. - Tall de l'strangler:
/api/v1/comandes/*al servei el 15 de juny de 2026 al 10 %, 100 % el 19;SAGA_ASINCRONA=trueal 100 % el 26 de juny; migració dels 2,1 milions de comandes històriques a la BDcomandesen tres nits per lots (càrrega inicial idempotent + esdeveniments de canvi d'estat en ombra); retirada del codi decrearComandadel monòlit el 10 de juliol.
I el 22 de juliol de 2026, INC-2031 (06-05 §10): un estoc.reservat amb linies: null publicat per Inventari 2.3.0 va encallar pagaments.estoc 40 minuts; 61 comandes afectades, 38 cancel·lades pel vigilant. És l'incident que va donar forma definitiva a l'operació: cues de reintent i DLQ a la primera per a errors permanents a Pagaments, alertes DlqAmbMissatges i SagaTardanaBurn*, validació dels esdeveniments de sortida contra l'esquema AsyncAPI a Inventari, i el runbook comu/dlq amb scripts/reprocessarDlq.js. Sense INC-2031, mitja lliçó 06-05 no existiria; amb ell, el sistema va quedar com és avui.
- Fase 6: clients i l'apagada del monòlit (juliol–agost de 2026)
servei-clients (3004) va ser l'últim per les raons de 02-02: identitat i dades personals, i client_id era a tot arreu. En ser l'últim, es va beneficiar de tot l'anterior:
- Keycloak (07-01) havia entrat en producció a l'inici de la fase 5, federant les credencials de la taula
clientsdel monòlit per poder protegir/api/v1/comandes/*amb JWT. A la fase 6 es va completar: les identitats es van migrar al realmtechcorp, l'alta de client va passar aservei-clients, que escriu l'atributclientIda Keycloak, i el claimclientIdviatja al token; el monòlit va deixar de tenir sessió. clients_refa Comandes (02-04) s'anava alimentant ambclient.actualitzatpublicat pel monòlit des de la fase 5; només va canviar el productor.- RGPD (07-03 §8):
DELETE /v1/clients/{id}→ anonimització +client.eliminat; Comandes esborra la rèplica i anonimitza adreces antigues. GET /v1/clients/{id}amb la regla "el mateix client, operador o token de servei ambclients:llegir" (07-01 ex. 2), iPOST /v1/comandesamb la comprovacióclientIddel cos =clientIddel token.
L'apagada del monòlit va tenir lloc el 7 d'agost de 2026. El que hi quedava a dins en aquell moment i on va anar a parar:
| Resta al monòlit | Destinació |
|---|---|
Informes de vendes i panells de direcció (els JOIN de quatre taules de 02-04 §8) |
Base de dades de lectura techcorp-analitica (PostgreSQL) alimentada per esdeveniments (comanda.confirmada, producte.actualitzat, client.actualitzat) amb un consumidor propi; els informes es van reescriure contra ella. És el CQRS "a escala d'empresa" de 02-05. |
| Panell d'administració intern (diverses àrees) | Aplicació web lleugera que consumeix les APIs pel gateway amb rol operador. |
| Exportació nocturna a l'ERP | Consumidor d'esdeveniments que genera el fitxer. |
Taula comandes històrica en només lectura |
Migrada a comandes a la fase 5; la còpia del monòlit es va conservar un mes i es va arxivar. |
# 2026-08-07 10:30 — l'últim commit del monòlit: el gateway deixa de tenir ruta comodí
kubectl -n techcorp scale deployment techcorp-shop --replicas=0 # ningú no ho nota: fa tres setmanes que no rep trànsit
# 2026-08-21 — després de dues setmanes a zero rèpliques sense cap petició al comodí (mètrica gateway_rutes_monolit_total = 0): esborrat
kubectl -n techcorp delete deployment,service,configmap -l app=techcorp-shopAquest scale --replicas=0 durant dues setmanes abans d'esborrar és l'última aplicació del principi de la fase 1: no tenir pressa a retirar el que és antic.
- Taula cronològica de la migració
| Fase | Dates | Servei | Tècnica principal | Lliçons | Risc principal | Resultat |
|---|---|---|---|---|---|---|
| 0 | jul–set 2025 | — (monòlit modular, plataforma) | CI, contenidors, K8s + gateway al davant, observabilitat mínima, quatre equips, retornar les escriptures d'estoc/pagaments al seu amo |
01-04, 02-02, 03-04, 05-01/02/03, 06-01 | Tres mesos "sense resultats" | Base per a tota la resta; suite de 40 → 12 min |
| 1 | set–nov 2025 | servei-cataleg |
Strangler de /productes, RepositoriProductesHTTP + CATALEG_REMOT, càrrega inicial + esdeveniments + ombra, HPA, Redis |
02-02, 02-04, 04-02, 05-04, 06-04 | Discrepàncies de dades | Black Friday sense caiguda (0 min vs 50); cost de campanya ÷3 |
| 2 | des 2025–gen 2026 | servei-inventari |
Reserves amb expira_en, INVENTARI_REMOT, primer consumidor, primera DLQ, KEDA; outbox/idempotència a comu-http |
02-04, 03-01, 03-02, 06-04 | Vendre el que no hi ha | Rebaixes ×3,5 sense incidència |
| 3 | feb 2026 | servei-notificacions |
Consumidor de comanda.confirmada/cancellada, reintents amb TTL + DLQ |
03-02, 06-03 | Correus duplicats/perduts | Fuita de memòria aïllada; crearComanda −300 ms |
| 4 | mar–abr 2026 | servei-pagaments |
Tokenització, webhook HMAC, auditoria, UNIQUE(comanda_id), canary amb revisió |
05-04, 06-03, 07-02, 07-03 | Cobraments duplicats / PCI | Zero cobraments duplicats; abast PCI mínim |
| 5 | mai–jul 2026 | servei-comandes |
Saga per coreografia, outbox, 202 + ETag, vigilant, reconciliació, SAGA_ASINCRONA |
02-05, 03-01, 04-04, 06-03, 06-05 | Sagues encallades | Comandes desplegable a diari; INC-2031 (40 min) i el seu postmortem |
| 6 | jul–ago 2026 | servei-clients + apagada |
Keycloak + clientId, clients_ref, RGPD, BD de lectura per a BI |
02-04, 07-01, 07-03 | Dades personals | Monòlit a 0 rèpliques el 7/8/2026 |
- Mètriques abans i després
Les quatre mètriques DORA de 05-03 §12 mesurades l'agost de 2026 (mitjana dels sis serveis), més les de negoci i organització que la Marta va presentar a direcció:
| Mètrica | Abans (juny 2025) | Després (agost 2026) | Com es mesura |
|---|---|---|---|
| Freqüència de desplegament | 1 cada 1–2 setmanes (dijous a la nit), tota la botiga | 11 al dia en total (Catàleg 3–4, Comandes 2–3, resta 1–2) | Syncs d'Argo CD per servei |
| Lead time de canvis | 9 dies de mediana | 4 hores de mediana (23 min per a hotfixes) | Data de commit → data de sync |
| Taxa de fallada de canvis | 33 % (4/12 reversions) | 6 % (5 reversions/rollbacks de 82 desplegaments al juliol) | Incidents o rollbacks / desplegaments |
| MTTR | 50 min (Black Friday); ~2 h de mediana en desplegaments fallits | 9 min de mediana (argocd app rollback o canary-weight=0) |
Des de l'alerta fins al tancament |
| Disponibilitat de "crear comanda" | 99,5 % mensual estimada (no es mesurava) | 99,93 % (SLO 99,9 %, 06-05) | SLI slo:comandes_disponibilitat |
| Latència catàleg p99 en campanya | > 8 s (saturació) | 280 ms | SLI de latència |
| Temps de coordinació (equip de Comandes) | ~20 % | ~7 % (revisions de contracte i PRs de promoció) | Enquesta trimestral + temps en PRs creuats |
| Suite de proves | 40 min (tot) | 4–7 min per servei | CI |
| Cost d'infraestructura de campanya | ×3,3 (deu servidors del monòlit) | ×1,4 (només Catàleg i Inventari escalen) | Factura del proveïdor |
Dos avisos honestos que la Marta va afegir a la taula: l'"abans" de disponibilitat és una estimació (no hi havia SLI, cosa que ja és una dada en si mateixa), i la taxa de fallada del 6 % inclou INC-2031, que va ser el pitjor incident de l'any i tot i així va durar menys que el millor desplegament de dijous.
- Costos reals i el que va sortir malament
El que va costar. Un any de migració no surt gratis, i convé tenir les xifres (fictícies, però d'ordre realista) per a l'exercici de 08-04:
| Cost | Magnitud | Comentari |
|---|---|---|
| Temps d'equip | ~40 % de la capacitat de desenvolupament durant 13 mesos (unes 10 persones equivalents) | La meitat a la fase 5. La resta va continuar lliurant funcionalitat; el negoci no es va aturar. |
| Infraestructura | +35 % el primer any (clúster, RabbitMQ, observabilitat, Keycloak, entorns d'staging); −20 % respecte de l'any anterior en campanyes | Amb el catàleg escalat per separat, el balanç net a final d'any va ser lleugerament positiu per l'estalvi en campanyes. El cost mensual detallat és a 08-03. |
| Corba d'aprenentatge | Kubernetes, RabbitMQ, OpenTelemetry, Keycloak, Pact: cadascun va costar a algú 2–4 setmanes | Mitigada per Plataforma (plantilles, workflow reutilitzable) i pel fet de fer-ho en ordre. |
| Eines de pagament | Registre privat, Pact Broker gestionat, gestor de secrets | Menors; es van justificar una a una. |
El que va sortir malament. Tres ensopegades que l'equip explica sense vergonya perquè són les que més ensenyen:
- El dual write que es va intentar (fase 1, octubre de 2025). La primera versió de la sincronització del catàleg escrivia la taula
productesi el document de MongoDB a la mateixa funció del monòlit, "per no muntar RabbitMQ encara". En una setmana la comparació en ombra va trobar 40 productes divergents: un timeout de MongoDB, una excepció entre les dues escriptures, i cap transacció que les cobrís (02-04 §6). Es va llençar el codi, es va avançar RabbitMQ i es va publicarproducte.actualitzatdes de la font de veritat. La lliçó es va convertir en regla escrita: una escriptura, a l'amo; la còpia, per esdeveniments. servei-descomptes, el nanoservei (fase 4, abril de 2026). Màrqueting va demanar cupons per a les rebaixes de primavera i l'equip d'Experiència de compra, amb ganes d'estrenar plantilla, va crear un servei amb una taulacuponsi un únic endpointPOST /v1/descomptes/calcular, cridat de manera síncrona percrearComandaa cada comanda. Va afegir 40 ms a cada comanda, un desplegament més, una dependència més al camí crític i cap capacitat de negoci autònoma (02-01: "es descriu en una frase sense 'i'?" sí, però "té dades i cicle de vida propis?" no). A la fase 5 es va reabsorbir dins deservei-comandescom a mòduldomini/descomptes.jsamb la taula dins de la BDcomandes, exactament el que l'exercici 2 de 02-02 havia recomanat. Si algun dia les promocions creixen (campanyes, regles, segments), tornaran a sortir; avui són dotze regles i una taula.- La cardinalitat que va tombar Prometheus (fase 3, febrer de 2026). Un consumidor de Notificacions va etiquetar
http_requests_totalamb la ruta sense plantilla (/v1/comandes/com-3f9a1c2ben lloc de/v1/comandes/{id}) i un altre va afegircomandaIdcom a etiqueta a un comptador. En cinc dies Prometheus va passar de 60.000 a 2,4 milions de sèries i el pod va morir per memòria; durant 25 minuts no hi va haver mètriques ni alertes. La correcció (06-01 §11): etiquetes només amb valors acotats,rutades dereq.route.path, una regla de linting de mètriques acomu-httpi un límitsample_limita l'scrape. És el motiu pel qual la mètricacomandes_cancellades_totalportamotiu(quatre valors) i maicomandaId.
I una quarta, menor però freqüent: durant dos mesos van conviure el ci.yml de 80 línies copiat a tres repositoris amb tres petites diferències; el workflow reutilitzable de 05-03 §11 va arribar "abans del quart", no "abans del segon". La regla del Luis també s'incompleix de vegades.
- L'arquitectura final
Així queda TechCorp l'agost de 2026, amb el monòlit apagat. Comparat amb el diagrama de 01-05 §7 (l'objectiu) hi ha tres diferències: no hi ha Istio (05-05: avaluat i posposat; mTLS amb Linkerd quan ho demani l'auditoria de Pagaments), sí que hi ha una BD de lectura per a analítica, i Redis, Keycloak i la pila d'observabilitat tenen nom propi.
flowchart TB
subgraph Extern
WEB[botiga-web / bff-mobil :3010]
PSP[Passarel·la de pagament]
SMTP[Proveïdor de correu]
end
WEB -->|HTTPS + JWT| ING[Ingress api.techcorp.example<br/>cert-manager]
ING --> GW[API Gateway :8080<br/>requereixToken, rate limit]
KC[Keycloak realm techcorp] -. JWKS .-> GW
GW -->|/api/v1/productes| CAT[servei-cataleg :3001<br/>HPA 2-20 + Redis]
GW -->|/api/v1/comandes| PED[servei-comandes :3002<br/>canary]
GW -->|/api/v1/clients| CLI[servei-clients :3004]
PSP -->|webhook HMAC| PAG
CAT --> MDB[(MongoDB cataleg)]
PED --> PGP[(PG comandes)]
CLI --> PGC[(PG clients)]
INV[servei-inventari :3006<br/>KEDA 2-10] --> PGI[(PG inventari)]
PAG[servei-pagaments :3003<br/>canary] --> PGG[(PG pagaments)]
NOT[servei-notificacions :3005] --> SMTP
PAG --> PSP
PED -->|GET productes / clients| CAT
PED --> CLI
PED <-.-> MQ[(RabbitMQ techcorp.esdeveniments<br/>amqps, vhost techcorp)]
MQ <-.-> INV
MQ <-.-> PAG
MQ -.-> NOT
MQ -.-> ANA[consumidor analitica] --> PGA[(PG techcorp-analitica<br/>informes / BI)]
CLI -.->|client.actualitzat / eliminat| MQ
subgraph Plataforma
OBS[Prometheus · Grafana · Loki · otel-collector · Jaeger]
ARGO[Argo CD ← techcorp/plataforma]
VAULT[Vault + ESO]
end
El que no es veu al diagrama i és tan important com el que s'hi veu: les NetworkPolicies deny-all de 07-04 (a Inventari només li parla Comandes; només Pagaments surt a Internet), els SLOs i les onze alertes de 06-05, els runbooks a techcorp/plataforma/runbooks/, i quatre equips que despleguen sense demanar permís a ningú.
Errors Comuns i Consells
- Saltar-se la fase 0. És la temptació més forta ("comencem per alguna cosa visible") i la que es paga més cara: sense gateway no hi ha strangler, sense CI no hi ha confiança, sense observabilitat no hi ha diagnòstic. Tres mesos de deures van estalviar un any.
- Extreure el core primer. Comandes va ser el cinquè perquè depenia de tots; extreure'l primer hauria produït un monòlit distribuït amb cinc crides al monòlit per comanda.
- Esborrar el que és antic el dia del tall. La taula
productesen només lectura durant sis setmanes i el monòlit a zero rèpliques durant dues van evitar dos incidents segurs (l'informe mensual i una integració oblidada). - Mesurar només al final. L'"abans" de disponibilitat és una estimació perquè no es mesurava. Instrumenta el monòlit abans de tocar-lo: és la teva línia base i el teu argument davant de direcció.
- Confondre ensopegada amb fracàs. El dual write, el nanoservei i la cardinalitat van costar dies, no mesos, perquè cadascun es va detectar amb una eina que ja existia (ombra, panell RED, alerta de Prometheus caigut). L'objectiu no és no equivocar-se: és equivocar-se barat i aprendre'n per escrit.
- Consell: guarda una taula cronològica com la de l'apartat 9 des del primer dia, amb la columna "risc principal" omplerta abans de començar cada fase. És la millor eina de comunicació amb negoci i el millor material per al postmortem del projecte.
Exercicis
Exercici 1: Reordenar amb una altra restricció
Imagina que TechCorp hagués tingut, el juliol de 2025, una auditoria PCI obligatòria el gener de 2026. Canviaria l'ordre d'extracció? Proposa un ordre alternatiu, indica quina fase s'avança i a quin cost, i quina part de la fase 0 passaria a ser imprescindible abans d'aquesta fase.
Exercici 2: Diagnosticar una ensopegada
Un equip explica que, durant la seva migració d'un catàleg, "les dades del servei nou es dessincronitzaven de tant en tant i ningú no sabia per què". Amb el que has après a la fase 1 i a l'apartat 11: enumera les tres causes més probables, l'eina que les hauria detectat i la tècnica que les evita.
Exercici 3: Llegir la taula de mètriques
Amb la taula de l'apartat 10: (a) quina mètrica demostra que la fase 1 va resoldre el problema 2 de 01-05? (b) per què la taxa de fallada del 6 % és millor encara que en nombre absolut de desplegaments fallits (5 al juliol) sigui més gran que abans (4 en un trimestre)? (c) Quina mètrica de la taula és la menys fiable i per què?
Solucions
Exercici 1. Sí: Pagaments passaria del quart al segon lloc (després de Catàleg), perquè al gener la passarel·la, la tokenització, el webhook HMAC, l'auditoria i el securityContext/NetworkPolicies de Pagaments estiguessin aïllats en un servei amb abast PCI mínim. Cost: Pagaments s'extrauria amb branch by abstraction des del monòlit (com a la fase 4 real) però abans que existís Inventari, de manera que continuaria cobrant per crida síncrona des de crearComanda més temps, i el seu consumidor d'estoc.reservat s'escriuria més tard (doble feina a l'adaptador). A més, l'equip estrenaria canary i revisió humana amb el servei més delicat, en lloc d'entrenar-se amb Catàleg. De la fase 0 passarien a imprescindibles abans de Pagaments: la retirada de l'escriptura a pagaments des de crearComanda (pagaments.registrarCobrament()), la gestió de secrets (07-04: el Secret pagaments-passarella no pot viure en un YAML) i les NetworkPolicies de "només Pagaments surt a Internet".
Exercici 2. (1) Dual write: el monòlit escriu a les dues fonts sense transacció comuna; una excepció o timeout entre totes dues deixa còpies divergents. Ho detecta la comparació en ombra; ho evita "una escriptura a l'amo + esdeveniments" (02-04 §6). (2) Esdeveniments perduts: el productor publica sense outbox (o el consumidor fa ack abans d'escriure) i un reinici perd missatges. Ho detecta l'ombra i la mètrica outbox_pendents/missatges sense ack; ho evita l'outbox transaccional (02-05 §7) i l'ack després de processar (03-02). (3) Esdeveniments desordenats o duplicats que trepitgen un valor nou amb un de vell. Ho detecta l'ombra (discrepàncies intermitents que "s'arreglen soles" al canvi següent); ho evita processarUnCop + comparació per actualitzatEn (04-04 ex. 2). Afegit: un script de càrrega inicial no idempotent que es va tornar a llançar a mitges (duplicats o valors antics); ho evita l'upsert (02-04).
Exercici 3. (a) "Latència catàleg p99 en campanya" (> 8 s → 280 ms) i sobretot la dada de negoci de l'apartat 3: 0 minuts sense vendre el 28/11/2025 davant de 50; el cost de campanya ×3,3 → ×1,4 confirma que s'escala només el que se satura. (b) Perquè la taxa es mesura per desplegament i el nombre de desplegaments s'ha multiplicat per més de 20: 5 fallades de 82 (6 %) davant de 4 de 12 (33 %). A més, cada fallada afecta un servei, es detecta en un canary al 10 % i es reverteix en minuts (MTTR 9 min), en lloc de revertir tota la botiga al cap de dues hores. És la relació DORA de 05-03: més desplegaments petits → menys fallades i menys MTTR. (c) La disponibilitat "abans" (99,5 %): és una estimació retrospectiva, perquè el monòlit no tenia SLI; i en menor mesura el temps de coordinació, que es basa en enquestes. La mateixa taula ho adverteix: sense mesura prèvia no hi ha línia base fiable, i això és una lliçó en si mateixa.
Conclusió
La migració de TechCorp no va ser una reescriptura sinó tretze mesos d'extraccions ordenades sobre una fase 0 de deures que no va produir cap servei i ho va fer possible tot: quatre equips amos de les seves àrees, CI i contenidors, un clúster amb el gateway al davant com a façana de l'strangler, observabilitat mínima i un monòlit modular en què crearComanda va deixar d'escriure a estoc i pagaments. Després, cada fase va resoldre un problema concret de 01-05 amb les tècniques dels mòduls anteriors: Catàleg (càrrega inicial, esdeveniments, ombra, flag, HPA) i el primer Black Friday sense caiguda; Inventari (reserves amb caducitat, primer consumidor, primera DLQ, KEDA); Notificacions (el correu fora del procés, fi de la fuita que tombava cobraments); Pagaments (tokenització, webhook HMAC, auditoria, canary amb revisió); Comandes (la saga per coreografia amb outbox i vigilant en lloc de la transacció, el 202, i INC-2031 com a mestre); Clients (Keycloak, clientId, RGPD) i l'apagada del monòlit amb l'analítica traslladada a una base de dades de lectura. Les mètriques expliquen el resultat —d'un desplegament quinzenal a onze al dia, de 9 dies a 4 hores de lead time, del 33 % al 6 % de fallades, de 50 a 9 minuts de recuperació, 99,93 % de disponibilitat de "crear comanda"— i les ensopegades (el dual write, servei-descomptes, la cardinalitat) expliquen el que va costar aprendre-ho.
Aquest relat ha remès constantment a codi que ja existeix (servei-cataleg de 04-02, servei-comandes de 04-04, el gateway de 03-04 i 07-01) i a quatre serveis que hem descrit però mai no hem escrit: Inventari, Pagaments, Notificacions i Clients. La lliçó següent els implementa de manera condensada però completa, amb la mateixa plantilla i la mateixa llibreria, tanca el mapa d'esdeveniments i segueix la comanda com-88213 pels sis serveis reals, base de dades a base de dades i cua a cua.
Curs de Microserveis
Mòdul 1: Introducció als Microserveis
- Conceptes Bàsics de Microserveis
- Avantatges i Desavantatges dels Microserveis
- Comparació amb l'Arquitectura Monolítica
- Quan Adoptar Microserveis: Criteris de Decisió
- El Cas Pràctic del Curs: la Botiga Online de TechCorp
Mòdul 2: Disseny de Microserveis
- Principis de Disseny de Microserveis
- Descomposició d'Aplicacions Monolítiques
- Definició de Bounded Contexts
- Gestió de Dades: una Base de Dades per Servei
- Consistència Distribuïda: Sagues, CQRS i Event Sourcing
Mòdul 3: Comunicació entre Microserveis
- APIs RESTful
- Missatgeria Asíncrona
- Protocols de Comunicació: gRPC, GraphQL
- API Gateway i Backend for Frontend
- Descobriment de Serveis i Balanceig de Càrrega
- Contractes i Versionat d'APIs
Mòdul 4: Implementació de Microserveis
- Elecció de Tecnologies i Eines
- Desenvolupament d'un Microservei Simple
- Gestió de Configuració
- Integració Pràctica: Consumir APIs i Publicar Esdeveniments
- Proves en Microserveis: Unitàries, d'Integració i de Contracte
Mòdul 5: Desplegament i Orquestració
- Contenidors i Docker
- Orquestració amb Kubernetes
- CI/CD per a Microserveis
- Estratègies de Desplegament: Rolling, Blue-Green i Canary
- Service Mesh: Istio i Linkerd
Mòdul 6: Monitoratge i Manteniment
- Monitoratge i Logging
- Traçabilitat Distribuïda amb OpenTelemetry
- Gestió d'Errors i Recuperació
- Escalabilitat i Rendiment
- SLOs, Alertes i Gestió d'Incidents
Mòdul 7: Seguretat en Microserveis
- Autenticació i Autorització
- Seguretat en la Comunicació
- Pràctiques de Seguretat
- Seguretat en Contenidors i Kubernetes
