Diseñar la arquitectura de servicios para un e-commerce

Lectura
25 min~5 min lectura

Concepto clave

Diseñar una arquitectura de servicios para un e-commerce con gRPC implica descomponer el dominio en servicios acoplados débilmente que se comunican mediante contratos tipados. Piensa en un centro comercial: cada tienda (servicio) tiene su propia especialidad (productos, pagos, inventario), pero todas siguen reglas comunes (Protocol Buffers) para interactuar. gRPC actúa como el sistema de mensajería interno que garantiza que los pedidos entre tiendas sean rápidos y sin errores.

La clave está en definir interfaces claras usando Protocol Buffers, que sirven como contrato entre servicios. Esto evita que cambios en un servicio rompan otros, similar a cómo un contrato legal protege a ambas partes en un negocio. Para un e-commerce, servicios como Catálogo, Carrito, Pagos, y Envíos deben operar de forma independiente pero coordinada, usando gRPC para llamadas síncronas (como verificar stock) y streams para datos en tiempo real (como notificaciones de pedidos).

Cómo funciona en la práctica

Imagina que un usuario agrega un producto al carrito. Primero, el servicio Frontend llama al servicio Carrito via gRPC para agregar el ítem. El servicio Carrito, a su vez, llama al servicio Catálogo para validar el precio y disponibilidad. Aquí, Protocol Buffers define los mensajes, por ejemplo:

message AddToCartRequest {
  string user_id = 1;
  string product_id = 2;
  int32 quantity = 3;
}

message AddToCartResponse {
  bool success = 1;
  string message = 2;
  double total_price = 3;
}

Paso a paso: 1) Define los archivos .proto para cada servicio, especificando métodos y mensajes. 2) Genera código en tu lenguaje (ej., Go o Java) usando el compilador protoc. 3) Implementa servidores gRPC que expongan estos métodos. 4) Configura clientes en otros servicios para llamar a estos métodos. 5) Usa middleware para manejar logs, métricas y retries, asegurando resiliencia.

Caso de estudio

Considera un e-commerce con 1 millón de usuarios diarios. Desglosamos en servicios:

ServicioResponsabilidadgRPC Métodos Clave
CatálogoGestionar productos y preciosGetProduct, ListProducts, UpdateStock
CarritoManejar carritos de compraAddItem, RemoveItem, Checkout
PagosProcesar transaccionesProcessPayment, Refund
EnvíosGestionar logísticaCreateShipment, TrackOrder

Ejemplo concreto: Cuando un usuario finaliza una compra, el servicio Carrito llama a Pagos via gRPC con un mensaje ProcessPaymentRequest. Si el pago es exitoso, Carrito notifica a Envíos para crear un envío, usando un stream gRPC para actualizaciones en tiempo real. Esto reduce la latencia a milisegundos vs. REST, crucial para alta concurrencia.

En pruebas, gRPC mostró un 60% menos de latencia que REST para 10,000 solicitudes concurrentes en un entorno de e-commerce.

Errores comunes

  1. Definir mensajes .proto demasiado grandes: Esto acopla servicios y dificulta evoluciones. Solución: Mantén mensajes pequeños y usa imports para reutilizar definiciones comunes.
  2. Ignorar el manejo de errores en gRPC: gRPC usa códigos de estado (ej., NOT_FOUND, INTERNAL), pero muchos devs no los mapean correctamente. Implementa interceptores para traducir errores de negocio a códigos gRPC apropiados.
  3. No planificar versiones de Protocol Buffers: Cambiar un campo .proto puede romper clientes. Usa reglas como no eliminar campos y marcar obsoletos con reserved.
  4. Olvidar timeouts y retries: En microservicios, las fallas de red son comunes. Configura timeouts específicos por método y usa políticas de retry con backoff exponencial.
  5. Sobrecargar servicios con lógica de negocio cruzada: Ej., poner lógica de inventario en el servicio Carrito. Mantén responsabilidades claras para evitar acoplamiento.

Checklist de dominio

  • ¿Definiste archivos .proto separados por servicio con mensajes y servicios claros?
  • ¿Implementaste servidores gRPC con manejo de errores usando códigos de estado estándar?
  • ¿Configuraste clientes gRPC con timeouts, retries y balanceo de carga?
  • ¿Usaste streams gRPC para casos como notificaciones en tiempo real?
  • ¿Integraste middleware para observabilidad (logs, métricas, tracing)?
  • ¿Probaste la interoperabilidad entre servicios en diferentes lenguajes?
  • ¿Documentaste las APIs gRPC generadas para otros equipos?

Diseñar e implementar un servicio de carrito con gRPC

En este ejercicio, crearás un servicio de carrito para un e-commerce usando gRPC y Protocol Buffers. Sigue estos pasos:

  1. Define el contrato .proto: Crea un archivo cart.proto con un servicio CartService que incluya métodos como AddItem, RemoveItem, y GetCart. Define mensajes como CartItem y CartResponse, usando tipos apropiados (ej., string para user_id, int32 para quantity).
  2. Genera el código: Usa el compilador protoc para generar código en tu lenguaje preferido (ej., Go, Java, o Python). Asegúrate de incluir opciones para gRPC.
  3. Implementa el servidor: Crea un servidor gRPC que maneje los métodos definidos. Por ejemplo, en AddItem, valida la cantidad y calcula el precio total llamando a un servicio simulado de catálogo.
  4. Crea un cliente de prueba: Implementa un cliente que llame a AddItem con datos de ejemplo (ej., user_id="123", product_id="prod_abc", quantity=2) y muestre la respuesta.
  5. Añade resiliencia: Configura timeouts de 5 segundos para las llamadas y un retry policy con 3 intentos para fallas temporales.
  6. Prueba la integración: Ejecuta el servidor y cliente, verificando que las respuestas sean correctas y los errores se manejen adecuadamente.
Pistas
  • Usa el paquete google.golang.org/grpc si trabajas en Go para simplificar la implementación.
  • Para simular el servicio de catálogo, puedes crear un mock que devuelva un precio fijo, como 29.99.
  • Considera usar un mapa en memoria para almacenar los carritos por user_id en el servidor, pero recuerda que en producción necesitarías una base de datos.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.