Centrifugo

Centrifugo — это выделенный сервер real-time-коммуникации, который принимает и удерживает длительные соединения с клиентами, управляет подписками на каналы и доставляет события подключённым пользователям.

WebSocket является его основным транспортом, но не единственным: Centrifugo также поддерживает SSE, HTTP-streaming, gRPC и WebTransport. Поэтому определение «WebSocket-сервер» верное, но немного сужает его роль. По сути это user-facing Pub/Sub-шлюз между backend-системой и клиентами.

Centrifugo и Centrifuge

Названия легко спутать:

  • Centrifugo — готовый отдельный сервер, который запускается как самостоятельный процесс или контейнер.
  • Centrifuge — Go-библиотека для построения real-time-серверов внутри собственного приложения. Она является ядром Centrifugo.

То есть:

Centrifuge = библиотека
Centrifugo = готовый сервер, построенный на Centrifuge

Как выглядит архитектура

┌──────────────┐
│ Browser/App  │
└──────┬───────┘
       │ WebSocket
       ▼
┌────────────────────┐
│     Centrifugo     │
│                    │
│ connections        │
│ subscriptions      │
│ channels           │
│ fan-out            │
│ presence           │
│ recovery/history   │
└─────────┬──────────┘
          │ HTTP/gRPC API
          ▼
┌────────────────────┐
│ Application Backend│
│                    │
│ business logic     │
│ authorization      │
│ database           │
│ transactions       │
└────────────────────┘

Клиент обычно не держит WebSocket непосредственно с каждым бизнес-сервисом. Он подключается к Centrifugo и подписывается на каналы:

user:42
booking:9182
hotel:775:availability
order:123:status
notifications:user:42

Backend после изменения состояния публикует событие через HTTP- или gRPC API Centrifugo:

POST /api/publish

channel: booking:9182
data:
  status: confirmed
  bookingId: 9182

Centrifugo находит все соединения, подписанные на booking:9182, и раздаёт сообщение клиентам. Его серверный API позволяет публиковать сообщения, отключать пользователей, получать presence и работать с историей каналов.

Что именно Centrifugo снимает с backend

Без Centrifugo приложению пришлось бы самостоятельно реализовать:

  1. Хранение десятков или сотен тысяч открытых соединений.
  2. Ping/pong и обнаружение оборванных соединений.
  3. Переподключение клиентов.
  4. Повторную подписку после reconnect.
  5. Маршрутизацию сообщений по каналам.
  6. Fan-out одного события на множество клиентов.
  7. Аутентификацию соединений.
  8. Авторизацию подписок.
  9. Presence: кто сейчас подключён.
  10. Временную историю сообщений и восстановление пропущенных публикаций.
  11. Координацию нескольких экземпляров WebSocket-сервера.
  12. Метрики и наблюдаемость real-time-слоя.

Centrifugo предоставляет каналы, подписки, JWT-авторизацию, presence, history, recovery, proxy-вызовы к backend и клиентские SDK.

Что Centrifugo не должен делать

Centrifugo не становится главным backend-приложением. Обычно туда не помещают:

  • бизнес-логику;
  • расчёт стоимости;
  • бронирование номера;
  • проведение платежа;
  • изменение остатка;
  • проверку бизнес-инвариантов;
  • долговременное хранение бизнес-состояния;
  • распределённые транзакции.

Например, Centrifugo может сообщить:

{
  "bookingId": 9182,
  "status": "confirmed"
}

Но решение о том, можно ли подтвердить бронирование, принимает Booking Service, а не Centrifugo.

Критически важный порядок действий

Нельзя сначала отправить событие пользователю, а потом пытаться сохранить изменение в базе:

publish "booking confirmed"
        ↓
database transaction fails

Иначе пользователь увидит подтверждённую бронь, которой в реальности нет.

Надёжнее:

1. Backend изменяет состояние в БД.
2. Транзакция фиксируется.
3. Событие попадает в outbox.
4. Outbox-процессор публикует событие в Centrifugo.
5. Centrifugo доставляет обновление клиентам.

То есть Centrifugo отвечает за оперативную доставку представления об изменении, но источником истины остаётся база данных бизнес-сервиса.

Centrifugo не равен Kafka

У них разные направления доставки:

Kafka:
service → service
долговременный журнал событий
повторное чтение
consumer groups
обработка бизнес-событий

Centrifugo:
server → online client
длительные клиентские соединения
подписки на пользовательские каналы
мгновенное обновление интерфейса

Они могут работать вместе:

Booking Service
      │
      ▼
    Kafka
      │
      ▼
Notification / Realtime Consumer
      │
      ▼
  Centrifugo
      │
      ▼
 Browser / Mobile App

Итоговая формулировка

Centrifugo — это выделенный масштабируемый сервер real-time-сообщений, который управляет клиентскими соединениями, подписками и доставкой событий через WebSocket и другие streaming-транспорты. Backend сохраняет бизнес-состояние и публикует события, а Centrifugo маршрутизирует их подключённым пользователям.

А Centrifuge — это Go-библиотека, на которой можно построить собственный аналогичный real-time-слой.

Прокрутить вверх