Microservicios: cuándo no.
Una junta de dos horas, seis personas y un diagrama en el pizarrón con once cajitas y flechas entre casi todas. Cuando ya estaba dibujado, alguien preguntó cuántos ingenieros había en el equipo. Eran cuatro.
Esa junta pasa seguido, y la pregunta que la convoca llega casi siempre con la misma forma: ¿deberíamos migrarnos a microservicios? Es una pregunta sobre cómo está organizado tu equipo y cuántas cosas quieres poder desplegar sin pedirle permiso a nadie.
Esta nota defiende que elijas a sabiendas.
Lo que compras
Un microservicio te vende exactamente un producto: independencia de despliegue. Un pedazo del sistema puede salir a producción en su propio horario, con su propio riesgo, sin coordinarse con el resto.
Todo lo demás que se le atribuye (escalar por partes, usar otro lenguaje, aislar fallos, separar responsabilidades) se puede conseguir sin partir el despliegue, y casi siempre más barato:
- Escalar por partes. Un mismo binario desplegado en dos grupos de máquinas, uno atendiendo tráfico web y otro consumiendo una cola, ya escala por partes. No hacen falta dos repositorios.
- Aislar fallos. Bulkheads, timeouts, límites de concurrencia y circuit breakers son patrones de proceso. Funcionan igual dentro de un solo binario.
- Separar responsabilidades. Eso son módulos con fronteras que alguien defiende. La frontera la imponen la disciplina y el compilador.
Si lo que te duele es alguna de esas tres cosas, hay una respuesta más corta que partir el sistema.
Lo que pagas
El costo tiene un nombre concreto: cada llamada de función se convierte en un problema de red. Esa frase parece pequeña escrita. No lo es.
Lo que en el panel A era esto:
total = pagos.cobrar(carrito)
en el panel B es esto, y ninguna de las líneas nuevas es opcional:
total = pagos.cobrar(
carrito,
timeout = 800ms, # ¿cuánto es demasiado?
reintentos = 3, # ¿y si el cobro sí pasó?
clave_idem = pedido.id, # por eso hace falta esta
contrato = "v2", # y por eso hace falta esta otra
)
# y si aun así no contesta: ¿el pedido queda cobrado, cancelado o pendiente?
Esa última línea es la factura. En el panel A la pregunta no existía: o corría la función o no corría. En el panel B existe un estado nuevo (no sé) y alguien tiene que diseñarlo, probarlo, monitorearlo y explicárselo a soporte.
Multiplícalo por cada frontera que cruces. Aparecen, todos juntos y el mismo mes:
- fallos parciales y el estado no sé;
- latencia de cola larga (tail latency): la petición más lenta manda, y ahora hay cuatro oportunidades de ser la más lenta;
- idempotencia obligatoria en cualquier cosa que cobre, cargue o envíe;
- versionado de contratos y despliegues que ya no pueden ir en cualquier orden;
- consistencia eventual donde antes había una transacción;
- trazas distribuidas, porque sin ellas depurar es adivinar;
- entornos: levantar el sistema completo en la laptop deja de ser gratis.
Una señal barata de diagnóstico. Pregunta cuántas veces al mes el equipo despliega y cuántas de esas hubo que coordinar con otro equipo. Si la respuesta es «desplegamos los jueves y no coordinamos con nadie», tienes un problema de frecuencia de despliegue, y ese se arregla con pipeline.
Conway, en la dirección correcta
La ley de Conway dice que los sistemas terminan pareciéndose a la estructura de comunicación de la organización que los construye. La lectura útil es la inversa: no compres una topología de sistema que no corresponde a tu topología de equipos.
Cuatro servicios y un equipo dan cuatro repositorios que la misma gente tiene que desplegar en orden. Eso es un monolito distribuido: el monolito con la factura de red incluida y ninguno de sus beneficios.
El mejor microservicio puede ser el que decidimos no construir.
Cuándo no
Si alguna de estas es cierta hoy, la respuesta probablemente es todavía no:
- El equipo cabe en una sala. Con uno o dos equipos, la coordinación se resuelve en una junta de quince minutos.
- El dominio todavía se mueve. Las fronteras que dibujes hoy se van a mover. Moverlas dentro de un repositorio cuesta una tarde; moverlas entre servicios cuesta un trimestre.
- No tienes observabilidad distribuida. Sin trazas correlacionadas, partir el sistema es apagar la luz antes de entrar.
- El cuello de botella está en la base de datos. Cuatro servicios contra la misma base de datos son cuatro clientes peleándose por el mismo recurso, con más conexiones y menos control del plan de consultas.
- Nadie está de guardia. Los sistemas distribuidos fallan de formas que solo se aprenden operándolos. Si no hay quien los opere, no los construyas.
Cuándo sí
Hay razones buenas, y son concretas y pocas:
- Dos o más equipos con dueños distintos se bloquean entre sí, con evidencia: despliegues detenidos, releases coordinados, filas de revisión.
- Una parte tiene un perfil de escala genuinamente distinto: mil veces más tráfico, o mil veces más caro por petición.
- Una parte tiene un perfil de riesgo o cumplimiento distinto y conviene aislarla también en operación.
- Una parte tiene un ciclo de vida distinto: cambia cada semana mientras el resto cambia cada trimestre.
Fíjate en el patrón: todas son afirmaciones verificables. Ninguna es «así se hace ahora».
Qué hacer mientras tanto
Casi siempre hay un camino intermedio que se paga solo:
- Pon fronteras dentro de un solo despliegue. Módulos con interfaz pública explícita, y una regla de compilación que impida importar sus adentros. Si el lenguaje puede fallar el build por una dependencia prohibida, mejor: el criterio deja de depender de que alguien lo recuerde en la revisión.
- Separa los datos antes que el proceso. Que cada módulo sea dueño de sus tablas y nadie más las lea directamente. Este es el trabajo difícil, y es el mismo trabajo que tendrías que hacer para extraer un servicio. Hazlo primero, donde equivocarse es barato.
- Haz que desplegar sea aburrido. Si desplegar da miedo, partir el sistema no lo va a quitar: lo va a multiplicar por cuatro.
- Extrae uno, cuando duela por una razón que puedas nombrar. El primero enseña cuánto cuesta en tu contexto. Sácalo, opéralo tres meses y vuelve a decidir con datos.
Si haces los tres primeros pasos y el cuarto ya no hace falta, hiciste el mismo trabajo de diseño y te ahorraste la red.
La arquitectura correcta es la que corresponde al tamaño de tu equipo, al estado de tu dominio y a lo que tu operación puede sostener un martes a las tres de la mañana. Elegir eso bien cuesta trabajo. Elegirlo mal cuesta más.
¿Tienes un problema parecido?
Si estás en medio de esta decisión y equivocarse sale caro, es exactamente el tipo de conversación que nos gusta tener.
Cuéntanoslo