Многопоточность в Metarhia

Impress — первый Node.js application server с менеджером тредов из коробки. Балансер + сетевые треды + worker pool настраиваются в конфиге.

Проблема

В голом Node.js worker_threads надо настраивать руками: pool, лимиты, балансировка, таймауты. Это редко делают правильно.

Решение Impress

В конфиге server описываешь:

  • Балансер (если есть поле balancer, аллоцируется отдельный тред)
  • N сетевых тредов (HTTP/HTTPS)
  • M worker-тредов (бизнес-логика)
  • Таймауты ожидания свободного воркера и выполнения задачи
server: {
  balancer: { port: 8000 },
  protocol: 'https',
  ports: [8001, 8002, 8003],     // 3 сетевых треда
  workers: {
    pool: 2,                      // 2 воркера для бизнес-логики
    wait: 3000,                   // макс ожидание свободного воркера
    timeout: 5000,                // макс время выполнения задачи
  },
}

Классификация тредов

Тред Назначение
balancer Принимает соединения, раздаёт по сетевым тредам
net (N штук) Принимают HTTP/WS-запросы
workers (M штук) Бизнес-логика, CPU-интенсив
main Координация, scheduler

Итого: 1 + N + M + 1 тредов.

Эксклюзивный захват

Можно сказать «возьми этот метод и держи воркер только под него». Полезно для долгих CPU-задач, которые не должны конкурировать с другими.

Что делает таймаут

  • wait — если воркер свободен — нет смысла убивать.
  • timeout — задача висит, скорее всего deadlock. Воркер уничтожается, клиенту возвращается ошибка.

Scheduler на тредах

Встроенный планировщик: scheduler.add({ every: 10000 }, task) — каждые 10 секунд выполнить задачу в одном из тредов.

Вызов между тредами

application.invoke(method, args)  // вызов в другом треде

API одинаковый, не важно, исполняется ли метод в main или в worker.

🎓 Источники

См. также