Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як масштабувати Reverb на тисячі з'єднань і кілька серверів?

WebSocket-з'єднання довгоживучі: кожна відкрита вкладка - постійне з'єднання, яке тримає пам'ять і файловий дескриптор. Обмеження зазвичай не в процесорі, а в лімітах ОС, вебсервера й циклу подій.

1. Ліміт відкритих файлів. У Unix кожне з'єднання - файл. Типовий ліміт ulimit -n - 1024:

# /etc/security/limits.conf
forge  soft  nofile  10000
forge  hard  nofile  10000

Під Supervisor - minfds=10000 у supervisord.conf, бо процес успадковує ліміти від менеджера процесів.

2. Цикл подій. Reverb працює на ReactPHP, і за замовчуванням використовує stream_select, обмежений приблизно 1024 файлами. Для понад тисячі з'єднань потрібне розширення ext-uv (pecl install uv) - Reverb підхопить його автоматично.

3. Вебсервер перед Reverb. Nginx проксіює WebSocket із заголовками Upgrade і Connection "Upgrade", і має власні ліміти:

worker_rlimit_nofile 10000;
events {
    worker_connections 10000;
}

4. Горизонтальне масштабування. Один процес Reverb однопотоковий. Коли одного сервера замало:

REVERB_SCALING_ENABLED=true
  • усі сервери Reverb підключаються до спільного Redis і обмінюються повідомленнями через pub/sub: подія, отримана одним сервером, доставляється клієнтам на всіх;
  • сервери стоять за балансувальником, що підтримує WebSocket;
  • Redis для масштабування - центральна залежність: його відмова розриває обмін між серверами.

5. Деплой і перезапуск. reverb:restart коректно закриває з'єднання, і клієнти Echo перепідключаються. Але тисячі одночасних перепідключень - стрибок навантаження на Reverb і на ендпойнт авторизації каналів /broadcasting/auth (кожне приватне з'єднання - запит до застосунку). Варто перезапускати сервери по черзі.

6. Моніторинг. Reverb інтегрується з Pulse: картки з кількістю з'єднань і повідомлень. Слідкуйте за пам'яттю процесу й pulse:check на серверах Reverb.

7. Що навантажує систему крім самих з'єднань:

  • трансляція йде через чергу - при масових подіях пропускна здатність черги стає вузьким місцем;
  • розмір повідомлень - транслюйте ідентифікатори й мінімум полів, а не моделі з усіма зв'язками;
  • частота - події, що генеруються сотні разів на секунду, варто об'єднувати чи дебаунсити.

Альтернатива власному масштабуванню - керований сервіс (Pusher, Ably, Laravel Cloud) з тим самим протоколом: код застосунку не змінюється.

Докладніше в документації: Reverb: масштабування

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання