Spring Scheduler / Asynchrone Verarbeitung und Load-Balancing/Skalierung

LimDul

Top Contributor
Was für Pattern gibt es eigentlich für asynchrone Verarbeitung, wenn die Anwendung gleichzeitg in mehreren Instanzen läuft (Load-Balancing/Skalierung)? Hier im Kontext Spring-Boot

Oft man hat ja Bedarf in Enterprise Anwendungen Dinge nachgelagert / im Hintergrund auszuführen. Dafür kann man natürlich einen Batch schreiben und einplanen. Aber alternativ ist eine Scheduled Bean oft auch sinnvoll. Da gibt es nur das Problem, dass so eine Anwendung oft ja alleine aus Load-Balancing Gründen in mehreren Instanzen läuft. Standardmäßig ist die Scheduled Bean dann auf allen Instanzen aktiv und habe ich die gleichen Herausforderungen wie bei Multithreading und muss sicherstellen, das Dinge nur 1x abgearbeitet werden.

Das hört sich für mich jetzt nicht nach einem exotischen Problem an - gibt es da nicht was von Ratiopharm aka - Standard-Patterns? Klar, ich kann mit Locks auf der DB arbeiten oder versuchen sicherzustellen, dass die Abarbeitung idempotent ist so dass eine doppelte Abarbeitung keine Probleme macht - aber so richtig toll sind die beiden Varianten nicht.
 

KonradN

Super-Moderator
Mitarbeiter
Also ich denke, es gibt da diverse Dinge, die interessant sein könnten, aber ich bin da kein Experte sondern bringe nur Dinge, über die ich in der Vergangenheit schon einmal gestolpert bin (Ohne es irgendwie tiefer analysiert / betrachtet zu haben)

Leader Election
Eine Herangehensweise könnte allgemein das "Leader Election" sein. Du hast also mehrere Instanzen und davon ist dann der Leader (ohne feste Konfiguration). Der kann dann Aufgaben verteilen bzw. hat die Aufgabe, dies zu konfigurieren.
Im Spring Umfeld wären da dann zu nennen:
  • Spring Cloud Zookeeper (Nutzt dann Apache Zookeeper)
  • Spring Cloud Kubernetes um die Funktionalität von Kubernetes zur Leader Election diesbezüglich zu nutzen.

Distributed Locking
Eine andere Möglichkeit, die ich hier sehen würde, wäre ein Distributed Locking. Das wäre dann mittels Redis oder auch wieder Zookeeper denkbar. (Spring Integration für Redis mit RedissonClient::getLock müsste das z.B sein) Die Idee geht unter dem Strich einen ähnlichen Weg.

Message Queue
Du wirst da vermutlich selbst schon an Message Queues gedacht haben. Das ist etwas, das mir direkt einfällt, wenn ich "nachgelagert" oder so höre. Also eigentlich eine etwas unabhängige Aufgabe und es ist die Aufteilung in zwei Parts denkbar. Halt einer, der die Message in die Queue steckt und ein anderer Teil, der dies abarbeitet... Aber meine Intuitiven Gedanken müssen hier natürlich nicht zutreffend sein, da einfach nur etwas angetriggert wurde.

Externer Scheduler
Quarz als externer Scheduler mit "Clustered Scheduling"? Ich habe es noch nie selbst eingesetzt, daher kann ich nur aufzeigen, was Google mir so an womöglich interessanten Links herausgesucht hat:

Database Polling
Dann hast Du natürlich auch die schon von Dir genannte Möglichkeit des Database Polling. Also einfach selbst etwas Logik schreiben. Clients holen sich einfach aus der Datenbank einen Job und tragen sich transaktionsgesichert ein. Ggf. wird ein Task, der nicht beendet wird, nach einer gewissen Zeit von einem anderen Worker ebenfalls abgearbeitet ...

Das wären so ein paar Dinge, die mir so durch den Kopf gehen. Die Frage ist immer, wie viel man wirklich braucht. Sowas kann sonst mal schnell ganz schön aufgebläht werden mit vielen tollen Features, die man aber vermutlich nicht wirklich braucht (Aber das kann ich nicht wissen).

Aber evtl. waren da paar Ideen dabei, die für Dich interessant waren und es hilft, mal ein paar Dinge im Web näher anzusehen. Wirklich Experte bin ich bei den Themen meist nicht, bei meinen Anforderungen reichte dann bisher unkompliziert das Database Polling und wir haben die anderen Dinge nicht tiefer ausprobiert / umgesetzt.
 

httpdigest

Top Contributor
Je nachdem, wie dein Deploymentszenario genau aussieht, kannst du natürlich auch einfach einen externen Scheduling-/Cron-mechanismus verwenden, der nicht in die Laufzeitumgebung bzw. Framework deines Services eingebaut ist. Wenn du z.B. Kubernetes verwendest, kannst du auch dessen Scheduling per CronJob nutzen.
Oder aber du stellst eine Instanz deines Services explizit ab nur für solche asynchrone Jobabarbeitung und deaktivierst das in allen anderen horizontal skalierenden Instanzen.
 

LimDul

Top Contributor
Vermutlich läuft es größtenteils auf Message Queues raus - selbst wenn ggf. das System, dass sie abarbeitet das gleiche ist, was es auslöst.

Danke für den Input
 


Schreibe deine Antwort... und nutze den </> Button, wenn du Code posten möchtest...
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben