Ai auzit termenul „serverless" de sute de ori. Și de fiecare dată cineva simte nevoia să precizeze: „nu înseamnă că nu sunt servere." Corect. Serverele există, dar nu mai sunt treaba ta. AWS le gestionează, le scalează, le patch-uiește, și tu plătești doar când codul tău rulează efectiv. Zero trafic? Zero cost.
În articolele precedente am vorbit despre migrarea unei aplicații clasice (React + Node.js + PostgreSQL + Redis) pe EC2 cu Auto Scaling și despre zero-downtime deployment. Acum explorăm alternativa radicală: ce-ar fi dacă ai elimina complet serverele din ecuație?
Ce este serverless, concret?
Serverless înseamnă că scrii funcții (bucăți de cod) care se execută ca reacție la evenimente — un request HTTP, un fișier uploadat în S3, un mesaj într-o coadă SQS, o modificare în baza de date. Nu provisionezi servere, nu configurezi Auto Scaling Groups, nu te gândești la câtă memorie RAM are instanța.
Pe AWS, ecosistemul serverless se construiește din câteva servicii cheie:
AWS Lambda — motorul de compute. Scrii o funcție (Node.js, Python, Java, Go, etc.), o uploadezi, și Lambda o execută de fiecare dată când primește un eveniment. Scalează automat de la zero la mii de execuții simultane.
API Gateway — ușa de intrare. Primește request-urile HTTP/HTTPS și le rutează către funcțiile Lambda. Gestionează autentificarea, rate limiting-ul, și versionarea API-ului.
DynamoDB — baza de date serverless. NoSQL, complet gestionată, cu scalare automată și latență de milisecunde. Plătești per request și per GB stocat.
S3 + CloudFront — pentru frontend-ul static (React/Vue), identic cu arhitectura clasică.
SQS / SNS / EventBridge — pentru comunicarea asincronă între funcții.
Cum arată codul unei funcții Lambda?
Hai să pornim de la un exemplu concret. Ai un endpoint care returnează o listă de produse din DynamoDB:
// handler.js
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
const { DynamoDBDocumentClient, ScanCommand } = require('@aws-sdk/lib-dynamodb');
const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);
exports.getProducts = async (event) => {
try {
const result = await docClient.send(
new ScanCommand({ TableName: 'Products' })
);
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result.Items)
};
} catch (error) {
return {
statusCode: 500,
body: JSON.stringify({ error: 'Internal Server Error' })
};
}
};
Funcția primește un event (care conține detalii despre request-ul HTTP — path, headers, body, query parameters) și returnează un obiect cu statusCode, headers și body. Atât. Nicio configurare de Express, niciun server care ascultă pe un port, nicio gestionare a proceselor.
Diferența fundamentală față de o aplicație Node.js clasică: nu ai un proces care rulează permanent. Funcția se „trezește" la fiecare request, execută codul, și se oprește. AWS menține un pool de containere pregătite pentru a minimiza latența (dar la primul apel după o perioadă de inactivitate, vei experimenta un „cold start" de 100-500ms).
Cum se face deploy?
Deployment-ul serverless e radical diferit de cel pe EC2. Nu ai instanțe de actualizat, nu ai rolling deployment sau blue/green. Uploadezi codul, și noua versiune e live.
Opțiunea 1: AWS SAM (Serverless Application Model) — cel mai popular framework. Definești infrastructura într-un fișier template.yaml:
# template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: nodejs20.x
Timeout: 10
MemorySize: 256
Resources:
GetProductsFunction:
Type: AWS::Serverless::Function
Properties:
Handler: handler.getProducts
Events:
Api:
Type: HttpApi
Properties:
Path: /products
Method: get
Policies:
- DynamoDBReadPolicy:
TableName: Products
ProductsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: Products
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
Deploy-ul se face cu două comenzi:
sam build
sam deploy --guided
SAM împachetează codul, creează un stack CloudFormation, provisionează Lambda, API Gateway și DynamoDB — totul dintr-un singur fișier de configurare. Actualizarea? Modifici codul sau template-ul și rulezi din nou sam deploy.
Opțiunea 2: Serverless Framework — alternativa populară cu ecosistem bogat de plugin-uri. Folosește serverless.yml în loc de template.yaml, dar principiul e identic.
Opțiunea 3: AWS CDK (Cloud Development Kit) — pentru cine preferă să definească infrastructura în cod (TypeScript, Python) în loc de YAML. Mai verbose, dar mai flexibil și mai ușor de testat.
Integrarea cu CI/CD e simplă. În GitHub Actions, adaugi un step care rulează sam build && sam deploy --no-confirm-changeset. În GitLab CI/CD, la fel. Nu mai ai nevoie de CodeDeploy — SAM gestionează totul prin CloudFormation.
Avantajele reale ale serverless
Zero administrare de infrastructură. Nu există servere de patch-uit, nu există OS-uri de actualizat, nu există configurări de Nginx. Echipa se concentrează 100% pe cod.
Scalare automată la zero. Cu EC2, chiar și cu Auto Scaling, plătești minim 2 instanțe 24/7 (~$67/lună). Cu Lambda, dacă nimeni nu accesează API-ul, costul e literal $0.
Plata per execuție. Lambda costă $0.20 per milion de request-uri plus $0.0000166667 per GB-secundă de compute. Free tier-ul include 1 milion de request-uri și 400.000 GB-secunde pe lună — permanent, nu doar 12 luni.
Exemplu de cost concret: o aplicație cu 5 milioane de request-uri pe lună, fiecare funcție cu 256MB memorie și 200ms durată medie, costă aproximativ $4-5/lună pe Lambda. Aceeași aplicație pe EC2 cu ALB costă minim $90-100/lună.
Deploy instant. Uploadezi codul, Lambda îl servește imediat. Nu există rolling update, nu există downtime. Poți folosi alias-uri și versiuni Lambda pentru canary deployment dacă vrei.
Reziliență built-in. Lambda rulează automat în multiple Availability Zones. Dacă o zonă pică, traficul merge automat la altele. Nu trebuie să configurezi nimic.
Dezavantajele pe care trebuie să le știi
Cold starts. Când o funcție nu a fost invocată recent, primul apel poate dura 100-500ms în plus (sau chiar mai mult pentru funcții Java). Soluția: Provisioned Concurrency (funcții pre-încălzite), dar costă suplimentar.
Limita de 15 minute. O funcție Lambda nu poate rula mai mult de 15 minute. Procesările lungi trebuie sparte în pași mai mici (Step Functions) sau mutate pe ECS/EC2.
Timeout API Gateway: 29 secunde. Dacă funcția Lambda nu răspunde în 29 de secunde prin API Gateway, request-ul primește timeout. Pentru operații lungi, folosești pattern-ul async: funcția pornește procesarea, returnează un job ID, iar clientul face polling.
Vendor lock-in. Codul Lambda e strâns legat de ecosistemul AWS. Migrarea pe alt cloud provider necesită refactorizare semnificativă. Poți mitiga parțial cu framework-uri ca Serverless Framework care abstractizează provider-ul.
Debugging mai dificil. Nu te poți conecta cu SSH pe server să vezi ce se întâmplă. Depinzi de CloudWatch Logs, X-Ray pentru tracing, și testare locală cu SAM CLI (sam local invoke).
Complexitate arhitecturală. O aplicație cu 50 de funcții Lambda, 10 cozi SQS și 5 tabele DynamoDB poate fi mai greu de înțeles și debuguit decât un singur server Node.js.
Serverless vs. EC2: Când alegi ce?
Alege serverless când: traficul e variabil sau imprevizibil (de la 0 la spike-uri masive), vrei time-to-market rapid, echipa e mică și nu vrei să gestioneze infrastructură, aplicația se descompune natural în funcții independente, sau bugetul pentru trafic mic trebuie minimizat.
Alege EC2/containers când: ai trafic constant și previzibil (24/7 la capacitate ridicată), aplicația are procese long-running (websockets, video processing), ai nevoie de control total asupra mediului de execuție, sau aplicația existentă e un monolit care nu se fragmentează ușor.
Varianta hibridă e adesea cea mai pragmatică: frontend pe CloudFront + S3, API principal pe Lambda + API Gateway, dar cu procese grele de background pe ECS Fargate sau EC2. PostgreSQL rămâne pe RDS, Redis pe ElastiCache — nu tot trebuie să fie serverless.
De la teorie la practică
Dacă vrei să testezi serverless fără să te angajezi la o migrare completă, începe cu un singur endpoint. Creează o funcție Lambda cu SAM, conecteaz-o la API Gateway, și vezi cum se comportă. Free tier-ul AWS acoperă lejer experimentarea.
Cel mai natural prim pas: mută procesările asincrone pe Lambda. Trimiterea de email-uri, generarea de PDF-uri, procesarea imaginilor, cron jobs — toate sunt candidați perfecți. Backend-ul principal poate rămâne pe EC2, iar Lambda preia sarcinile care nu trebuie să răspundă sincron.
Serverless nu e un „all or nothing." E un instrument în plus în toolbox-ul tău — extrem de puternic când e folosit în contextul potrivit.
Publicat pe teninvent.ro — TEN INVENT S.R.L. oferă consultanță și implementare de soluții serverless pe AWS. Contactează-ne pentru a evalua dacă serverless e potrivit pentru aplicația ta.