Перейти к содержимому
RU
О продукте5 мин на чтение

Архитектура

Как веб-приложение, медиасервисы и хранилище взаимодействуют друг с другом при развертывании MeetSpace.

На этой странице
Веб-, десктопные и Android-клиенты HTTPS · WebSocket · WebRTC
Веб-шлюз Фронтенд и обратный прокси-сервер
Go API Аккаунты, чаты и доступ к встречам
Медиа SFU + TURN Аудио, видео и демонстрация экрана
PostgreSQL Данные приложения
Redis Присутствие и координация
RabbitMQ Команды управления записью
Хранилище S3 Записи и вложения
Рабочие процессы записи и дополнительные интеграции работают параллельно с основными сервисами. Медиатрафик и трафик приложений используют отдельные пути.

Модель развертывания

Представленное развертывание выполняется на одном хосте Linux с использованием Docker Compose. Процессы приложения представляют собой отдельные контейнеры с частными сетевыми подключениями к общей инфраструктуре. Публичный обратный прокси-сервер завершает HTTPS-соединение и перенаправляет запросы браузера на фронтенд, API и авторизованные загрузки записей.

Веб-фронтенд написан на React и TypeScript, скомпилирован с помощью Vite и обслуживается Nginx. Бэкенд-сервисы написаны на Go. API использует фреймворк Gin, а для передачи медиа в реальном времени - Pion WebRTC. Рабочий файл Compose является эталоном для компоновки сервисов; в конфигурациях для разработки используются дополнительные локальные порты.

text
Веб-клиенты и клиенты приложений
  ├─ HTTPS / WSS → Обратный прокси-сервер → Фронтенд и API
  │                                  ├─ PostgreSQL
  │                                  ├─ Redis
  │                                  ├─ RabbitMQ → Сервис записи
  │                                  └─ Частное объектное хранилище
  └─ WebRTC ─────→ Медиа-воркер SFU
       └─ TURN-ретранслятор при необходимости

SFU → Сервис записи → Объектное хранилище
SFU → Обработчик речи → Настроенный речевой сервис
Фоновый обработчик продукта ↔ PostgreSQL → Настроенные интеграции

Сервисы приложения

Медиафайлы в реальном времени не проходят через обычный обработчик запросов API. FFmpeg запускается в модуле записи, отдельно от SFU. Фоновая обработка имеет собственные очереди и ограничения, чтобы в случае сбоя дополнительного провайдера совещание не было намеренно остановлено.

  • frontend: обслуживает приложение и общедоступные страницы, а также проксирует запросы к API с тем же источником.
  • api: аутентифицирует пользователей, проверяет права доступа, управляет встречами и сообщениями, обслуживает конечные точки REST и соединения в реальном времени, а также планирует работу.
  • media-worker: сервис выборочной передачи медиапотоков (SFU). Получает потоки участников и передаёт дорожки другим участникам. Правила допуска и использования устройств задаются управляющими сервисами.
  • worker: сервис записи. Он получает команды на запись, захватывает медиафайлы, запускает композитинг и FFmpeg, а также публикует файлы с записями и превью.
  • product-worker: выполняет сохраняемые в базе фоновые задания - напоминания, интеграции с почтой и календарём, расшифровку, подготовку итогов и индексирование.
  • live-worker: обрабатывает включенное в реальном времени распознавание речи и наблюдения за ходом совещаний для создания субтитров и аналитики.
  • migrate: одноразовая задача по миграции базы данных, а не постоянно работающий сервис.

Хранилище и очереди

  • В PostgreSQL хранятся учетные записи, права доступа, данные о совещаниях, история переписки, метаданные записей, уведомления, фоновые задания и результаты включенной обработки.
  • В объектном хранилище, совместимом с S3, хранятся личные записи, превью, архивы треков и вложения. В классической схеме используется MinIO, а в защищенном установщике - SeaweedFS под совместимым именем сервиса minio. У них разные форматы хранения на диске, поэтому при смене провайдера требуется плановая миграция данных.
  • Для захвата и промежуточной записи файлов перед окончательной публикацией используется постоянный буфер.
  • Redis хранит временное состояние присутствия, блокировки с ограниченным сроком действия, билеты подключения, ограничения частоты запросов и уведомления в реальном времени. Источником истории переписки остаётся PostgreSQL.
  • RabbitMQ доставляет команды управления записью с подтверждениями. Сохраняемая исходящая очередь (outbox) связывает изменения базы данных с публикацией команд.
  • Фоновые операции продукта используют сохраняемые задания PostgreSQL с ограниченными повторными попытками и блокировками на время выполнения. Они не зависят от очереди записи RabbitMQ.

Как работает встреча

  1. Клиент входит в систему или подтверждает получение приглашения на совещание. API проверяет учетную запись, статус совещания и возможность доступа.
  2. Клиент устанавливает авторизованное соединение в режиме реального времени и обменивается сигналами мультимедиа с сервером. Участники, ожидающие своей очереди, не публикуют медиафайлы в рамках совещания.
  3. WebRTC подключает клиента к SFU. Coturn обеспечивает ретрансляцию, когда прямое медиасоединение установить невозможно.
  4. SFU пересылает медиапотоки. Сообщения в чате и элементы управления совещаниями используют API приложения и события в реальном времени, а не встраиваются в видеопоток.
  5. При запросе на запись API сохраняет запрос и запускает процесс. Модуль записи фиксирует, обрабатывает и загружает артефакты, а затем помечает результат как готовый.
  6. Если эта функция включена, отдельные фоновые модули создают расшифровки, краткие обзоры, субтитры или аналитические данные, не участвуя в основном процессе пересылки медиапотоков.

Обмен сообщениями и повторное подключение

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

Сервер сохраняет сообщение в PostgreSQL, а затем публикует обновление через Redis и WebSocket-соединения. Уведомления сообщают клиентам о необходимости обновить страницу. Они не являются надежным архивом сообщений. После повторного подключения клиенты снова считывают достоверные данные, поэтому потерянное событие не приводит к удалению сохраненной истории.

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

Границы данных и доступа

В общедоступном развертывании используется протокол HTTPS для веб-трафика и защищенные транспорты WebRTC для передачи медиаданных. Пароли хранятся в виде хешей Argon2id с солью. Для длительных сеансов работы с учетными записями используются защищенные файлы cookie, а авторизация на сервере применяется для каждого защищенного ресурса.

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

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

Эксплуатация, производительность и доступность

Сервисы предоставляют внутренние конечные точки для проверки работоспособности, готовности и версии. В классических развертываниях можно включить профиль наблюдаемости с помощью Prometheus и Grafana. Текущая защищенная версия установщика включает Prometheus и не включает Grafana. Метрики и административные конечные точки должны находиться в контролируемых сетях; стандартный общедоступный прокси-сервер блокирует внутренние операционные маршруты.

Стандартный стек включает в себя один хост, базу данных, брокер, объектное хранилище и SFU. Он не обеспечивает автоматическую высокую доступность или динамическую миграцию активного собрания. Замена медиа-воркера может привести к прерыванию звонков и необходимости повторного подключения клиентов.

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