Предварительная подготовка

Кластер NocoBaseEnterprise Edition+

Перед развёртыванием кластерного приложения необходимо выполнить следующие подготовительные шаги.

Лицензии коммерческих плагинов

Запуск приложения NocoBase в режиме кластера требует поддержки следующих плагинов:

НазначениеПлагин
Адаптер кэшаВстроенный
Адаптер сигнала синхронизации@nocobase/plugin-pubsub-adapter-redis
Адаптер очереди сообщений@nocobase/plugin-queue-adapter-redis или @nocobase/plugin-queue-adapter-rabbitmq
Адаптер распределённой блокировки@nocobase/plugin-lock-adapter-redis
Распределитель идентификаторов воркеров@nocobase/plugin-workerid-allocator-redis

Сначала убедитесь, что в Вашу лицензию входят перечисленные плагины.

Системные компоненты

Остальные системные компоненты, помимо самого экземпляра приложения, можно выбирать исходя из эксплуатационных требований команды.

База данных

Поскольку текущий режим кластера пока ориентирован только на экземпляры приложения, база данных временно поддерживается только в одноузловом варианте. Если у вас архитектура master-slave, её нужно реализовать самостоятельно через middleware и обеспечить прозрачность для приложения NocoBase.

Если вам требуется warm standby или аварийное восстановление между зонами доступности или регионами, стратегия синхронизации и переключения базы данных должна быть спроектирована и реализована вашей командой эксплуатации.

Промежуточный слой (Middleware)

Режим кластера NocoBase опирается на middleware-компоненты для межкластерной связи и координации, включая:

  • Кэш: распределённый кэш на базе Redis для ускорения доступа к данным.
  • Сигналы синхронизацииl: передача сигналов синхронизации между узлами через Redis stream.
  • Очередь сообщений: асинхронная обработка сообщений через очереди на базе Redis или RabbitMQ.
  • Распределённая блокировка: распределённые блокировки на базе Redis для безопасного доступа к общим ресурсам в кластере.

Когда все middleware-компоненты используют Redis, можно запустить один Redis-сервис во внутренней сети кластера (или Kubernetes). Либо можно выделить отдельный Redis для каждой функции (кэш, сигналы синхронизации, очереди и блокировки)).

Рекомендуемые версии

  • Redis: >=8.0 или redis-stack с поддержкой Bloom Filter.
  • RabbitMQ: >=4.0

Общее хранилище

NocoBase использует директорию storage для хранения системных файлов. В многоузловом режиме следует монтировать cloud disk (или NFS), чтобы обеспечить общий доступ нескольких узлов. Иначе локальное хранилище не синхронизируется автоматически и не будет работать корректно.

При развёртывании в Kubernetes см. Развёртывание в Kubernetes: Общее хранилище.

Что обычно хранится в каталоге storage

Содержимое каталога storage зависит от включенных плагинов и способа развертывания. Согласно текущей реализации, типичное содержимое включает:

ПутьНазначениеРекомендация по использованию
storage/uploadsЗагруженные файлы при использовании локального режима храненияВ производственных кластерах следует в первую очередь использовать объектное хранилище, такое как S3 / OSS / COS
storage/pluginsЛокальные пакеты плагинов, устанавливаемые, загружаемые или обнаруживаемые во время выполненияЕсли вы зависите от локальных плагинов, этот каталог должен быть общим; если плагины уже встроены в образ, эту зависимость можно уменьшить
storage/apps/<app>/jwt_secret.datСекрет токена по умолчанию, автоматически создаваемый, когда APP_KEY явно не заданНе полагайтесь на этот файл в production; явно задайте APP_KEY
storage/apps/<app>/aes_key.datКлюч AES по умолчанию, автоматически создаваемый, когда APP_AES_SECRET_KEY явно не заданНе полагайтесь на этот файл в production; явно задайте APP_AES_SECRET_KEY
storage/environment-variables/<app>/aes_key.datФайл ключа AES для сценариев с плагином переменных окруженияРекомендуется использовать файл ключа, смонтированный только для чтения
storage/logsКаталог логов по умолчанию и некоторые журналы миграцииВ дальнейшем рекомендуется интеграция с внешней платформой логирования
storage/tmpВременные файлы для импорта, экспорта, миграции и т. д.Может быть временным, но если требуется повторное использование между узлами, его нужно сделать общим, либо выполнять операцию только на одном управляющем узле
storage/backups, storage/duplicator, storage/migration-managerАртефакты, связанные с резервным копированием, восстановлением и миграциейИх следует рассматривать как эксплуатационные каталоги, хранить постоянно и не изменять одновременно с нескольких узлов

Приведенная выше таблица не является исчерпывающей, но она показывает важный момент: в storage одновременно находятся бизнес-файлы, файлы ключей, каталоги плагинов, логи и временные артефакты, связанные с эксплуатацией. Поэтому при кластерном развертывании базовым подходом обычно является совместное использование и постоянное хранение всего каталога /app/nocobase/storage.

Рекомендации по хранению

Согласованность кластера в NocoBase в основном обеспечивается базой данных, Redis, очередями сообщений и распределенными блокировками, а не использованием общей файловой системы в качестве средства координации при высокой конкуренции.

Поэтому рекомендуется:

  • Для высокочастотных бизнес-файлов, таких как вложения, отдавать приоритет объектному хранилищу. Долговременная зависимость от локального хранилища в production-кластерах не рекомендуется.
  • Использовать общее хранилище в первую очередь для размещения каталога storage, а не как высокопроизводительный файловый сервис.
  • Такие операции, как установка и обновление плагинов, резервное копирование, восстановление и миграция, выполнять только после сокращения кластера до одного узла; после завершения кластер можно снова масштабировать.

Балансировка нагрузки

Режим кластера требует балансировщика нагрузки для распределения запросов, для проверки состояния и обеспечения отказоустойчивости экземпляров приложения. Конкретный вариант выбирается и настраивается по требованиям команды эксплуатации.

Пример конфигурации для собственного Nginx:

upstream myapp {
    server 172.31.0.1:13000; # Внутренний узел 1
    server 172.31.0.2:13000; # Внутренний узел 2
    server 172.31.0.3:13000; # Внутренний узел 3
}

server {
    listen 80;

    location / {
        # Использование определенного выше upstream для балансировки нагрузки
        proxy_pass http://myapp;
        # ... остальные настройки
    }
}

Это означает, что запросы будут реверс-проксироваться и распределяться на разные серверные узлы для обработки.

Для балансировщиков других облачных провайдеров см. документацию конкретного провайдера.

Для развертываний с высокой доступностью рекомендуется:

  • Запускать как минимум 2 экземпляра приложения в рамках одного кластера и поручать балансировщику нагрузки обработку отказов отдельных экземпляров.
  • Проверка работоспособности балансировщика нагрузки должна отражать фактическую доступность приложения, а не только факт открытия порта.
  • Если вам требуется warm standby между зонами доступности или регионами, обычно следует развернуть несколько независимых кластеров, а команда эксплуатации должна отвечать за синхронизацию и переключение базы данных, общего хранилища и другой инфраструктуры.

Конфигурация переменных окружения

Все узлы кластера должны использовать одинаковую конфигурацию переменных окружения. Помимо базовых переменных окружения NocoBase нужно также настроить переменные middleware-компонентов ниже.

Ключевые секреты

Помимо переменных окружения промежуточного ПО, все узлы кластера также должны явно настроить одинаковые ключевые секреты:

APP_KEY=
APP_AES_SECRET_KEY=
# Или использовать файл ключа, смонтированный только для чтения
# APP_AES_SECRET_KEY_PATH=
  • APP_KEY используется для подписи token / JWT. Если он явно не задан, приложение использует резервный файл секрета по умолчанию в каталоге storage.
  • APP_AES_SECRET_KEY используется для расшифровки чувствительных полей в базе данных. Если он явно не задан, приложение также использует резервный файл секрета по умолчанию в каталоге storage.
  • В эфемерных контейнерах или многоузловых развертываниях зависимость от автоматически созданных локальных файлов ключей может привести к тому, что после перезапуска токены станут недействительными, а исторические зашифрованные данные больше нельзя будет расшифровать.
Tip

APP_AES_SECRET_KEY должен быть 32-байтным ключом AES-256, представленным 64 шестнадцатеричными символами.

В облачных средах рекомендуется централизованно управлять этими значениями через такие сервисы, как Secrets Manager, SSM Parameter Store, Kubernetes Secret или файл ключа, смонтированный только для чтения.

Многоядерный режим

Когда приложение запускается на многоядерном узле, можно включить многоядерный режим:

# Включить многоядерный режим PM2
# CLUSTER_MODE=max # По умолчанию отключено, требует ручной настройки

Если вы разворачиваете Pods приложения в Kubernetes, эту настройку можно игнорировать и контролировать количество экземпляров через число реплик pod.

Кэш

# Адаптер кэша, в cluster mode должен быть redis (если не задано, используется in-memory)
CACHE_DEFAULT_STORE=redis

# URL подключения Redis-адаптера кэша, обязателен к заполнению
CACHE_REDIS_URL=

Сигнал синхронизации

# URL подключения Redis sync-адаптера, по умолчанию redis://localhost:6379/0
PUBSUB_ADAPTER_REDIS_URL=

Распределённая блокировка

# Адаптер блокировок, в cluster mode должен быть redis (если не задано, используется in-memory local lock)
LOCK_ADAPTER_DEFAULT=redis

# URL подключения Redis lock-адаптера, по умолчанию redis://localhost:6379/0
LOCK_ADAPTER_REDIS_URL=

Очередь сообщений

# Включить Redis как адаптер очереди сообщений, иначе используется in-memory
QUEUE_ADAPTER=redis
# URL подключения Redis-адаптера очереди, по умолчанию redis://localhost:6379/0
QUEUE_ADAPTER_REDIS_URL=

Распределитель идентификаторов воркеров

Некоторые системные коллекции в NocoBase используют глобально уникальные ID как первичные ключи. Чтобы избежать конфликтов PK в кластере, каждый экземпляр приложения должен получать уникальный Worker ID через Worker ID Allocator. Текущий диапазон Worker ID — 0–31, то есть каждое приложение может одновременно запускать до 32 узлов. Подробнее о дизайне глобально уникального ID: @nocobase/snowflake-id.

# URL подключения Redis для Worker ID Allocator. Если не задано, будет назначен случайный Worker ID.
REDIS_URL=
Tip

Обычно все адаптеры могут использовать один и тот же экземпляр Redis, но лучше использовать разные базы, чтобы избежать потенциальных конфликтов ключей, например:

CACHE_REDIS_URL=redis://localhost:6379/0
PUBSUB_ADAPTER_REDIS_URL=redis://localhost:6379/1
LOCK_ADAPTER_REDIS_URL=redis://localhost:6379/2
QUEUE_ADAPTER_REDIS_URL=redis://localhost:6379/3
REDIS_URL=redis://localhost:6379/4

Сейчас каждый плагин использует собственные Redis-переменные окружения. В будущем REDIS_URL может стать fallback-конфигурацией.

Если вы используете Kubernetes для управления кластером, перечисленные переменные можно задать через ConfigMap или Secret. См. Kubernetes Deployment.

После завершения подготовительных шагов переходите к Процедурам обслуживания для дальнейшего управления экземплярами приложения.