L'arquitectura serverless (sense servidor) és un model en què escrius i desplegues codi sense gestionar ni aprovisionar servidors: el proveïdor cloud s'encarrega completament de la infraestructura, executa el teu codi només quan cal i et cobra únicament pel temps d'execució real, normalment en mil·lisegons. El nom enganya: és clar que hi ha servidors, però tu no els veus ni els administres. La seva màxima expressió és FaaS (Funcions com a Servei), on desplegues funcions petites que reaccionen a esdeveniments. És rellevant perquè permet construir sistemes que escalen automàticament de zero a milers d'execucions, amb cost zero quan no hi ha trànsit, i redueix dràsticament la càrrega operativa. Però no és una bala de plata: té limitacions importants (el cold start, els temps màxims d'execució, la dependència del proveïdor) que has de conèixer per decidir quan aplicar-lo.
Contingut
- Què és serverless i què és FaaS.
- Arquitectura dirigida per esdeveniments.
- El problema del cold start (arrencada en fred).
- Avantatges i limitacions.
- Exemple de funció serverless.
- Quan fer servir serverless i quan no.
- Errors comuns i consells.
- Exercicis i solucions.
- Què és serverless i què és FaaS
"Serverless" és un paraigua que inclou diversos tipus de serveis gestionats que escalen sols i es paguen per ús: bases de dades serverless, cues de missatges, emmagatzematge d'objectes, etc. El seu component més representatiu és FaaS (Function as a Service): puges una funció —una unitat de codi petita i sense estat— i el proveïdor l'executa en resposta a un esdeveniment (una petició HTTP, un fitxer pujat, un missatge en una cua, un temporitzador). Exemples: AWS Lambda, Azure Functions, Google Cloud Functions.
| Característica | Servidor tradicional / VM | Contenidor (K8s) | Serverless (FaaS) |
|---|---|---|---|
| Gestiones el SO | Sí | Parcial | No |
| Escalat | Manual o configurat | Configurat | Automàtic (fins i tot a zero) |
| Cost sense trànsit | Pagues igual | Pagues igual | Zero (o gairebé) |
| Unitat de desplegament | Servidor/app | Contenidor | Funció |
| Estat | Pot tenir-ne | Pot tenir-ne | Sense estat (stateless) |
| Control | Alt | Mitjà | Baix |
- Arquitectura dirigida per esdeveniments
El serverless brilla en arquitectures dirigides per esdeveniments (event-driven): les funcions no estan "sempre enceses" esperant, sinó que s'activen davant d'un disparador (trigger). Això encaixa de forma natural amb fluxos asíncrons i desacoblats.
graph LR
A[Usuari puja imatge] --> B[Emmagatzematge S3]
B -- esdeveniment ObjectCreated --> C[Funcio: generar miniatura]
C --> D[Desa miniatura a S3]
C --> E[Cua de missatges]
E --> F[Funcio: notificar usuari]Explicació del diagrama: l'usuari puja una imatge a l'emmagatzematge. Aquest acte emet un esdeveniment que dispara una funció per generar una miniatura. La funció desa el resultat i publica un missatge en una cua, que al seu torn dispara una altra funció que notifica l'usuari. Cada peça és petita, independent i escala per separat. No hi ha servidors esperant: el codi només s'executa quan passa alguna cosa.
- El problema del cold start (arrencada en fred)
Quan una funció no s'ha fet servir recentment, el proveïdor no té un entorn llest per a ella. Davant de la primera invocació ha de: aprovisionar un contenidor, carregar el runtime (Node, Python, Java…) i inicialitzar el teu codi. Aquest retard inicial és el cold start (arrencada en fred) i pot anar de desenes de mil·lisegons a diversos segons. Les invocacions següents, mentre l'entorn segueix "calent", són ràpides (warm start).
| Factor | Efecte en el cold start |
|---|---|
| Llenguatge | Java/.NET solen trigar més; Node/Python/Go arrenquen ràpid |
| Mida del paquet | Com més gran, més triga a carregar |
| Memòria assignada | Més memòria sol donar més CPU i arrencada més veloç |
| Dependències i inicialització | Connexions i llibreries pesades a l'arrencada la penalitzen |
Mitigacions habituals: mantenir funcions petites, triar runtimes lleugers, fer servir concurrència aprovisionada (entorns preescalfats que es paguen a part) i reutilitzar connexions fora del handler perquè persisteixin entre invocacions calentes.
- Avantatges i limitacions
| Avantatges | Limitacions |
|---|---|
| Escalat automàtic, fins i tot a zero | Cold start: latència en la primera invocació |
| Pagament per ús real (sense cost en repòs) | Límit de temps d'execució (p. ex. minuts, no hores) |
| Zero gestió de servidors i pedaços | Sense estat: necessites emmagatzematge extern |
| Desplegaments ràpids i granulars | Dependència del proveïdor (vendor lock-in) |
| Alta disponibilitat gestionada | Depuració i monitoratge més complexos |
| Ideal per a càrregues irregulars o en pics | Costós si el trànsit és alt i constant |
- Exemple de funció serverless
Una funció AWS Lambda en Node.js que respon a una petició HTTP. El handler és el punt d'entrada que el proveïdor invoca amb l'event (dades del disparador) i el context (metadades de l'execució):
// index.js
// Connexio reutilitzable: es declara FORA del handler per
// aprofitar els "warm starts" i no reconnectar en cada invocacio.
const db = require("./db").connect();
exports.handler = async (event, context) => {
try {
// 'event' conte les dades del disparador (p. ex. la peticio HTTP)
const userId = event.queryStringParameters?.id;
if (!userId) {
return { statusCode: 400, body: JSON.stringify({ error: "Falta id" }) };
}
const user = await db.getUser(userId);
// Resposta en el format que espera l'API Gateway
return {
statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(user),
};
} catch (err) {
console.error("Error a la funcio:", err);
return { statusCode: 500, body: JSON.stringify({ error: "Error intern" }) };
}
};Explicació del codi:
- La línia
const db = require("./db").connect();està fora del handler expressament: el codi d'inicialització s'executa una sola vegada per entorn i es reutilitza en invocacions calentes, evitant reconnectar cada vegada. És una optimització clau en serverless. exports.handler = async (event, context) => {...}: el handler és la funció que el proveïdor crida.eventporta les dades del disparador;contextporta metadades (temps restant, identificadors).- Es valida l'entrada i, si falta l'
id, es respon amb el codi HTTP400(petició incorrecta). - Es consulta la dada i es retorna un objecte amb
statusCode,headersibody. El proveïdor (via API Gateway) tradueix aquest objecte en una resposta HTTP real. - El bloc
catchregistra l'error i retorna500per no exposar detalls interns.
Per definir el disparador HTTP de forma declarativa amb el Serverless Framework:
service: usuaris-api
provider:
name: aws
runtime: nodejs20.x
memorySize: 256 # MB de memoria (afecta la CPU i el cold start)
timeout: 10 # segons maxims d'execucio
functions:
getUser:
handler: index.handler # fitxer.funcio
events:
- http:
path: /usuaris
method: get # GET /usuaris dispara la funcioExplicació: runtime fixa l'entorn d'execució; memorySize i timeout configuren recursos i límit de temps; handler apunta a index.js i a la funció handler; el bloc events declara que una petició GET /usuaris invoca la funció. El framework s'encarrega de crear la Lambda, l'API Gateway i els permisos.
- Quan fer servir serverless i quan no
Bons casos d'ús:
- APIs i backends amb trànsit irregular o impredictible (pics puntuals).
- Processament d'esdeveniments: redimensionar imatges, processar fitxers pujats, reaccionar a missatges d'una cua.
- Tasques programades (cron) i automatitzacions puntuals.
- Webhooks i integracions lleugeres entre sistemes.
- Prototips i MVP on vols anar ràpid sense muntar infraestructura.
Mals casos d'ús:
- Aplicacions amb trànsit alt, constant i predictible: a aquest volum sol sortir més barat un servidor o contenidor reservat.
- Processos llargs (per sobre del límit de temps de la funció) o amb ús intensiu de CPU/memòria sostingut.
- Càrregues amb latència crítica i estricta on el cold start seria inacceptable.
- Aplicacions amb estat en memòria persistent (les funcions són efímeres i sense estat).
Errors Comuns i Consells
- Ficar connexions a base de dades dins del handler. Declara-les fora per reutilitzar-les en warm starts i vigila l'esgotament del pool de connexions, un problema clàssic quan moltes funcions escalen alhora.
- Funcions massa grans (funcions monolítiques). Mantén cada funció centrada en una tasca; els paquets grans empitjoren el cold start.
- Ignorar el cost a escala. Serverless és barat amb poc trànsit, però amb milions d'invocacions constants pot ser més car que un contenidor. Mesura.
- No dissenyar per a la idempotència. Els esdeveniments poden lliurar-se més d'una vegada; les teves funcions han de tolerar execucions repetides sense efectes duplicats.
- Oblidar l'observabilitat. En ser distribuït i efímer, sense traces i mètriques adequades depurar és molt difícil. Instrumenta des del principi.
- Consell: abraça el desacoblament per esdeveniments, però documenta bé el flux: una embullada de funcions sense diagrama es torna inmanejable.
Exercicis
- Explica per què declarar la connexió a la base de dades fora del handler millora el rendiment, i en quin tipus d'invocacions es nota.
- Una empresa té una API interna amb trànsit constant i elevat les 24 hores. Recomanaries serverless? Justifica-ho.
- Descriu un flux event-driven serverless per processar factures que es pugen a un emmagatzematge: quins disparadors i funcions encadenaries?
Solucions
- Perquè el codi situat fora del handler s'executa una sola vegada en inicialitzar l'entorn i es reutilitza mentre l'entorn segueix calent, evitant reobrir la connexió en cada crida. La millora es nota en les invocacions calentes (warm starts) consecutives; en el primer cold start igualment cal inicialitzar.
- No, probablement no. Amb trànsit constant i elevat les 24 h, el model de pagament per invocació tendeix a resultar més car que un contenidor o servidor reservat, que a més evita completament el cold start. Serverless rendeix millor amb trànsit irregular o amb pics.
- Possible flux: (1) l'usuari puja la factura a l'emmagatzematge d'objectes, cosa que emet un esdeveniment
ObjectCreated; (2) aquest esdeveniment dispara una funció de validació/extracció que llegeix el PDF i n'obté les dades; (3) la funció publica un missatge en una cua; (4) aquest missatge dispara una altra funció de registre que desa les dades en una base de dades i, opcionalment, dispara una tercera funció de notificació. Cada pas és independent, asíncron i escala per separat.
Conclusió
Has comprès el model serverless i el seu cor FaaS, l'arquitectura dirigida per esdeveniments, el repte del cold start, el balanç d'avantatges i limitacions, com s'escriu una funció i, sobretot, quan convé i quan no. Serverless és una eina potent per a càrregues irregulars i fluxos per esdeveniments, no una solució universal. A la lliçó següent recollirem bones pràctiques transversals per construir aplicacions robustes al núvol amb els patrons de disseny cloud-native.
Curs d'Arquitectura d'Aplicacions
Mòdul 1: Fonaments de l'Arquitectura d'Aplicacions
- Què és l'Arquitectura d'Aplicacions?
- El Rol de l'Arquitecte de Programari
- Atributs de Qualitat i Requisits No Funcionals
- Decisions Arquitectòniques i Compromisos (Trade-offs)
- Documentació d'Arquitectura: Vistes i el Model C4
Mòdul 2: Principis i Tàctiques de Disseny
- Acoblament, Cohesió i Separació de Responsabilitats
- Principis SOLID Aplicats a l'Arquitectura
- DRY, KISS, YAGNI i Altres Principis de Disseny
- Tàctiques Arquitectòniques per als Atributs de Qualitat
- Gestió del Deute Tècnic
Mòdul 3: Estils i Patrons Arquitectònics
- Arquitectura Monolítica
- Arquitectura en Capes (N-Tier)
- Arquitectura Client-Servidor
- Arquitectura Hexagonal (Ports i Adaptadors)
- Arquitectura Neta i Ceba (Clean & Onion)
Mòdul 4: Arquitectures Distribuïdes i Microserveis
- Introducció als Sistemes Distribuïts
- Arquitectura de Microserveis
- Descomposició de Serveis i Bounded Contexts
- API Gateway, Service Discovery i Comunicació entre Serveis
- Patrons de Resiliència: Circuit Breaker, Retry i Bulkhead
- El Teorema CAP i la Consistència de Dades
Mòdul 5: Arquitectures Dirigides per Esdeveniments i Missatgeria
- Fonaments de l'Arquitectura Orientada a Esdeveniments
- Missatgeria Asíncrona: Cues i Brokers
- Patrons d'Esdeveniments: Event Sourcing i CQRS
- Gestió de Transaccions Distribuïdes: Patró Saga
- Streaming de Dades en Temps Real
Mòdul 6: Disseny Dirigit pel Domini (DDD)
- Conceptes Fonamentals del DDD
- Disseny Estratègic: Bounded Contexts i Llenguatge Ubic
- Disseny Tàctic: Entitats, Agregats i Repositoris
- Mapatge de Contextos (Context Mapping)
Mòdul 7: Dades i Persistència
- Estratègies de Persistència: SQL vs NoSQL
- Patrons d'Accés a Dades: Repository, Unit of Work i DAO
- Base de Dades per Servei i Gestió de Dades Distribuïdes
- Cau i Estratègies d'Invalidació
Mòdul 8: Arquitectura al Núvol i Desplegament
- Fonaments del Cloud Computing (IaaS, PaaS, SaaS)
- Contenidors i Orquestració amb Docker i Kubernetes
- Arquitectura Serverless
- Patrons de Disseny Cloud-Native
- Infraestructura com a Codi (IaC)
Mòdul 9: Qualitat, Seguretat i Observabilitat
- Escalabilitat: Horitzontal vs Vertical i Balanceig de Càrrega
- Alta Disponibilitat i Tolerància a Fallades
- Seguretat per Disseny i Autenticació/Autorització
- Observabilitat: Logging, Mètriques i Traçabilitat
- Rendiment i Proves de Càrrega
