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

  1. Què és serverless i què és FaaS.
  2. Arquitectura dirigida per esdeveniments.
  3. El problema del cold start (arrencada en fred).
  4. Avantatges i limitacions.
  5. Exemple de funció serverless.
  6. Quan fer servir serverless i quan no.
  7. Errors comuns i consells.
  8. Exercicis i solucions.

  1. 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 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

  1. 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.

  1. 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.

  1. 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

  1. 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. event porta les dades del disparador; context porta metadades (temps restant, identificadors).
  • Es valida l'entrada i, si falta l'id, es respon amb el codi HTTP 400 (petició incorrecta).
  • Es consulta la dada i es retorna un objecte amb statusCode, headers i body. El proveïdor (via API Gateway) tradueix aquest objecte en una resposta HTTP real.
  • El bloc catch registra l'error i retorna 500 per 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 funcio

Explicació: 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.

  1. 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

  1. 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.
  2. Una empresa té una API interna amb trànsit constant i elevat les 24 hores. Recomanaries serverless? Justifica-ho.
  3. Descriu un flux event-driven serverless per processar factures que es pugen a un emmagatzematge: quins disparadors i funcions encadenaries?

Solucions

  1. 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.
  2. 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.
  3. 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

Mòdul 2: Principis i Tàctiques de Disseny

Mòdul 3: Estils i Patrons Arquitectònics

Mòdul 4: Arquitectures Distribuïdes i Microserveis

Mòdul 5: Arquitectures Dirigides per Esdeveniments i Missatgeria

Mòdul 6: Disseny Dirigit pel Domini (DDD)

Mòdul 7: Dades i Persistència

Mòdul 8: Arquitectura al Núvol i Desplegament

Mòdul 9: Qualitat, Seguretat i Observabilitat

Mòdul 10: Evolució, Governança i Casos Pràctics

© Copyright 2026. Tots els drets reservats