
La informática sin servidor permite a los desarrolladores crear y ejecutar aplicaciones sin administrar servidores. El proveedor de la nube maneja toda la infraestructura: aprovisionamiento, escalamiento, parches y mantenimiento. Los desarrolladores escriben funciones, configuran activadores y la plataforma se encarga del resto.
La informática sin servidor permite a los desarrolladores crear y ejecutar aplicaciones sin administrar servidores. El proveedor de la nube maneja toda la infraestructura: aprovisionamiento, escalamiento, parches y mantenimiento. Los desarrolladores escriben funciones, configuran activadores y la plataforma se encarga del resto.
El nombre "sin servidor" es engañoso: los servidores todavía están involucrados. Pero el desarrollador nunca piensa en ellos. Este cambio de la gestión de infraestructura a la lógica pura de las aplicaciones está transformando la forma en que se crean e implementan las aplicaciones.
┌─────────────────────┐
│ Event Source │
│ (HTTP, Queue, Timer,│
│ Storage, etc.) │
└──────────┬──────────┘
│ Trigger
▼
┌──────────────────────────────────────────────────┐
│ Serverless Function │
│ ┌────────────────────────────────────────────┐ │
│ │ 1. Cold Start (if needed) │ │
│ │ - Provision sandbox │ │
│ │ - Initialize runtime (Node, Python) │ │
│ │ - Load dependencies │ │
│ ├────────────────────────────────────────────┤ │
│ │ 2. Execute handler function │ │
│ │ 3. Return response │ │
│ └────────────────────────────────────────────┘ │
│ Auto-scales horizontally │
│ from 0 to N concurrent executions │
└──────────────────────────────────────────────────┘
// AWS Lambda handler
exports.handler = async (event) => {
const { name } = JSON.parse(event.body);
const response = {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: `Hello, ${name}!`,
timestamp: new Date().toISOString()
})
};
return response;
};
| Aspecto | Tradicional (servidores) | Sin servidor |
|---|---|---|
| Gestión de servidores | Requerido (parches, actualizaciones) | Ninguno |
| Escalado | Grupos de escalado manual o automático | Automático, de 0 a 1000s |
| Facturación | Por hora/instancia (costo inactivo) | Por ejecución + por memoria (sin costo de inactividad) |
| Arranques en frío | N/A (siempre activado) | 100 ms-1 s para la invocación inicial |
| Ejecución máxima | Ilimitado | Tiempo de espera (15 min Lambda, 10 min Funciones de nube) |
| Estado | Persistente (estado en memoria) | Apátrida por diseño |
| Implementación | Servidor o contenedor completo | Función única |
| Granularidad | Monolito o servicio | Función única |
| Fuente del evento | Proveedor | Caso de uso |
|---|---|---|
| HTTP (Puerta de enlace API) | AWS, Azure, GCP | API REST, webhooks |
| Cambio de base de datos (CDC) | Flujos de DynamoDB, fuente de cambios de CosmosDB, Firestore | Sincronizar datos, activar flujos de trabajo |
| Carga de archivos | S3, almacenamiento de blobs, almacenamiento en la nube | Procesamiento de imágenes, validación de archivos. |
| Cola de mensajes | SQS, almacenamiento en cola, Pub/Sub | Procesamiento asíncrono desacoplado |
| Transmitir | Kinesis, centros de eventos, pub/sub | Procesamiento de datos en tiempo real |
| Horario | Eventos de CloudWatch, temporizador, programador | Trabajos cron, procesamiento por lotes |
| Correo electrónico | SES, SendGrid | Procesamiento de correo electrónico |
| IoT | Núcleo de IoT, Event Grid | Procesamiento de telemetría del dispositivo |
# AWS SAM template — Function triggered by multiple events
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
OrderProcessor:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: orders.handler
Runtime: nodejs20.x
Events:
HttpPost:
Type: Api
Properties:
Path: /orders
Method: POST
QueueConsumer:
Type: SQS
Properties:
Queue: !GetAtt OrderQueue.Arn
BatchSize: 10
StreamProcessor:
Type: DynamoDB
Properties:
Stream: !GetAtt OrdersTable.StreamArn
StartingPosition: TRIM_HORIZON
┌──────────┐
│ User │
│ Uploads │
└────┬─────┘
▼
┌─────────────────┐
│ S3 Bucket │
│ (upload/raw) │
└────────┬────────┘
│ trigger
▼
┌─────────────────┐
│ Lambda │
│ (process.ts) │
│ │
│ 1. Read image │
│ 2. Resize │
│ 3. Compress │
│ 4. Extract │
│ metadata │
└────────┬────────┘
│
┌───────┴───────┐
▼ ▼
┌────────────┐ ┌──────────────┐
│ S3 Bucket │ │ DynamoDB │
│ (processed)│ │ (metadata) │
└────────────┘ └──────────────┘
// process.ts — Image processing Lambda
import { S3 } from '@aws-sdk/client-s3';
import { DynamoDB } from '@aws-sdk/client-dynamodb';
import sharp from 'sharp';
const s3 = new S3();
const dynamo = new DynamoDB();
const SUPPORTED_FORMATS = ['image/jpeg', 'image/png', 'image/webp'];
export const handler = async (event: S3Event) => {
const results = await Promise.allSettled(
event.Records.map(async (record) => {
const bucket = record.s3.bucket.name;
const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));
// Validate file type
const headResult = await s3.headObject({ Bucket: bucket, Key: key });
if (!SUPPORTED_FORMATS.includes(headResult.ContentType!)) {
console.log(`Unsupported format: ${headResult.ContentType}`);
return;
}
// Read original
const { Body } = await s3.getObject({ Bucket: bucket, Key: key });
const buffer = await Body!.transformToByteArray();
// Process: resize to multiple sizes
const sizes = [
{ suffix: 'thumbnail', width: 150, height: 150 },
{ suffix: 'medium', width: 800, height: 600 },
{ suffix: 'large', width: 1920, height: 1080 },
];
for (const size of sizes) {
const processed = await sharp(buffer)
.resize(size.width, size.height, { fit: 'cover' })
.webp({ quality: 80 })
.toBuffer();
const outputKey = key.replace('raw', `processed/${size.suffix}`);
await s3.putObject({
Bucket: bucket.replace('-raw', '-processed'),
Key: outputKey,
Body: processed,
ContentType: 'image/webp',
});
}
// Store metadata
await dynamo.putItem({
TableName: 'ImageMetadata',
Item: {
imageId: { S: key },
originalSize: { N: buffer.byteLength.toString() },
formats: { SS: ['thumbnail', 'medium', 'large'] },
uploadedAt: { S: new Date().toISOString() },
},
});
})
);
const failed = results.filter(r => r.status === 'rejected');
if (failed.length > 0) {
throw new Error(`${failed.length} images failed processing`);
}
return { processed: results.length - failed.length, failed: failed.length };
};
Cuando una función está inactiva, la plataforma recupera sus recursos. La siguiente invocación requiere:
Arranque en frío total: 100 ms a 2 s según el tiempo de ejecución y el tamaño del paquete.
| Tiempo de ejecución | Arranque en frío (mediana) | Arranque en frío (p99) |
|---|---|---|
| pitón | 200 ms | 500ms |
| Nodo.js | 250 ms | 600 ms |
| ir | 100 ms | 300 ms |
| .NET | 500ms | 2s |
| Java | 800ms | 3s |
| óxido | 100 ms | 250 ms |
| Estrategia | Cómo funciona | Impacto en los costos |
|---|---|---|
| Simultaneidad aprovisionada (Lambda) | Mantenga N instancias siempre calientes | Paga por instancias cálidas |
| Inicio instantáneo (Lambda) | Preinicialización y tiempo de ejecución de instantáneas | Costo adicional mínimo |
| Pings para mantener el calor | Invocaciones periódicas cada 5 minutos | insignificante |
| Tiempo de ejecución más ligero | Utilice Node.js/Python/Go en lugar de Java | Sin coste adicional |
| Minimizar dependencias | Paquetes de implementación más pequeños | Sin coste adicional |
La mayoría de las plataformas sin servidor cobran según:
Scenario: API handling 1M requests/month, 200ms avg execution, 512MB memory
Traditional (t3.small, $0.0208/hr):
$0.0208 × 730 hours = $15.18/month (always on)
Serverless (Lambda):
Requests: 1M × $0.20/1M = $0.20
Duration: 1M × 0.2s × 512MB/1024MB × $0.0000166667/GB-s = $1.67
Total: $1.87/month
Savings: ~87% at low traffic
Breakeven point: At ~45M requests/month, traditional becomes cheaper
# Serverless cost optimization checklist
cost_optimization:
- "Right-size memory: 128MB may be sufficient, but 1769MB costs 14x more"
- "Use AWS Compute Optimizer for memory recommendations"
- "Minimize function duration (optimize code, use async where possible)"
- "Use reserved concurrency only when needed"
- "Delete unused functions and resources"
- "Use Lambda SnapStart for Java/.NET to reduce duration"
- "Leverage Lambda@Edge or CloudFront Functions for edge processing"
| Servicio | Proveedor | Característica clave |
|---|---|---|
| AWS Lambda | AWS | Ecosistema más grande, tiempo de espera de 15 minutos |
| Funciones de Azure | microsoft | Integración profunda de Office 365/Teams |
| Funciones en la nube | Integración eventarc primero en Python | |
| Trabajadores de Cloudflare | Llamarada de nube | Basado en el borde, arranques en frío <1 ms, scripts de 30 MB |
| Servicio | Tipo | Función sin servidor |
|---|---|---|
| DynamoDB | Valor-clave + Documento | Capacidad bajo demanda, escalamiento automático |
| Aurora sin servidor | Relacional (MySQL/PostgreSQL) | Capacidad informática de escalamiento automático |
| CosmosDB | Multimodelo | Modo de rendimiento sin servidor |
| Firestore | Documento | Escalado automático y sincronización en tiempo real |
| Neón | PostgreSQL sin servidor | Ramificación, suspensión automática |
| Servicio | Caso de uso |
|---|---|
| S3/Blob/Almacenamiento en la nube | Almacenamiento de archivos, desencadenadores de eventos |
| ElastiCache sin servidor | Almacenamiento en caché en memoria |
| SQS/almacenamiento en cola | Cola de mensajes |
| EventBridge/Event Grid | Autobús de eventos |
Procese varios elementos en paralelo:
SQS Queue → Lambda → SNS Topic → Lambda (email)
→ Lambda (SMS)
→ Lambda (push)
→ Lambda (logging)
// Order saga with compensation
async function createOrder(event) {
const { orderId, userId, items, total } = event;
try {
await reserveInventory(items);
await processPayment(userId, total);
await createShipment(orderId);
await sendConfirmation(userId);
return { status: 'completed', orderId };
} catch (error) {
// Compensating transactions (undo)
await cancelShipment(orderId);
await refundPayment(userId, total);
await releaseInventory(items);
throw error;
}
}
Maneje los picos de tráfico almacenando en búfer las solicitudes:
API Gateway → SQS (buffer) → Lambda (process)
↑
Process at your own pace
// Store events, derive current state
interface OrderEvent {
type: 'CREATED' | 'ITEM_ADDED' | 'PAID' | 'SHIPPED' | 'CANCELLED';
orderId: string;
timestamp: string;
data: Record<string, any>;
}
// Function: store event
exports.recordEvent = async (event: OrderEvent) => {
await dynamo.putItem({
TableName: 'OrderEvents',
Item: marshal(event)
});
// Don't modify order state directly
};
// Function: rebuild state from events
exports.getOrderState = async (orderId: string) => {
const events = await queryEvents(orderId);
return events.reduce((state, event) => applyEvent(state, event), initialState);
};
// Structured logging for serverless
const logger = {
info: (message: string, context?: object) => {
console.log(JSON.stringify({
timestamp: new Date().toISOString(),
level: 'INFO',
message,
aws_request_id: context.awsRequestId,
function_name: context.functionName,
...context
}));
},
error: (message: string, error?: Error) => {
console.error(JSON.stringify({
timestamp: new Date().toISOString(),
level: 'ERROR',
message,
error_name: error?.name,
error_message: error?.message,
stack: error?.stack,
}));
}
};
// X-Ray tracing
import { AWS } from '@aws-sdk/client-lambda';
import { captureAWS } from 'aws-xray-sdk-core';
const lambda = captureAWS(new AWS.Lambda());
exports.handler = async (event) => {
const segment = new Segment('process_order');
// ... function logic with automatic subsegment tracking
};
Métricas clave a monitorear:
| Escenario | Por qué la tecnología sin servidor no es ideal | Alternativa |
|---|---|---|
| Procesos de larga duración (>15 min) | Tiempo de espera de ejecución | Contenedores, máquinas virtuales |
| Aplicaciones con estado | Apátrida por diseño | Servicios con estado (WebSocket API, Redis) |
| Alto tráfico constante (>100 solicitudes/s sostenidas) | Los costos exceden la capacidad aprovisionada | Contenedores de escalado automático |
| Requisitos de baja latencia (<10 ms) | Arranque en frío por encima | Simultaneidad aprovisionada, funciones de borde |
| Orquestación compleja | La composición de funciones es difícil | Funciones de paso, flujos de trabajo |
| Funciones específicas de la plataforma | Capacidades de tiempo de ejecución limitadas | Acceso completo al sistema operativo (contenedores) |
La arquitectura sin servidor es ideal para:
Comience con la tecnología sin servidor para:
Migre a contenedores cuando:
La tecnología sin servidor no es la respuesta a todo, pero para las cargas de trabajo adecuadas, reduce drásticamente la sobrecarga operativa y el tiempo de desarrollo.
Todavía no hay comentarios aprobados. Las respuestas nuevas pueden esperar moderación.