Índice del curso
Lección 12 — Crecer en réplicas
Por Dorian Chávez · cofundador y Chief Executive Officer de Hábil ·
Lo que vas a lograr: correr tres copias de int-bd sin tocar los demás servicios, medir cómo se reparten las órdenes entre ellas, y descubrir por qué al principio no se reparten.
Antes de empezar necesitas: la lección 11 terminada y el ambiente de la 00 encendido (con el ERP recreado en la 10).
Lo nuevo de hoy, en una frase
Llega el Buen Fin y la tienda manda el triple de órdenes. El cuello de botella es int-bd, que escribe en el ERP.
Hoy escalas un solo servicio: en vez de una copia de int-bd corres tres, y el router las sigue llamando por el
mismo nombre, int-bd.
La imagen: una caja de banco que abre dos ventanillas más. Los clientes siguen formándose en la misma fila, y el banco pone a alguien que los mande a una ventanilla libre. Hoy vas a ver qué pasa cuando ese alguien no hace bien su trabajo.
Una réplica es una copia idéntica del mismo servicio: la misma imagen, la misma carpeta, las mismas rutas. int-bd se puede copiar sin que una orden se registre dos veces porque no guarda nada en memoria: todo lo que importa queda en el ERP.
1. Prepara tu carpeta
cd lecciones/12-crecer-en-replicas
cp -R inicio mio
Hoy no tocas ninguna ruta. Todo el trabajo va en un solo archivo, mio/replicas.yaml. Compose lo junta con el
compose.yaml de la lección, que no se toca: Compose los fusiona campo por campo: un
command del segundo archivo sustituye al del primero, y en environment cada variable se agrega o
reemplaza a la del mismo nombre.
DONDE=mio docker compose -f compose.yaml -f mio/replicas.yaml up -d
Es la misma idea del franquicias.yaml de la 11: cambiar cómo corre un servicio sin cambiar el servicio.
2. Predice
Hoy usas un lote nuevo: datos/ordenes/lote-30/, el lote de 30 órdenes, todas de tiendas propias (el socio no
recibe ninguna). Contesta en un papel:
- Si corres tres copias de int-bd y mandas las 30 órdenes, ¿cuántas registra cada copia?
- ¿Quién decide a qué copia va cada orden: el router, Camel, Docker o el ERP?
Comprueba cómo está hoy:
./verifica inicio
Salen dos marcas rojas: int-bd corre en 1 copia(s) y se esperaban 3, y Con una sola copia no hay nada que repartir. El verifica imprime el reparto, y hoy es int-bd-1=30: una sola copia hace todo.
3. Pide tres copias
En mio/replicas.yaml, el TODO 1. Pide tres copias de int-bd con deploy → replicas:
services:
int-bd:
deploy:
replicas: 3
Corre el verifica:
./verifica
Mira la línea Reparto:. Lo que vimos al probarla:
Reparto: practica-retail-l12-int-bd-1=0 practica-retail-l12-int-bd-2=0 practica-retail-l12-int-bd-3=30
❌ 2 de 3 copias no registraron nada: el router sigue usando la misma conexión.
Las tres copias están arriba, pero una hace todo y dos no hacen nada. ¿Acertaste el 10/10/10? Casi nadie lo acierta, porque parece obvio. Antes de seguir, escribe tu explicación: ¿por qué no se repartieron?
4. Por qué no se reparten
Hay dos razones, y van juntas.
La conexión se reusa. Abrir una conexión HTTP cuesta tiempo, así que el router abre una hacia int-bd y la
deja abierta (keep-alive). Todas las órdenes que siguen viajan por esa misma conexión, y una conexión va a una sola
copia. Docker no reparte peticiones: reparte conexiones.
La JVM recuerda la dirección. Cuando el router pregunta «¿dónde está int-bd?», el DNS de Docker contesta las
tres direcciones, en distinto orden cada vez. Pero la JVM del router guarda la primera respuesta y no vuelve a
preguntar en un buen rato.
| Lo que hace hoy | Lo que necesitas | |
|---|---|---|
| La conexión | Vive para siempre | Que venza pronto, para abrir otra |
La dirección de int-bd |
La JVM la recuerda | Que la olvide pronto, para volver a preguntar |
Con las dos cortas, cada conexión nueva vuelve a preguntar la dirección y puede caer en otra copia.
5. Haz que el router reparta
El TODO 2, en el mismo mio/replicas.yaml, dentro de orden-router. Son dos cosas:
a) Que la conexión viva a lo más un segundo. Es la opción connectionTimeToLive del componente http, en
milisegundos. Se le pasa al router al arrancar:
command: ["run", ".", "--prop=camel.component.http.connectionTimeToLive=1000"]
b) Que la JVM recuerde la dirección un segundo. Va en una variable de entorno que la JVM lee al arrancar:
environment:
JDK_JAVA_OPTIONS: "-Dsun.net.inetaddr.ttl=1"
Antes de poner la b, haz la prueba: pon solo la a y corre ./verifica. Al probar la lección, solo con la a el
reparto siguió en 0/0/30. La conexión ya vencía, pero la conexión nueva iba a la misma dirección que la JVM tenía
guardada. Ahora agrega la b y corre otra vez.
6. Comprueba
./verifica
verifica reinicia la API, vacía el ERP, levanta los servicios con tu replicas.yaml y manda las 30 órdenes con una
pausa entre cada una, para que el router tenga ocasión de abrir conexiones nuevas. Está terminada cuando ves las seis marcas verdes:
✅ int-bd corre en 3 copias
✅ Arrancaron el router, int-rest, int-edi y las copias de int-bd
✅ ERP: tiene las 30 órdenes REGISTRADO, cada una una sola vez
✅ API: tiene las 30 órdenes (crecer int-bd no tocó a los demás)
Reparto: practica-retail-l12-int-bd-1=12 practica-retail-l12-int-bd-2=12 practica-retail-l12-int-bd-3=6
✅ Entre todas las copias registraron 30 órdenes: ni una de más, ni una de menos
✅ (…) de 3 copias de int-bd registraron órdenes: el trabajo se repartió
Tu reparto va a ser distinto, y cambia en cada corrida: al probarla vimos 12/12/6 y 6/11/13. Quien elige la copia es la red, y la red no reparte exacto. Por eso el verifica no pide 10/10/10: pide que al menos dos copias reciban trabajo y que ninguna orden se pierda ni se repita. Puede tocarte que una copia se quede sin órdenes en una corrida: si las otras dos se repartieron las 30, está bien. Cada copia cuenta lo suyo en su propio log, así que el reparto lo dicen las copias, no el router.
¿No te corre? ./verifica solucion prueba la nuestra, y diff mio/replicas.yaml solucion/replicas.yaml te dice
en qué son distintas.
| Lo que ves | Qué haces |
|---|---|
int-bd corre en 1 copia(s) |
Falta el deploy → replicas: 3, o quedó debajo de otro servicio. Revisa la sangría |
2 de 3 copias no registraron nada |
Te falta la a, la b o las dos (paso 5) |
No pude levantar los servicios. Revisa que mio/replicas.yaml sea YAML válido |
Un error de sangría o de comillas; el verifica te enseña las últimas líneas del error |
Pusiste CAMEL_COMPONENT_HTTP_CONNECTION_TIME_TO_LIVE en environment y no reparte |
En esta versión esa variable no surte efecto (lo medimos: 0/29/0). Usa el --prop del paso 5 |
Tu ERP no tiene la columna correlacion |
Recrea el ERP como dice la 10 |
Lo que esto enseña fuera de la práctica
Se reparte por conexión, y una conexión eterna no se reparte. En Docker reparte el DNS. En Kubernetes, un Service también elige una copia por cada conexión nueva, así que el mismo problema aparece igual. Cambia quién reparte; la regla no.
El segundo es para que lo veas aquí, no una cifra para un sistema real. Cuánto debe vivir una conexión depende de cuánto tráfico hay y de qué tan seguido cambian las copias. Cerrarla después de cada orden también reparte, pero pagas el costo de abrir una conexión en cada llamada.
Ejercicio: crecer sin tocar a nadie
Con tu versión terminada, contesta solo con lo que ves en pantalla:
- Cambia
replicas: 3porreplicas: 5y corre./verifica. ¿Qué marca se pone roja, y por qué? (Pista: el verifica espera 3.) ¿Cuántas órdenes registró cada una de las cinco? - Regresa a 3. ¿Qué archivos tocaste para pasar de una copia a tres? ¿Tocaste alguna ruta, algún mapeo o el
compose.yamlde la lección? - ¿Por qué int-bd se puede copiar tres veces sin que una orden se registre dos veces? ¿Qué pasaría si cada copia guardara en su memoria las órdenes que ya vio?
Lo que ya funciona
Con esta lección cierras la parte 1. Una orden que la tienda crea ya hace todo esto:
- llega al router por HTTP y el router le contesta qué dijo cada destino;
- llega a la API una sola vez, aunque se reenvíe, gracias a su llave;
- entra al ERP completa o no entra, y el ERP puede crecer a varias copias;
- se vuelve un 850 que llega al socio sin pisarse ni quedar a medias, solo si la tienda es suya;
- lleva un hilo que la sigue por todos los servicios;
- y si un destino se cae, los demás la reciben igual.
Lo que todavía no hace: recordar en qué va cada orden. Eso empieza en la parte 2.
Por qué se hizo así
Lo que decidimos en esta lección, con lo que descartamos y qué nos haría cambiar de idea:
- Tres copias no reparten solas: el reparto es por conexión
- Una sola imagen; cada servicio es una carpeta
Repaso
- ¿Qué es una réplica, y por qué int-bd se puede copiar sin que una orden se registre dos veces?
- Con
replicas: 3y nada más, ¿cómo se repartieron las órdenes? ¿Por qué? - ¿Qué hace
connectionTimeToLive, y qué hacesun.net.inetaddr.ttl? ¿Por qué con una sola no basta? - ¿Por qué el verifica no pide 10/10/10, y qué pide en su lugar?
- La pregunta de cierre: si el router tuviera réplicas, ¿dónde viviría lo de cada orden? Escribe tu respuesta: la vas a comparar con la lección 15.
Siguiente: en la lección 13: llega el embarque. La bodega deja un archivo, y ahora que sabes correr copias, la pregunta es otra: si varias copias leen la misma carpeta, ¿quién toma el archivo?
¿Prefiere correo? Escríbanos a hola@habil.mx