Разделение сервисов v1.9.0+
Кластер NocoBaseEnterprise Edition+
Введение
Обычно все сервисы приложения NocoBase работают в одном экземпляре Node.js. По мере роста бизнеса функциональность усложняется, и некоторые ресурсоемкие задачи могут снижать общую производительность.
Чтобы повысить производительность, NocoBase поддерживает разделение сервисов приложения между разными узлами в режиме кластера. Это позволяет избежать ситуации, когда проблемы производительности одного сервиса влияют на способность всего приложения отвечать на пользовательские запросы.
Дополнительно это позволяет точечно масштабировать конкретные сервисы по горизонтали, улучшая утилизацию ресурсов кластера.
При развертывании NocoBase в кластере разные сервисы можно разделять и запускать на разных узлах. Ниже показана схема разделения:

Какие сервисы можно разделять
Асинхронные рабочие процессы
Ключ сервиса: workflow:process
Рабочие процессы в асинхронном режиме после триггера ставятся в очередь выполнения. Их можно рассматривать как фоновые задачи, результат которых пользователю обычно не нужно ждать синхронно. Особенно для сложных и длительных процессов с большим числом триггеров рекомендуется выносить их на отдельные узлы.
Другие пользовательские асинхронные задачи
Ключ сервиса: async-task:process
Сюда относятся задачи, создаваемые пользовательскими действиями, например асинхронный импорт и экспорт. При больших объёмах данных или высокой конкурентности рекомендуется выносить их на отдельные узлы.
Как разделять сервисы
Разделение разных сервисов по узлам достигается настройкой переменной окружения WORKER_MODE. Её можно задавать по следующим правилам:
WORKER_MODE=<empty>: если не задано или пусто, режим worker такой же, как в текущем single-instance режиме: принимает все запросы и обрабатывает все задачи. Совместимо с приложениями без прежней настройки.WORKER_MODE=!: worker обрабатывает только запросы и не обрабатывает задачи.WORKER_MODE=workflow:process,async-task:process: при указании одного или нескольких идентификаторов сервисов (через запятую) worker обрабатывает только эти задачи и не обрабатывает запросы.WORKER_MODE=*: worker обрабатывает все фоновые задачи вне зависимости от модуля, но не обрабатывает запросы.WORKER_MODE=!,workflow:process: worker обрабатывает запросы и одновременно задачи указанного идентификатора.WORKER_MODE=-: worker не обрабатывает ни з апросы, ни задачи (этот режим обязателен внутри worker-процесса).
Например, в среде K8S узлы с одинаковой функцией разделения можно настраивать одинаковыми значениями переменных окружения, что упрощает горизонтальное масштабирование конкретного типа сервиса.
Примеры конфигурации
Несколько узлов с раздельной обработкой
Предположим, есть три узла: node1, node2, node3. Возможная конфигурация:
node1: обрабатывает только пользовательские UI-запросы,WORKER_MODE=!.node2: обрабатывает только workflow-задачи,WORKER_MODE=workflow:process.node3: обрабатывает только асинхронные задачи,WORKER_MODE=async-task:process.
Несколько узлов со смешанной обработкой
Предположим, есть четыре узла: node1, node2, node3, node4. Возможная конфигурация:
node1иnode2: обрабатывают обычные запросы,WORKER_MODE=!, а балансировщик автоматически распределяет запросы между ними.node3иnode4: обрабатывают все остальные фоновые задачи,WORKER_MODE=*.
Справка для разработчиков
При разработке бизнес-плагинов можно выносить ресурсоёмкие сервисы в зависимости от требований сценария:
- Определите новый идентификатор сервиса, например
my-plugin:process, для конфигурации через переменные окружения и задокументируйте его. - В серверной бизнес-логике плагина используйте интерфейс
app.serving(), чтобы проверить окружение и понять, должен ли текущий узел предоставлять конкретный сервис с учётом переменной окружения.

