Hem arribat al final. TechCorp ha passat d'un monòlit amb cinc problemes mesurables (01-05) a sis serveis operats amb SLOs, desplegats onze vegades al dia i assegurats per capes; hem explicat la migració (08-01), hem escrit el sistema complet (08-02) i l'hem desplegat i operat (08-03). Aquesta última lliçó no afegeix res de nou al sistema: destil·la el que hem après perquè t'ho enduguis al teu propi context. Primer, les lliçons de TechCorp organitzades per dimensió, cadascuna en la forma més honesta possible ("què vam fer, què va sortir malament, què faríem diferent"). Després, el catàleg d'antipatrons que hem vist i com reconèixer-los a temps. Tot seguit, una llista consolidada de bones pràctiques amb la lliçó on s'explica cadascuna, el que TechCorp faria a la seva fase 2 i amb quin criteri, i una guia per a l'alumne: com decidir, per on començar, com practicar amb l'entorn del curs i què llegir després. I el tancament: el recorregut mòdul a mòdul i les paraules finals de la Marta i el Luis.
Contingut
- Lliçons apreses per dimensió
- Catàleg d'antipatrons i com detectar-los
- Llista consolidada de bones pràctiques
- Què faria TechCorp a la fase 2
- Guia per a l'alumne: aplicar el curs al teu context
- Lectures i recursos recomanats
- Tancament del curs (a la conclusió)
- Lliçons apreses per dimensió
Cada taula resumeix una dimensió del curs. La columna "què faríem diferent" és la més útil: és el que TechCorp escriuria al postmortem del projecte.
1.1 Organització i equips
| Què vam fer | Què va sortir malament | Què faríem diferent |
|---|---|---|
| Reorganitzar en quatre equips per capacitat de negoci (Experiència de compra, Comandes, Pagaments i comunicacions, Plataforma) abans d'extreure res; llei de Conway aplicada a propòsit (02-01, 08-01 fase 0). | L'equip de Plataforma va ser coll d'ampolla els primers mesos: tothom li demanava manifestos, cues i usuaris de BD. | Començar la plantilla, el workflow reutilitzable i l'"afegir un servei" del runbook (08-03 §10) a la fase 0, no a la 2; Plataforma com a proveïdor d'autoservei des del primer dia. |
| Propietat d'extrem a extrem: cada equip desplega, opera i fa guàrdia del que és seu; guàrdia rotatòria entre els quatre equips, només alertes critical amb runbook (06-05 §8). | Al principi la guàrdia rebia alertes per causes (CPU alta, pod reiniciat) i es va cremar; i un servei (servei-descomptes) va néixer sense amo clar. |
Alertes per símptoma i SLO des del primer servei; regla "sense amo no hi ha servei" (el CODEOWNERS i l'Application d'Argo ho fan explícit). |
| La Marta va fixar restriccions clares (no aturar la botiga, valor per trimestre, dues BD, un llenguatge) i va mesurar resultats (08-01 §10). | La línia base de disponibilitat no existia: l'"abans" és una estimació. | Instrumentar el monòlit amb SLIs abans de la primera fase; mesurar forma part de la fase 0. |
1.2 Disseny
| Què vam fer | Què va sortir malament | Què faríem diferent |
|---|---|---|
Bounded contexts amb DDD estratègic; "producte" i "client" diferents a cada context; ACL traductorProducte; sense shared kernel (02-03). |
La primera versió de comanda.creada portava el preu de Catàleg sense ACL; un canvi de format la va trencar a staging. |
ACL a cada frontera des del primer contracte, encara que sembli burocràcia. |
Una base de dades per servei, esquemes i usuaris svc_* com a pas intermedi, ids opacs amb prefix, clients_ref per esdeveniments, migració sense dual write (02-04). |
Es va intentar el dual write al catàleg (08-01 §11) i es va haver de llençar. | Posar per escrit "una escriptura, a l'amo; la còpia, per esdeveniments" a la fase 0. |
| Saga per coreografia amb màquina d'estats explícita, compensacions com a esdeveniments de negoci, vigilant i reconciliació (02-05, 06-03). | INC-2031: la saga sense alertes de símptoma ni DLQ ben dissenyada es va encallar 40 minuts. | Vigilant, DLQ amb reintent diferit, alerta de saga tardana i runbook abans del tall de la fase 5, no després de l'incident. |
| Mida de servei per capacitat de negoci: sis serveis, no seixanta (02-01). | servei-descomptes (nanoservei) va afegir latència i desplegaments sense autonomia; es va reabsorbir. |
La pregunta "té dades i cicle de vida propis i un equip que el vulgui?" abans de crear un repositori. |
Monòlit modular primer: retornar les escriptures d'estoc i pagaments al seu amo dins del monòlit (02-02, 08-01 fase 0). |
Res: va ser la millor feina invisible del projecte. | Fer-ho encara més: introduir les abstraccions (RepositoriProductes, ReservaEstoc) de les sis fronteres a la fase 0. |
1.3 Comunicació
| Què vam fer | Què va sortir malament | Què faríem diferent |
|---|---|---|
Contractes primer (OpenAPI, AsyncAPI), /v1/, RFC 7807 amb codi, 202 + ETag, Idempotency-Key (03-01, 03-06). |
El canvi de 201 a 202 a POST /comandes va sorprendre el front-end; es va avisar tard. |
Els canvis de contracte visibles al client entren al full de ruta amb dos sprints d'avís i Deprecation des del primer dia. |
| Esdeveniments amb sobre estàndard, topic exchange, una cua per consumidor amb DLQ, at-least-once + idempotència (03-02, 02-05). | El binding de Pagaments i Notificacions a comanda.creada no era al disseny inicial (08-02 §4-5): va aparèixer en implementar. |
Dissenyar el mapa d'esdeveniments complet (productor, consumidors, càrrega mínima) amb l'event storming, i validar-lo amb pactes de missatges abans de la primera cua. |
| Gateway prim: encaminament, JWT, rate limit, capçaleres internes; res de negoci (03-04, 07-01). | Algú va proposar "compondre el detall de la comanda al gateway"; es va rebutjar a temps. | Mantenir la regla escrita: la composició viu en un BFF o al servei, mai al gateway. |
Versionat: URI per a incompatibles, afegir sense treure, Sunset, upcasting d'esdeveniments (03-06). |
Cap trencament de contracte a producció gràcies a Pact; dos a staging. | Res de rellevant; potser adoptar abans els pactes de missatges. |
1.4 Implementació
| Què vam fer | Què va sortir malament | Què faríem diferent |
|---|---|---|
Plantilla + llibreria tècnica versionada (plantilla-servei-node, @techcorp/comu-http); codi de negoci mai compartit (04-01, 02-02 §6). |
Durant dos mesos el ci.yml es va copiar tres vegades amb diferències (08-01 §11); l'outbox va ser a Comandes fins que Inventari el va necessitar. |
La regla del Luis literal: automatitzar/extreure abans del segon ús, no del quart. |
Configuració validada en arrencar amb zod, fail-fast, sense process.env fora de config.js, secrets per Secret/ESO (04-03). |
Un CATALEG_REMOT mal escrit en un ConfigMap va tombar un pod a staging… i config.js ho va detectar en arrencar, que és l'objectiu. |
Res. |
| Piràmide de proves amb dobles injectats, Testcontainers, Pact HTTP i de missatges, una E2E (04-05, 08-02 §9). | Els pactes de missatges van arribar després d'INC-2031. | Pactes per a esdeveniments des del primer consumidor d'esdeveniments (fase 2). |
Idempotència a tot arreu: processarUnCop, Idempotency-Key, UNIQUE (comanda_id), UNIQUE (comanda_id, tipus), upsert (02-05 §8, 08-02). |
Cap cobrament ni correu duplicat a producció. | Res; és la pràctica que més vegades ens va salvar. |
1.5 Plataforma
| Què vam fer | Què va sortir malament | Què faríem diferent |
|---|---|---|
Contenidors multi-stage, USER node, sense latest, imatges per sha i semver, Trivy i cosign (05-01, 07-04). |
Res de greu. | Digest als overlays de prod en lloc d'etiquetes, des del principi. |
Kubernetes amb Kustomize per servei i entorn, Helm per a tercers, sondes, securityContext, PDB, HPA/KEDA (05-02, 06-04, 07-04). |
El primer HPA de Catàleg només per CPU oscil·lava; va caldre la mètrica de peticions. | Autoescalar per la mètrica que reflecteix la càrrega real (peticions, longitud de cua), CPU com a suport. |
GitOps amb Argo CD a prod, cd.yml a staging, can-i-deploy com a porta (05-03). |
Un kubectl scale manual en campanya revertit per selfHeal (08-03 §7). |
Educar: "producció es canvia per PR"; i l'overlay de campanya des del primer Black Friday. |
Desplegaments progressius: rolling amb maxUnavailable: 0, canary per a Comandes i Pagaments, blue-green del gateway, expand/contract (05-04). |
El canary per pes HTTP no detecta consumidors lents (08-03 ex. 2). | Panell canary vs estable amb mètriques de consumidors per version; Argo Rollouts quan hi hagi anàlisi automàtica. |
| Sense mesh a la fase 1 (05-05). | Res: la decisió es va sostenir. | Res; revisitar a la fase 2 (apartat 4). |
1.6 Operació
| Què vam fer | Què va sortir malament | Què faríem diferent |
|---|---|---|
Observabilitat: logs pino amb redact, mètriques RED i de negoci, Loki, traces OpenTelemetry amb traceparent per l'outbox, correlació (06-01, 06-02). |
La cardinalitat va tombar Prometheus 25 minuts (08-01 §11). | Regla d'etiquetes acotades i sample_limit a la plantilla des del primer servei. |
| Resiliència: timeouts, reintents amb backoff només del que és transitori, circuit breaker, bulkhead, cues de reintent amb TTL i DLQ, vigilant i reconciliació (06-03). | Pagaments reintentava en bucle amb prefetch(1) fins a INC-2031. |
Els patrons de 06-03 a comu-http abans del primer consumidor que parli amb un tercer. |
| SLOs i alertes per burn rate, Alertmanager per equip, runbooks versionats, severitats, postmortems sense culpa, política de pressupost d'error (06-05). | Els SLOs van arribar al mòdul 6, quan ja hi havia cinc serveis a producció. | SLO i alerta de símptoma per a cada servei en extreure'l, com a part de la seva definició de "fet". |
| Escalat per la mètrica correcta i proves de càrrega amb k6 abans de cada campanya (06-04). | Res de greu; el primer Black Friday va ser el gran èxit del projecte. | Res. |
1.7 Seguretat
| Què vam fer | Què va sortir malament | Què faríem diferent |
|---|---|---|
Identitat portable: Keycloak, JWT amb clientId, verificació al gateway i a cada servei, regla del propietari (404), client credentials (07-01). |
Keycloak va arribar a la fase 5 federant el monòlit; hi va haver dues setmanes de doble sessió incòmodes. | Keycloak a la fase 0 davant del monòlit: la identitat és prerequisit, com el gateway. |
Capes: TLS a la vora amb cert-manager, RabbitMQ amqps amb usuari per servei, BD verify-full, webhook HMAC; mTLS posposat (07-02). |
Cap bretxa; el mTLS continua pendent. | Res; el mesh de la fase 2 ho tanca. |
Codi: zod estricte, helmet, gitleaks, RGPD (dades personals només a comanda.creada, retenció, client.eliminat), auditoria immutable (07-03). |
La decisió RGPD va arribar tard i va obligar a destinataris a Notificacions (08-02 §5). |
Minimització de dades als esdeveniments decidida en dissenyar el mapa d'esdeveniments. |
Plataforma endurida: securityContext complet, PSA restricted, ESO + Vault, OIDC al CI, NetworkPolicies deny-all, RBAC per ServiceAccount (07-04). |
PSA en audit, no enforce; ESO encara no cobreix tots els serveis. |
Res de nou: són les tasques de fase 2 ja llistades a SEGURETAT.md. |
- Catàleg d'antipatrons i com detectar-los
Tots han aparegut al curs, gairebé tots a TechCorp. La columna "com detectar-lo" és una prova que pots aplicar al teu sistema demà mateix.
| Antipatró | Què és | Com detectar-lo | On l'hem vist |
|---|---|---|---|
| Monòlit distribuït | Serveis separats que cal desplegar junts o que comparteixen esquema | "Un canvi d'esquema a A obliga a desplegar B?"; "hi ha un ordre de desplegament obligatori?" (01-04 §7) | 01-04, 02-01 |
| Base de dades compartida | Dos serveis llegeixen/escriuen les mateixes taules | Matriu taula × servei amb més d'una E, o L alienes sense contracte (02-02 §3.3) | 02-02, 02-04 |
| Nanoserveis / serveis d'entitat | Un servei per taula o per funció | "Té dades, cicle de vida i equip propis?"; crides síncrones encadenades per a qualsevol cas d'ús | 02-01, servei-descomptes (08-01) |
| Gateway gras | Lògica de negoci, composició o transformacions al gateway | El repositori del gateway creix amb cada funcionalitat; PRs d'equips de negoci a dins | 03-04 |
| Dual write | Escriure en dos magatzems (o BD + broker) sense transacció comuna | Discrepàncies intermitents en ombra; esdeveniments "perduts" sense explicació | 02-04 §6, 02-05 §7, 08-01 §11 |
| Sincronia en cadena | A crida B que crida C a la petició del client | Latència p99 = suma; una dependència caiguda tomba tot el flux; traces amb més de 3 salts síncrons | 02-05, 03-02, 06-02 |
| Sense idempotència | Reintents que dupliquen efectes (dos cobraments, dos correus) | Relliuraments de RabbitMQ o reintents de xarxa produeixen files duplicades; no hi ha UNIQUE de negoci |
02-05 §8, 08-02 |
| Alertar per causes | Avisos per CPU, reinicis, cues amb 1 missatge | La guàrdia rep alertes que no requereixen acció; alertes sense runbook | 06-05 §6 |
| Mètriques d'alta cardinalitat | Ids o rutes sense plantilla com a etiquetes | Prometheus amb memòria creixent; count({__name__=~".+"}) en milions |
06-01 §11, 08-01 §11 |
| Secrets a la imatge o a git | Credencials al Dockerfile, .env versionat, Secret en YAML "perquè és base64" |
gitleaks; docker history mostra el secret; kubectl get secret -o yaml al repositori |
05-01, 07-03 §7, 07-04 §4 |
| Llibreria de models compartida | Un paquet @techcorp/models que tothom importa |
Un canvi a Producte obliga a redesplegar sis serveis |
01-04, 02-02 §6 |
| Extreure el core primer | Començar pel servei que depèn de tots | Neix amb N crides al monòlit i sense contractes | 02-02 §5 |
| Reintentar-ho tot, immediatament | nack amb requeue en bucle, reintents de 4xx |
Cues encallades per un missatge; x-intents inexistent |
03-02, 06-03, INC-2031 |
latest i desplegaments manuals |
Imatges mutables, kubectl apply des de portàtils |
Ningú no sap quina versió corre; drift respecte de git | 05-01 §5, 05-03 §6 |
| Sense línia base | Migrar sense mesurar l'"abans" | Impossible demostrar millora ni detectar regressió | 08-01 §10 |
- Llista consolidada de bones pràctiques
Vint-i-cinc punts, agrupats, amb la lliçó de referència. Fes-la servir com a checklist de revisió d'arquitectura o d'un servei nou.
Decisió i disseny
- Adopta microserveis per problemes mesurables, no per moda; construeix els quatre prerequisits sobre el monòlit i modularitza'l primer (01-04, 02-02, 08-01 fase 0).
- Talla per capacitats de negoci i bounded contexts; valida amb event storming i la matriu taula × àrea (02-02, 02-03).
- Un servei = les seves dades: base de dades (o esquema) pròpia, ids opacs, sense FK creuades, rèpliques de lectura per esdeveniments (02-04).
- Substitueix la transacció distribuïda per una saga amb màquina d'estats explícita, compensacions com a esdeveniments i un vigilant (02-05, 06-03 §9).
- Extreu en ordre de valor/risc/dependències amb strangler fig darrere d'un gateway i branch by abstraction amb flags; mai no esborris el que és antic el dia del tall (02-02, 08-01).
Comunicació
6. Contractes primer (OpenAPI/AsyncAPI), errors RFC 7807 amb codi, 202 per a processos asíncrons, ETag per a polling (03-01).
7. Esdeveniments amb sobre estàndard (esdevenimentId, tipus, versio, ocorregutEn), topic exchange, cua per consumidor amb reintent diferit i DLQ (03-02, 06-03 §8).
8. Outbox transaccional per publicar; processarUnCop + idempotència de negoci (UNIQUE) per consumir; Idempotency-Key als POST (02-05 §7-8, 04-04, 08-02).
9. Gateway prim; composició al BFF o al servei; ACL a cada frontera (03-04, 02-03).
10. Versiona: afegeix sense treure, /v2/ només per a incompatibles, Deprecation/Sunset, upcasting d'esdeveniments, pactes HTTP i de missatges amb can-i-deploy (03-06, 04-05, 05-03 §4).
Implementació
11. Plantilla de servei + llibreria tècnica versionada; el negoci no es comparteix (04-01, 02-02 §6).
12. crearApp sense listen, injecció de dependències per paràmetre, capes cap endins (04-02).
13. Configuració validada en arrencar, fail-fast, secrets fora del codi i de la imatge (04-03, 07-03 §7).
14. Piràmide: unitàries del domini, component amb dobles, integració amb Testcontainers, contracte amb Pact, una E2E (04-05).
15. Cap crida externa dins d'una transacció; transaccions curtes i consulta per clau d'idempotència davant del dubte (01-05, 08-02 §4).
Plataforma i desplegament
16. Imatges multi-stage, no root, etiquetades per sha i semver, escanejades i signades; mai latest (05-01, 07-04 §2).
17. Kustomize base + overlays per entorn; Helm per a tercers amb values versionats; sondes, securityContext, PDB, requests reals (05-02, 06-04, 07-04).
18. GitOps: producció canvia per PR; Argo CD sincronitza; rollback = revertir commit (05-03 §6).
19. Desplegaments progressius per servei (rolling, canary, blue-green) amb expand/contract i compatibilitat d'esdeveniments (05-04).
20. Workflow de CI reutilitzable i versionat; la regla del Luis (05-03 §11).
Operació i seguretat
21. Logs estructurats amb redact, mètriques RED i de negoci amb etiquetes acotades, traces amb context propagat per HTTP i per esdeveniments (06-01, 06-02).
22. Timeouts sempre, reintents només del que és transitori amb backoff, circuit breaker, bulkhead, DLQ amb runbook (06-03).
23. SLOs amb pressupost d'error, alertes per símptoma i burn rate, guàrdia amb runbooks, postmortems sense culpa amb accions (06-05).
24. Identitat portable (OIDC/JWT) verificada al gateway i a cada servei; autorització per rol, scope i propietari; TLS a tot arreu; webhooks signats (07-01, 07-02).
25. Validació estricta d'entrada, RGPD per disseny (minimització, retenció, supressió), auditoria immutable, secrets per operador, NetworkPolicies deny-all, RBAC mínim, i una llista de pendents honesta (07-03, 07-04).
- Què faria TechCorp a la fase 2
Res d'això és urgent; cada punt té un criteri que diu quan abordar-lo. És la diferència entre un full de ruta i una llista de desitjos.
| Iniciativa | Què aporta | Criteri per abordar-la | Lliçó |
|---|---|---|---|
| Service mesh (Linkerd) amb mTLS | Identitat criptogràfica entre serveis, canary per pes exacte intern, reintents/timeouts uniformes | Quan l'auditoria de Pagaments exigeixi mTLS, o quan hi hagi més de ~12 serveis i els patrons de comu-http divergeixin |
05-05, 07-02 §7 |
| Event sourcing selectiu a Comandes | Historial complet de la comanda, reconstrucció de vistes, auditoria natural | Si negoci demana sovint "què va passar exactament amb aquesta comanda", o si apareixen més de tres vistes de lectura diferents; mai per a tot el sistema | 02-05 §10 |
| gRPC Comandes ↔ Inventari | Reserva síncrona de baixa latència per al checkout amb "estoc en temps real" | Si la saga per esdeveniments deixa de ser acceptable per a l'experiència de compra (comprovació d'estoc al cistell), no abans | 03-03 |
| GraphQL al BFF per al web | Un sol endpoint per a pantalles compostes | Quan el web tingui tantes pantalles compostes com l'app; el bff-mobil ja ho demostra |
03-03, 03-04 |
| TypeScript a la plantilla | Contractes tipats des d'OpenAPI/AsyncAPI, menys errors de forma | Quan l'equip el domini i la plantilla el porti; migrar servei a servei, començant per comu-http |
04-01 |
| Go per a Inventari | Menor consum i latència al servei més "de sistema" | Només si el cost d'Inventari o la seva latència p99 es converteixen en problema mesurat; el segon llenguatge s'ha de justificar amb dades (regla de la Marta) | 04-01 |
| Plataforma interna (IDP): Backstage o similar | Catàleg de serveis, plantilles amb un clic, amos, SLOs i runbooks en un sol lloc | Quan hi hagi més de ~10 serveis o un segon domini de negoci; avui plataforma/README.md és suficient |
04-01, 08-03 |
| FinOps | Etiquetes de cost per equip/servei, informes mensuals, pressupostos per SLO | Ja: començar amb la taula de 08-03 §11 etiquetada per servei; automatitzar quan la factura superi ~5.000 €/mes | 08-03 §11 |
| Orquestració de la saga | Un coordinador si el flux creix | Només si apareixen els senyals de 02-05 §6 (més de 6 passos, branques condicionals, "en quin pas és?" freqüent) | 02-05 |
| Argo Rollouts / Flagger | Canary amb anàlisi automàtica de mètriques | Quan els canary manuals passin de dos al dia | 05-04 |
Pendents de SEGURETAT.md |
cosign en admissió, PSA enforce, ESO per a tots, mTLS |
Trimestre següent, en aquest ordre | 07-04 §10 |
- Guia per a l'alumne: aplicar el curs al teu context
Decidir. Torna a la matriu de 01-04 i respon amb dades, no amb opinions:
| Pregunta | Si la resposta és "sí" | Si és "no" |
|---|---|---|
| Teniu diversos equips per capacitat de negoci que es destorben al mateix codi i a les mateixes taules? | Senyal a favor | Un equip petit rendeix més amb un monòlit modular |
| CI, contenidors, observabilitat i propietat d'extrem a extrem ja funcionen? | Pots començar | Construeix això primer sobre el monòlit (fase 0 de 08-01) |
| Hi ha parts amb perfils de càrrega o disponibilitat molt diferents (el catàleg de TechCorp)? | Hi ha un primer candidat clar | Escala el monòlit; és més barat |
| El domini és estable i ben entès? | Els límits es poden dibuixar | Els límits canviaran; espera |
| La velocitat de lliurament està frenada per l'acoblament del desplegament (i no per una altra cosa)? | Els microserveis ajuden | Arregla l'altra cosa (proves, processos, deute) |
Quatre o més "sí" amb els prerequisits llestos: extreu de manera incremental començant per la raó més clara. Menys: monòlit modular i revisió d'aquí a sis mesos. I recorda que la llista de 01-04 té senyals d'alarma (equip de tres persones, "perquè ho fa Netflix", sense automatització) que anul·len tota la resta.
Per on començar (si decideixes continuar): en aquest ordre, i sense saltar-te'n cap: (1) els quatre equips —o els que tinguis— amb propietat clara; (2) CI i imatge del monòlit; (3) gateway al davant i observabilitat mínima; (4) matriu taula × àrea i monòlit modular; (5) primera extracció per valor/risc/dependències amb càrrega inicial, esdeveniments, ombra i flag; (6) SLO i alerta del servei nou abans de donar-lo per fet; (7) plantilla i llibreria abans del segon servei.
Com practicar. L'entorn del curs està pensat per reproduir-se:
- Aixeca TechCorp en local amb el
compose.yamlde 08-03 §2, obtén un token de Keycloak i segueixcom-88213per Jaeger, Grafana i Loki com a 08-03 §5. Trenca coses: aturaservei-pagamentsi observa el vigilant i la DLQ; publica un esdeveniment mal format ambpublicarEsdeveniment.jsi reprocessa'l; esgota l'estoc de p-802.
# Sessió de pràctica típica (repositoris germans clonats: servei-*, gateway, plataforma)
cd plataforma/local && docker compose up -d --wait # 19 contenidors; ~90 s
TOKEN=$(../scripts/token-keycloak.sh http://localhost:8180 techcorp proves-e2e ana.ruiz clau-de-proves)
docker compose stop servei-pagaments # 1. trenca Pagaments i crea una comanda: es queda en ESTOC_RESERVAT
curl -s -X POST http://localhost:8080/api/v1/comandes -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-H "Idempotency-Key: practica-$(date +%s)" -d '{"clientId":"c-1024","linies":[{"producteId":"p-501","quantitat":1}]}' | jq .id
# → espera 10 min i veuràs comanda.cancellada (TIMEOUT_PAGAMENT) del vigilant; o arrenca Pagaments abans i veuràs CONFIRMADA
docker compose start servei-pagaments
node ../../servei-comandes/scripts/publicarEsdeveniment.js estoc.reservat '{"comandaId":"com-inexistent"}' # 2. esdeveniment per a una comanda desconeguda → log, no DLQ
node ../../servei-comandes/scripts/publicarEsdeveniment.js pagament.confirmat '{"comandaId":"<una com- en PENDENT>"}' # 3. transició no permesa → transicio_ignorada al log, estat intacte
# Jaeger http://localhost:16686 · Grafana http://localhost:3000 · RabbitMQ http://localhost:15672 (mira comandes.saga.dlq després del pas 3 amb un JSON trencat)
docker compose down -v # base de dades neta per a la propera sessió- Exercicis d'extensió proposats, de menor a major: cupons i promocions (01-03, 02-02 ex. 2, 08-01 §11): primer com a mòdul de Comandes, després decideix amb criteri si mereix servei; devolucions: nou estat de la comanda,
pagament.reemborsatcom a branca habitual,estoc.reposat, correu, auditoria; enviaments: unservei-enviamentsque consumeixicomanda.confirmada, parli amb un transportista fictici (ACL, webhook signat, reintents) i publiquicomanda.enviada/comanda.lliuradaque Notificacions i l'analítica consumeixin; v2 decomanda.creadaamb upcasting i pactes de missatges; Argo Rollouts per al canary de Comandes amb anàlisi deslo:comandes_error_ratio. - Repeteix el mòdul 6 sobre la teva pròpia extensió: mètriques, SLO, alerta, runbook i un game day en què un company trenqui alguna cosa sense avisar.
- Lectures i recursos recomanats
Sense URLs (canvien); cerca per títol i projecte. Llibres:
- Sam Newman, Building Microservices (2a ed.) i Monolith to Microservices: la referència general i el manual de l'strangler fig que TechCorp va seguir (mòduls 1, 2 i 8).
- Chris Richardson, Microservices Patterns: sagues, outbox, CQRS, API composition; el lloc microservices.io de l'autor cataloga els patrons (02-05, 03-04).
- Eric Evans, Domain-Driven Design; Vaughn Vernon, Implementing Domain-Driven Design; Vlad Khononov, Learning Domain-Driven Design: bounded contexts, mapa de contextos, agregats (02-03).
- Martin Kleppmann, Designing Data-Intensive Applications: consistència, replicació, missatgeria, la base teòrica de 02-04 i 02-05.
- Gregor Hohpe i Bobby Woolf, Enterprise Integration Patterns: missatgeria, DLQ, idempotència (03-02, 06-03).
- Michael Nygard, Release It! (2a ed.): timeouts, circuit breaker, bulkhead, estabilitat (06-03).
- Betsy Beyer i altres (Google), Site Reliability Engineering i The Site Reliability Workbook: SLOs, burn rate, guàrdies, postmortems (06-05).
- Nicole Forsgren, Jez Humble i Gene Kim, Accelerate: les mètriques DORA (05-03, 08-01 §10).
- Matthew Skelton i Manuel Pais, Team Topologies: equips alineats a flux i equip de plataforma (02-01, 08-04 §1.1).
- Jez Humble i David Farley, Continuous Delivery; Marko Lukša, Kubernetes in Action: la base dels mòduls 5 i 8.
- Neal Ford, Mark Richards, Pramod Sadalage i Zhamak Dehghani, Software Architecture: The Hard Parts: granularitat, dades i sagues amb trade-offs explícits.
Documentació oficial i projectes que convé tenir a mà: Node.js i Express; PostgreSQL i MongoDB; RabbitMQ (guies de fiabilitat, DLX i TTL); Docker i Compose; Kubernetes (conceptes, Kustomize), Helm, kind, KEDA, Argo CD i Argo Rollouts, ingress-nginx, cert-manager, External Secrets Operator; GitHub Actions; Prometheus, Grafana, Loki, OpenTelemetry (JavaScript SDK) i Jaeger; Keycloak; Pact (inclosos els pactes de missatges) i el Pact Broker; Trivy i Sigstore/cosign; OWASP API Security Top 10; The Twelve-Factor App; i les especificacions OpenAPI, AsyncAPI, RFC 7807 i W3C Trace Context.
Errors Comuns i Consells
- Convertir la llista de bones pràctiques en dogma. Cada punt de l'apartat 3 té una lliçó amb el seu context i els seus trade-offs; aplicat sense el context (per exemple, outbox en un servei que no publica res de crític) afegeix complexitat sense benefici. Llegeix la lliçó abans d'imposar la pràctica.
- Copiar l'arquitectura final de TechCorp en lloc del seu mètode. Sis serveis, RabbitMQ i Kubernetes són la resposta als cinc problemes de 01-05 amb 25 tècnics; amb tres persones i un domini canviant, la resposta correcta de la matriu de 01-04 és un monòlit modular.
- Confondre "fase 2" amb "pendent". Mesh, event sourcing, gRPC o Go tenen un criteri d'activació; abordar-los abans que es compleixi és el "perquè ho fa Netflix" de què 01-04 avisava.
- Postmortem sense accions o accions sense data. Les taules de l'apartat 1 són postmortems del projecte; el seu valor és a la columna "què faríem diferent" convertida en tasques amb amo.
- Practicar només el camí feliç. L'entorn local serveix per trencar: atura Pagaments, esgota l'estoc, publica esdeveniments mal formats, rota un secret. El que no has vist fallar en local ho veuràs fallar a producció.
- Consell: guarda la teva pròpia versió de les taules de l'apartat 1 des del primer dia del teu projecte, encara que estiguin gairebé buides. La disciplina d'omplir-les cada trimestre val més que qualsevol eina.
Exercicis
Exercici 1: La teva pròpia matriu
Aplica la matriu de l'apartat 5 a un sistema que coneguis (el de la teva feina, un projecte personal o, si no en tens cap, un sistema de reserves d'un hotel amb 4 tècnics). Respon les cinc preguntes amb dades concretes, indica quina recomanació en surt i, si és "extreure", quin seria el primer servei i què faria la teva fase 0.
Exercici 2: Reconèixer antipatrons
Un equip descriu el seu sistema així: "Tenim vuit serveis a Kubernetes. Comparteixen una base de dades PostgreSQL amb esquemes separats per servei, però el servei d'informes fa JOIN entre esquemes. Despleguem els vuit junts cada dues setmanes perquè un canvi a la llibreria models-comuns obliga a actualitzar-los tots. Els serveis es criden per HTTP en cadena i, quan el de clients triga, tot triga. Cada servei reintenta les crides fallides tres vegades seguides." Identifica tots els antipatrons de l'apartat 2 que hi apareixen, ordena'ls pel dany que fan i proposa per a cadascun la primera acció, amb la lliçó de referència.
Exercici 3: Prioritzar la fase 2
La Marta té pressupost per a dues iniciatives de la taula de l'apartat 4 el semestre vinent. Amb les dades del curs (08-01 §10-11, 08-03 §11, SEGURETAT.md), tria'n dues, justifica-ho amb el criteri de cadascuna i explica per què en descartes almenys tres altres que semblen atractives.
Solucions
Exercici 1. No hi ha una única resposta; la solució és el mètode. Per a l'hotel de 4 tècnics: (1) un equip, sense destorbs → no; (2) probablement sense CI complet ni observabilitat → no; (3) reserves i facturació tenen càrregues semblants; potser el motor de disponibilitat en temporada alta → feble; (4) domini conegut → sí; (5) la velocitat la frena la manca de proves, no el desplegament → no. Resultat: monòlit modular amb mòduls per capacitat (reserves, facturació, disponibilitat, clients), CI, contenidor, observabilitat i SLIs des d'ara; revisar d'aquí a 6-12 mesos. Si al teu sistema real surten quatre "sí" amb els prerequisits llestos, el primer servei és el que tingui la raó més clara i menys dependències (el "catàleg" del teu domini) i la fase 0 és la llista de l'apartat 5 ("per on començar").
Exercici 2. Per dany: (1) Base de dades compartida (els JOIN del servei d'informes creuen esquemes: qualsevol canvi d'esquema trenca informes) → matriu taula × servei i BD de lectura per a informes alimentada per esdeveniments (02-02 §3.3, 02-04 §8); (2) Llibreria de models compartida + monòlit distribuït (vuit serveis desplegats junts per models-comuns) → substituir per contractes per servei i una llibreria només tècnica versionada; cada servei defineix els seus DTOs (02-02 §6, 03-06); (3) Sincronia en cadena amb reintents immediats (tot triga quan triga clients; tres reintents seguits multipliquen la càrrega: tempesta de reintents) → timeouts amb pressupost, circuit breaker, reintents amb backoff només del que és transitori, i substituir les crides no necessàries a la petició per esdeveniments o rèpliques de lectura (06-03, 02-04 §4, 03-02); (4) Desplegament conjunt cada dues setmanes (símptoma, no causa) → desapareix en resoldre 1-2; mesurar DORA per comprovar-ho (05-03 §12). No hi apareixen (o no se sap): gateway gras, secrets, cardinalitat; preguntar.
Exercici 3. Una resposta defensable: (a) FinOps — criteri "ja": la factura és de 2.760 €/mes amb palanques identificades de ~800 € (08-03 ex. 3); cost de la iniciativa baix (etiquetes i un informe); retorn immediat que a més finança la resta. (b) Pendents de SEGURETAT.md (cosign en admissió, PSA enforce, ESO per a tots) — criteri "trimestre següent"; risc conegut, cost acotat, i desbloqueja l'auditoria de Pagaments que al seu torn activarà el mesh. Descartaments: mesh/mTLS ara — el seu criteri (auditoria o >12 serveis) encara no es compleix i costa d'operar (05-05); event sourcing — ningú no ha demanat l'historial complet i l'auditoria de 07-03 cobreix el que és sensible; Go per a Inventari — no hi ha cost ni latència mesurats que ho justifiquin (regla de la Marta); gRPC Comandes↔Inventari — la saga compleix el seu SLO de 60 s amb p95 de 3 s; IDP — amb 6 serveis i un README, no compensa. L'important no són les dues triades sinó que cada descartament es recolzi en el criteri de la taula i no en l'atractiu de la tecnologia.
Conclusió
El recorregut, mòdul a mòdul. Al mòdul 1 vam aprendre què és un microservei, què s'hi guanya i què s'hi paga, com es compara amb el monòlit, quan té sentit fer el pas i vam conèixer TechCorp: un monòlit amb cinc problemes i una funció, crearComanda, que feia sis coses de cinc àrees. Al mòdul 2 vam dissenyar: principis i acoblaments, descomposició amb event storming i la matriu de taules, bounded contexts i el mapa de contextos, una base de dades per servei i la migració sense dual write, i la saga per coreografia amb outbox i idempotència que va substituir la transacció. Al mòdul 3 vam fer parlar els serveis: contractes REST amb 202, ETag i Idempotency-Key; RabbitMQ amb la seva topologia i les seves DLQ; gRPC i GraphQL com a candidats; el gateway i el BFF; descobriment i sondes; versionat i pactes. Al mòdul 4 vam escriure codi: la plantilla i la llibreria, servei-cataleg, la configuració validada, servei-comandes amb el seu outbox i els seus consumidors, i la piràmide de proves. Al mòdul 5 ho vam empaquetar i desplegar: Docker i Compose, Kubernetes amb Kustomize, CI/CD amb GitHub Actions, Pact Broker i Argo CD, desplegaments progressius, i l'avaluació honesta del mesh. Al mòdul 6 ho vam fer operable: logs, mètriques i traces; resiliència i recuperació; escalat; SLOs, alertes, guàrdies, runbooks i el postmortem d'INC-2031. Al mòdul 7 ho vam assegurar per capes: Keycloak i JWT, TLS i signatures, codi validat i RGPD, plataforma endurida. I al mòdul 8 ho vam unir: la migració explicada en ordre, els quatre serveis que faltaven, el sistema desplegat i operat, i aquestes lliçons.
Paraules de la Marta. "Quan vaig presentar el pla el juliol de 2025 em van preguntar per què no reescrivíem la botiga d'una vegada. Tretze mesos després, la resposta és als números que no vam haver d'explicar: cap dia sense vendre, onze desplegaments al dia, un incident seriós que va durar quaranta minuts i del qual vam aprendre més que de dos anys de dijous a la nit. Però el que més valoro no és a la taula: avui cada equip sap què és seu, ho mesura i ho millora sense demanar permís. Els microserveis van ser el mitjà; el fi era una organització que pogués canviar la botiga cada dia sense por. Si hagués de resumir el projecte en una frase per a una altra CTO: no comencis pels serveis, comença pels deures; i no esborris res el dia del tall."
Paraules del Luis. "Jo em quedo amb tres coses. La primera, que la millor decisió tècnica de l'any va ser la menys vistosa: retornar les escriptures d'estoc i pagaments al seu amo dins del monòlit abans de moure una línia de servidor. La segona, que gairebé tot el que ens va salvar a producció era avorrit i estava escrit abans de necessitar-ho: l'UNIQUE (comanda_id), el processarUnCop, el vigilant, la clau d'idempotència cap a la passarel·la, la cua de reintent. I la tercera, que la regla de 'si es fa més d'un cop per servei, s'automatitza abans del segon' és més fàcil de dir que de complir —el ci.yml es va copiar tres vegades— i tot i així és la que fa que sis serveis els pugui operar un equip de vint-i-cinc persones. A qui estigui començant: torneu a llegir crearComanda de 01-05, ara que sabeu en què es va convertir. Tot el curs és a la distància entre aquelles 80 línies i com-88213 creuant quatre bases de dades en tres segons."
Per a tu. Has recorregut el mateix camí que TechCorp, amb les seves decisions i les seves ensopegades. El que t'endús no és una llista de tecnologies —canviaran— sinó un mètode: mesurar abans de decidir, fer els deures abans de dividir, tallar per capacitats i dades, comunicar per contractes i esdeveniments idempotents, automatitzar abans del segon ús, desplegar en petit i sovint, observar i acordar què és "anar bé", assegurar per capes i aprendre per escrit de cada incident. Aixeca TechCorp al teu portàtil, trenca-la, amplia-la amb cupons, devolucions o enviaments, i després aplica el mètode al teu propi sistema, començant per la fase 0. Els microserveis no són la destinació; són una manera que la teva organització pugui canviar el seu programari amb confiança, una comanda —i un desplegament— cada vegada. Gràcies per arribar fins aquí, i bona sort amb la teva pròpia migració.
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
