Diese Dokumentation wurde automatisch von KI übersetzt.
In einer Einzelknoten-Umgebung können Plugins ihre Anforderungen normalerweise über In-Process-Zustände, Ereignisse oder Aufgaben erfüllen. Im Cluster-Modus kann dasselbe Plugin jedoch gleichzeitig auf mehreren Instanzen laufen, was zu folgenden typischen Problemen führt:
Der NocoBase-Kern stellt auf der Anwendungsebene verschiedene Middleware-Schnittstellen bereit, die Plugins dabei unterstützen, einheitliche Funktionen in einer Cluster-Umgebung wiederzuverwenden. In den folgenden Abschnitten erfahren Sie mehr über die Verwendung und Best Practices für Caching, synchrone Nachrichten, Nachrichtenwarteschlangen und verteilte Sperren, inklusive Referenzen zum Quellcode.
Für Daten, die im Arbeitsspeicher gespeichert werden müssen, empfehlen wir die Verwendung der systeminternen Cache-Komponente zur Verwaltung.
app.cache.Cache bietet grundlegende Operationen wie set/get/del/reset und unterstützt außerdem wrap und wrapWithCondition zur Kapselung der Cache-Logik sowie Batch-Methoden wie mset/mget/mdel.ttl (Time-to-Live) festzulegen, um den Verlust des Caches bei einem Neustart der Instanz zu verhindern.Beispiel: Cache-Initialisierung und -Verwendung im plugin-auth
Wenn der In-Memory-Zustand nicht mit einem verteilten Cache verwaltet werden kann (z. B. weil er nicht serialisierbar ist), muss eine Zustandsänderung, die durch Benutzeraktionen ausgelöst wird, über ein synchrones Signal an andere Instanzen gesendet werden, um die Zustandskonsistenz zu gewährleisten.
sendSyncMessage implementiert, welches intern app.syncMessageManager.publish aufruft und automatisch ein anwendungsweites Präfix zum Kanal hinzufügt, um Konflikte zu vermeiden.publish kann eine transaction angeben. Die Nachricht wird dann nach dem Commit der Datenbanktransaktion gesendet, wodurch die Synchronisierung von Zustand und Nachricht gewährleistet wird.handleSyncMessage, um Nachrichten von anderen Instanzen zu verarbeiten. Das Abonnieren während der beforeLoad-Phase eignet sich hervorragend für Szenarien wie Konfigurationsänderungen und Schema-Synchronisierung.Das Nachrichten-Broadcasting ist die zugrunde liegende Komponente synchroner Signale und kann auch direkt verwendet werden. Wenn Sie Nachrichten zwischen Instanzen senden müssen, können Sie diese Komponente nutzen.
app.pubSubManager.subscribe(channel, handler, { debounce }) kann verwendet werden, um einen Kanal über Instanzen hinweg zu abonnieren; die Option debounce dient dazu, häufige Rückrufe durch wiederholte Broadcasts zu verhindern.publish unterstützt skipSelf (Standard ist true) und onlySelf, um zu steuern, ob die Nachricht an die aktuelle Instanz zurückgesendet wird.Beispiel: plugin-async-task-manager verwendet PubSub, um Ereignisse zur Aufgabenabbruch zu senden
Die Nachrichtenwarteschlange wird zur Planung asynchroner Aufgaben verwendet und eignet sich für langwierige oder wiederholbare Operationen.
app.eventQueue.subscribe(channel, { idle, process, concurrency }). process gibt ein Promise zurück, und Sie können AbortSignal.timeout verwenden, um Timeouts zu steuern.publish fügt automatisch das Präfix des Anwendungsnamens hinzu und unterstützt Optionen wie timeout und maxRetries. Standardmäßig wird ein In-Memory-Warteschlangenadapter verwendet, der bei Bedarf auf erweiterte Adapter wie RabbitMQ umgestellt werden kann.Beispiel: plugin-async-task-manager verwendet EventQueue zur Aufgabenplanung
Wenn Sie Race Conditions vermeiden müssen, können Sie eine verteilte Sperre verwenden, um den Zugriff auf eine Ressource zu serialisieren.
local-Adapter bereitgestellt. Sie können verteilte Implementierungen wie Redis registrieren. Verwenden Sie app.lockManager.runExclusive(key, fn, ttl) oder acquire/tryAcquire, um die Parallelität zu steuern.ttl (Time-to-Live) dient als Schutzmechanismus, um die Sperre freizugeben und zu verhindern, dass sie in Ausnahmefällen dauerhaft gehalten wird.Beispiel: plugin-data-source-main verwendet eine verteilte Sperre, um den Feldlöschvorgang zu schützen
app.cache und app.syncMessageManager, um die Neuimplementierung von Cross-Node-Kommunikationslogik in Plugins zu vermeiden.transaction.afterCommit verwenden (dies ist in syncMessageManager.publish integriert), um die Konsistenz von Daten und Nachrichten zu gewährleisten.timeout, maxRetries und debounce fest, um neue Traffic-Spitzen in Ausnahmesituationen zu vermeiden.Mit diesen Funktionen können Plugins Zustände sicher teilen, Konfigurationen synchronisieren und Aufgaben über verschiedene Instanzen hinweg planen, wodurch die Anforderungen an Stabilität und Konsistenz in Cluster-Bereitstellungsszenarien erfüllt werden.