Orquestación de Procesos Descentralizada con RabbitMQ: Una Alternativa a Apache Camel
Un sistema para procesar grandes volúmenes de datos desde archivos FTP y flujos de Kafka/RabbitMQ utiliza una arquitectura de microservicios con más de 40 servicios. Anteriormente, las cadenas de procesamiento se implementaban con Apache Camel mediante DSL en Java con llamadas REST desde un servicio central. Los problemas incluían pérdida de estado durante reinicios, limitaciones de escalabilidad debido a flujos paralelos y riesgos durante las implementaciones.
Una nueva biblioteca de RabbitMQ con colas de quórum permite una gestión descentralizada. El estado se conserva en el broker, y los procesos se reanudan automáticamente. El servicio de inicialización escala horizontalmente.
Entidades Principales de la Biblioteca
La biblioteca incluye clases e interfaces para pasos, rutas y ejecutores:
- RouteStepInfo: Identifica un paso en una ruta.
public class RouteStepInfo {
private final String routeName;
private final String stepId;
public RouteStepInfo(String routeName, String stepId) {
this.routeName = routeName;
this.stepId = stepId;
}
}
- StepExecutor: Interfaz para ejecución asíncrona/síncrona/desacoplada.
public interface StepExecutor {
String getStepName();
void runAsync(RouteStepInfo routeStepInfo, Long objectId);
void runSync(RouteStepInfo routeStepInfo, Long objectId);
void runDetached(RouteStepInfo routeStepInfo, Long objectId);
void appendListener(StepExecutionFinishedListener listener);
}
- StepExecutionFinishedListener: Callback para la finalización de un paso.
public interface StepExecutionFinishedListener {
void onStepExecutionFinished(RouteStepInfo routeStepInfo, Long objectId);
}
- RouteStep: Paso con modos ASYNC, SYNC, DETACHED.
public interface RouteStep {
String getRouteName();
String getStepId();
String getStepName();
ExecutionMode getExecutionMode();
void run(Long objectId);
void appendListener(StepExecutionFinishedListener listener);
enum ExecutionMode {
ASYNC,
SYNC,
DETACHED
}
}
- ExecutionRoute: Ruta como una lista de pasos con índices.
@Slf4j
public class ExecutionRoute {
@Getter
private final String routeName;
private final List<RouteStep> routeSteps;
private final Map<String, Integer> stepsIndex;
public ExecutionRoute(String routeName, List<RouteStep> routeSteps) {
this.routeName = routeName;
this.routeSteps = routeSteps;
this.stepsIndex = new HashMap<>();
for (int i = 0; i < routeSteps.size(); i++) {
stepsIndex.put(routeSteps.get(i).getStepId(), i);
}
}
}
Además: RoutesConfigBuilder para configuración, RouterConfigProvider para rutas, ProcessRouter como listener y ejecutor.
Modos de Ejecución de Pasos
La biblioteca admite tres modos:
- ASYNC: Lanzamiento secuencial en segundo plano, pasando al siguiente paso tras la finalización.
- SYNC: Llamada bloqueante, que retorna después de toda la cadena.
- DETACHED: Lanzamiento sin esperar, avanzando inmediatamente.
Las combinaciones permiten ramificación y paralelismo:
- Ruta 1: Pasos SYNC 1→2→3.
- Ruta 2: Pasos ASYNC 1→2→3, retornando inmediatamente.
- Ruta 3: ASYNC con paso DETACHED 2.
- Ruta 5: Subruta paralela Ruta 4.
Implementación y Migración
Las pruebas de carga confirmaron la funcionalidad. La migración es por fases: reemplazando partes de Camel con conmutación A/B. Las dependencias existentes se mantienen para revertir.
Puntos clave:
- El estado en RabbitMQ garantiza la reanudación tras reinicios.
- Escalabilidad horizontal del inicializador.
- Configuración transparente mediante builder.
- Soporte para ramificación y paralelismo sin un servicio centralizado.
Este enfoque es adecuado para sistemas con altos requisitos de fiabilidad y escalabilidad.
— Editorial Team
Aún no hay comentarios.