Ten dokument został przetłumaczony przez AI. W przypadku niedokładności, proszę odnieść się do wersji angielskiej
W środowisku jednowęzłowym wtyczki zazwyczaj radzą sobie z wymaganiami, wykorzystując stan w procesie, zdarzenia lub zadania. Jednakże w trybie klastrowym ta sama wtyczka może działać jednocześnie na wielu instancjach, co wiąże się z następującymi typowymi problemami:
Rdzeń NocoBase udostępnia na poziomie aplikacji różnorodne interfejsy oprogramowania pośredniczącego (middleware), które pomagają wtyczkom w wykorzystaniu ujednoliconych możliwości w środowisku klastrowym. W poniższych sekcjach przedstawimy zastosowanie i najlepsze praktyki dotyczące buforowania, wiadomości synchronicznych, kolejek wiadomości oraz blokad rozproszonych, wraz z odniesieniami do kodu źródłowego.
W przypadku danych, które muszą być przechowywane w pamięci, zaleca się użycie wbudowanego komponentu buforowania systemu do zarządzania nimi.
app.cache.Cache udostępnia podstawowe operacje, takie jak set/get/del/reset, a także obsługuje metody wrap i wrapWithCondition do hermetyzacji logiki buforowania, oraz metody wsadowe, takie jak mset/mget/mdel.ttl, aby zapobiec utracie danych z pamięci podręcznej po ponownym uruchomieniu instancji.Przykład: Inicjalizacja i użycie pamięci podręcznej w plugin-auth
Jeśli stan przechowywany w pamięci nie może być zarządzany za pomocą rozproszonej pamięci podręcznej (np. nie może być serializowany), wówczas, gdy stan zmienia się w wyniku działań użytkownika, zmiana musi zostać rozgłoszona do innych instancji za pośrednictwem sygnału synchronizacji, aby zachować spójność stanu.
sendSyncMessage, która wewnętrznie wywołuje app.syncMessageManager.publish i automatycznie dodaje prefiks na poziomie aplikacji do kanału, aby uniknąć konfliktów.publish może określać transaction, a wiadomość zostanie wysłana po zatwierdzeniu transakcji bazy danych, zapewniając synchronizację stanu i wiadomości.handleSyncMessage do przetwarzania wiadomości z innych instancji. Subskrybowanie podczas fazy beforeLoad jest bardzo odpowiednie dla scenariuszy, takich jak zmiany konfiguracji i synchronizacja schematu.Rozgłaszanie wiadomości jest podstawowym komponentem sygnałów synchronicznych i może być również używane bezpośrednio. Gdy zachodzi potrzeba rozgłaszania wiadomości między instancjami, można użyć tego komponentu.
app.pubSubManager.subscribe(channel, handler, { debounce }) może być używana do subskrybowania kanału między instancjami; opcja debounce służy do zapobiegania częstym wywołaniom zwrotnym spowodowanym powtarzającymi się rozgłoszeniami.publish obsługuje opcje skipSelf (domyślnie true) i onlySelf, aby kontrolować, czy wiadomość jest wysyłana z powrotem do bieżącej instancji.Przykład: plugin-async-task-manager używa PubSub do rozgłaszania zdarzeń anulowania zadań
Kolejka wiadomości służy do planowania zadań asynchronicznych i jest odpowiednia do obsługi długotrwałych lub możliwych do ponowienia operacji.
app.eventQueue.subscribe(channel, { idle, process, concurrency }). Metoda process zwraca Promise, a do kontrolowania limitów czasu można użyć AbortSignal.timeout.publish automatycznie dodaje prefiks nazwy aplikacji i obsługuje opcje, takie jak timeout i maxRetries. Domyślnie używa adaptera kolejki w pamięci, ale w razie potrzeby można przełączyć się na rozszerzone adaptery, takie jak RabbitMQ.Przykład: plugin-async-task-manager używa EventQueue do planowania zadań
Gdy zachodzi potrzeba uniknięcia warunków wyścigu, można użyć blokady rozproszonej do serializacji dostępu do zasobu.
local oparty na procesach. Mogą Państwo zarejestrować rozproszone implementacje, takie jak Redis. Proszę użyć app.lockManager.runExclusive(key, fn, ttl) lub acquire/tryAcquire do kontrolowania współbieżności.ttl służy jako zabezpieczenie do zwolnienia blokady, zapobiegając jej wiecznemu utrzymywaniu w wyjątkowych przypadkach.Przykład: plugin-data-source-main używa blokady rozproszonej do ochrony procesu usuwania pól
app.cache i app.syncMessageManager, aby uniknąć ponownego implementowania logiki komunikacji międzywęzłowej we wtyczkach.transaction.afterCommit (co jest wbudowane w syncMessageManager.publish), aby zapewnić spójność danych i wiadomości.timeout, maxRetries i debounce, aby zapobiec nowym szczytom ruchu w wyjątkowych sytuacjach.Dzięki tym możliwościom wtyczki mogą bezpiecznie współdzielić stan, synchronizować konfiguracje i planować zadania między różnymi instancjami, spełniając wymagania stabilności i spójności w scenariuszach wdrożeń klastrowych.