Zurück zur Startseite

Dezentrale Orchestrierung auf RabbitMQ

Der Artikel beschreibt eine Bibliothek für dezentrale Orchestrierung auf RabbitMQ als Ersatz für Apache Camel. Im Detail: Entitäten, Ausführungsmodi, Migration. Vorteile: Zustandswiederherstellung, Skalierung.

RabbitMQ-Orchestrierung: Verzicht auf Camel in Microservices
Advertisement 728x90

Dezentrale Prozessorchestrierung mit RabbitMQ: Eine Alternative zu Apache Camel

Ein System zur Verarbeitung großer Datenmengen aus FTP-Dateien und Kafka/RabbitMQ-Streams nutzt eine Microservices-Architektur mit über 40 Diensten. Zuvor wurden Verarbeitungsketten mit Apache Camel über Java DSL mit REST-Aufrufen von einem zentralen Dienst implementiert. Probleme umfassten Zustandsverlust bei Neustarts, Skalierungsbeschränkungen durch parallele Streams und Risiken bei Releases.

Eine neue RabbitMQ-Bibliothek mit Quorum-Queues ermöglicht dezentrales Management. Der Zustand wird im Broker gespeichert, und Prozesse setzen automatisch fort. Der Initialisierungsdienst skaliert horizontal.

Kernbibliotheks-Entitäten

Die Bibliothek enthält Klassen und Schnittstellen für Schritte, Routen und Executors:

Google AdInline article slot
  • RouteStepInfo: Identifiziert einen Schritt in einer Route.
public class RouteStepInfo {
    private final String routeName;
    private final String stepId;

    public RouteStepInfo(String routeName, String stepId) {
        this.routeName = routeName;
        this.stepId = stepId;
    }
}
  • StepExecutor: Schnittstelle für asynchrone/synchrone/entkoppelte Ausführung.
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 für Schrittabschluss.
public interface StepExecutionFinishedListener {
    void onStepExecutionFinished(RouteStepInfo routeStepInfo, Long objectId);
}
  • RouteStep: Schritt mit ASYNC-, SYNC-, DETACHED-Modi.
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: Route als Liste von Schritten mit Indizes.
@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);
        }
    }
}

Zusätzlich: RoutesConfigBuilder für Konfiguration, RouterConfigProvider für Routen, ProcessRouter als Listener und Executor.

Schrittausführungsmodi

Die Bibliothek unterstützt drei Modi:

  • ASYNC: Sequentielle Hintergrundausführung, Fortsetzung nach Abschluss.
  • SYNC: Blockierender Aufruf, Rückkehr nach gesamter Kette.
  • DETACHED: Ausführung ohne Warten, sofortiges Fortfahren.

Kombinationen ermöglichen Verzweigung und Parallelität:

Google AdInline article slot
  • Route 1: SYNC-Schritte 1→2→3.
  • Route 2: ASYNC-Schritte 1→2→3, sofortige Rückkehr.
  • Route 3: ASYNC mit DETACHED-Schritt 2.
  • Route 5: Parallele Subroute Route 4.

Implementierung und Migration

Lasttests bestätigten Funktionalität. Migration erfolgt phasenweise: Ersetzen von Camel-Teilen mit A/B-Umschaltung. Bestehende Abhängigkeiten bleiben für Rollback erhalten.

Wichtige Punkte:

  • Zustand in RabbitMQ gewährleistet Fortsetzung nach Neustarts.
  • Horizontale Skalierung des Initialisierers.
  • Transparente Konfiguration über Builder.
  • Unterstützung für Verzweigung und Parallelität ohne zentralen Dienst.

Dieser Ansatz eignet sich für Systeme mit hohen Anforderungen an Zuverlässigkeit und Skalierbarkeit.

Google AdInline article slot

— Editorial Team

Advertisement 728x90

Weiterlesen