Retour à l'accueil

Orchestration décentralisée sur RabbitMQ

L'article décrit une bibliothèque pour orchestration décentralisée sur RabbitMQ en remplacement d'Apache Camel. En détail : entités, modes d'exécution, migration. Avantages : récupération d'état, mise à l'échelle.

Orchestration RabbitMQ : abandon de Camel dans les microservices
Advertisement 728x90

Orchestration décentralisée des processus avec RabbitMQ : Une alternative à Apache Camel

Un système de traitement de gros volumes de données provenant de fichiers FTP et de flux Kafka/RabbitMQ utilise une architecture microservices avec plus de 40 services. Auparavant, les chaînes de traitement étaient implémentées avec Apache Camel via un DSL Java avec des appels REST depuis un service central. Les problèmes incluaient la perte d'état lors des redémarrages, les limitations de mise à l'échelle dues aux flux parallèles et les risques pendant les déploiements.

Une nouvelle bibliothèque RabbitMQ avec des files d'attente de quorum permet une gestion décentralisée. L'état est conservé dans le broker, et les processus reprennent automatiquement. Le service d'initialisation se met à l'échelle horizontalement.

Entités principales de la bibliothèque

La bibliothèque inclut des classes et interfaces pour les étapes, les routes et les exécuteurs :

Google AdInline article slot
  • RouteStepInfo : Identifie une étape dans une 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 : Interface pour l'exécution asynchrone/synchrone/détachée.
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 : Rappel pour la fin d'exécution d'une étape.
public interface StepExecutionFinishedListener {
    void onStepExecutionFinished(RouteStepInfo routeStepInfo, Long objectId);
}
  • RouteStep : Étape avec modes 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 : Route sous forme de liste d'étapes avec index.
@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);
        }
    }
}

De plus : RoutesConfigBuilder pour la configuration, RouterConfigProvider pour les routes, ProcessRouter comme écouteur et exécuteur.

Modes d'exécution des étapes

La bibliothèque prend en charge trois modes :

  • ASYNC : Lancement séquentiel en arrière-plan, passage à l'étape suivante après achèvement.
  • SYNC : Appel bloquant, retour après toute la chaîne.
  • DETACHED : Lancement sans attente, avancement immédiat.

Les combinaisons permettent le branchement et le parallélisme :

Google AdInline article slot
  • Route 1 : Étapes SYNC 1→2→3.
  • Route 2 : Étapes ASYNC 1→2→3, retour immédiat.
  • Route 3 : ASYNC avec étape DETACHED 2.
  • Route 5 : Sous-route parallèle Route 4.

Implémentation et migration

Les tests de charge ont confirmé la fonctionnalité. La migration est progressive : remplacement des parties Camel avec basculement A/B. Les dépendances existantes sont conservées pour le retour en arrière.

Points clés :

  • L'état dans RabbitMQ garantit la reprise après redémarrage.
  • Mise à l'échelle horizontale de l'initialiseur.
  • Configuration transparente via le builder.
  • Prise en charge du branchement et du parallélisme sans service centralisé.

Cette approche convient aux systèmes nécessitant une haute fiabilité et évolutivité.

Google AdInline article slot

— Editorial Team

Advertisement 728x90

Lire ensuite