Эта документация была автоматически переведена ИИ.
В одноузловой среде плагины обычно могут выполнять свои задачи, используя внутрипроцессное состояние, события или задачи. Однако в кластерном режиме один и тот же плагин может одновременно работать на нескольких экземплярах, сталкиваясь со следующими типичными проблемами:
Ядро NocoBase предоставляет на уровне приложения различные интерфейсы промежуточного ПО, которые помогают плагинам использовать унифицированные возможности в кластерной среде. Ниже мы рассмотрим использование и лучшие практики для кэширования, синхронных сообщений, очередей сообщений и распределенных блокировок, с примерами из исходного кода.
Для данных, которые необходимо хранить в памяти, рекомендуется использовать встроенный компонент кэширования системы.
app.cache.Cache предоставляет базовые операции, такие как set/get/del/reset, а также поддерживает wrap и wrapWithCondition для инкапсуляции логики кэширования, и пакетные методы, такие как mset/mget/mdel.ttl, чтобы предотвратить потерю кэша при перезапуске экземпляра.Пример: Инициализация и использование кэша в plugin-auth
Если состояние в памяти не может быть управляемо с помощью распределенного кэша (например, его невозможно сериализовать), то при изменении состояния в результате действий пользователя необходимо уведомить об этих изменениях другие экземпляры с помощью синхронного сигнала для поддержания согласованности состояния.
sendSyncMessage, который внутренне вызывает app.syncMessageManager.publish и автоматически добавляет префикс уровня приложения к каналу, чтобы избежать конфликтов каналов.publish может указывать transaction, и сообщение будет отправлено после фиксации транзакции базы данных, что гарантирует синхронизацию состояния и сообщения.handleSyncMessage. Подписка на сообщения на этапе beforeLoad очень подходит для сценариев, таких как изменение конфигурации и синхронизация схемы.Широковещательная рассылка сообщений является базовым компонентом синхронных сигналов и также может использоваться напрямую. Когда вам нужно транслировать сообщения между экземплярами, вы можете реализовать это с помощью данного компонента.
app.pubSubManager.subscribe(channel, handler, { debounce }) позволяет подписываться на канал между экземплярами; опция debounce используется для устранения дребезга, предотвращая частые обратные вызовы, вызванные повторной трансляцией.publish поддерживает skipSelf (по умолчанию true) и onlySelf для управления тем, будет ли сообщение отправлено обратно текущему экземпляру.Пример: plugin-async-task-manager использует PubSub для трансляции событий отмены задач
Очередь сообщений используется для планирования асинхронных задач и подходит для обработки длительных или повторяемых операций.
app.eventQueue.subscribe(channel, { idle, process, concurrency }). Метод process возвращает Promise, и вы можете использовать AbortSignal.timeout для контроля времени ожидания.publish автоматически добавляет префикс имени приложения и поддерживает такие опции, как timeout и maxRetries. По умолчанию он использует адаптер очереди в памяти, но при необходимости может быть переключен на расширенные адаптеры, такие как RabbitMQ.Пример: plugin-async-task-manager использует EventQueue для планирования задач
Когда необходимо избежать состояний гонки, вы можете использовать распределенную блокировку для сериализации доступа к ресурсу.
local на основе процессов. Вы можете зарегистрировать распределенные реализации, такие как Redis; управляйте параллелизмом с помощью app.lockManager.runExclusive(key, fn, ttl) или acquire/tryAcquire.ttl используется для гарантированного снятия блокировки, предотвращая ее постоянное удержание в исключительных ситуациях.Пример: plugin-data-source-main использует распределенную блокировку для защиты процесса удаления полей
app.cache, app.syncMessageManager и другие, чтобы избежать повторной реализации логики межузлового взаимодействия в плагинах.transaction.afterCommit (встроенный в syncMessageManager.publish) для обеспечения согласованности данных и сообщений.timeout, maxRetries и debounce, чтобы предотвратить новые пики трафика в исключительных ситуациях.Благодаря этим возможностям плагины могут безопасно обмениваться состоянием, синхронизировать конфигурации и планировать задачи между различными экземплярами, отвечая требованиям стабильности и согласованности в сценариях кластерного развертывания.