Laravel Reverb
Вступ
Laravel Reverb забезпечує надзвичайно швидке та масштабоване реального часу спілкування через WebSocket безпосередньо у вашому Laravel-застосунку, і забезпечує безшовну інтеграцію з існуючим набором інструментів трансляції подій Laravel.
Встановлення
Ви можете встановити Reverb за допомогою команди Artisan install:broadcasting:
php artisan install:broadcasting
Конфігурація
За лаштунками, команда Artisan install:broadcasting виконає команду reverb:install, яка встановить Reverb з розумним набором параметрів конфігурації за замовчуванням. Якщо ви хочете внести будь-які зміни в конфігурацію, ви можете зробити це, оновивши змінні середовища Reverb або оновивши файл конфігурації config/reverb.php.
Облікові дані застосунку
Для встановлення з'єднання з Reverb, набір облікових даних Reverb "застосунку" повинен бути обміняний між клієнтом і сервером. Ці облікові дані налаштовуються на сервері і використовуються для перевірки запиту від клієнта. Ви можете визначити ці облікові дані, використовуючи наступні змінні середовища:
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret
Дозволені джерела
Ви також можете визначити джерела, з яких можуть надходити клієнтські запити, оновивши значення конфігурації allowed_origins у секції apps конфігураційного файлу config/reverb.php. Будь-які запити з джерела, не зазначеного у ваших дозволених джерелах, будуть відхилені. Ви можете дозволити всі джерела, використовуючи *:
'apps' => [
[
'app_id' => 'my-app-id',
'allowed_origins' => ['laravel.com'],
// ...
]
]
Додаткові застосунки
Зазвичай, Reverb надає сервер WebSocket для застосунку, в якому він встановлений. Однак, можливо обслуговувати більше ніж один застосунок, використовуючи одну установку Reverb.
Наприклад, ви можете бажати підтримувати один Laravel застосунок, який через Reverb забезпечує підключення WebSocket для декількох застосунків. Це можна досягти, визначивши декілька apps у файлі конфігурації вашого застосунку config/reverb.php:
'apps' => [
[
'app_id' => 'my-app-one',
// ...
],
[
'app_id' => 'my-app-two',
// ...
],
],
SSL
У більшості випадків безпечні з'єднання WebSocket обробляються вищестоящим веб-сервером (Nginx тощо) перед тим, як запит буде проксійовано на ваш сервер Reverb.
Однак, іноді може бути корисним, наприклад, під час локальної розробки, щоб сервер Reverb безпосередньо обробляв безпечні з'єднання. Якщо ви використовуєте функцію безпечного сайту Laravel Herd або використовуєте Laravel Valet і виконали команду secure для вашого застосунку, ви можете використовувати сертифікат Herd / Valet, згенерований для вашого сайту, щоб захистити ваші з'єднання Reverb. Для цього встановіть змінну середовища REVERB_HOST на ім'я хоста вашого сайту або явно передайте опцію імені хоста під час запуску сервера Reverb:
php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"
Оскільки домени Herd і Valet вирішуються в localhost, виконання наведеної вище команди призведе до того, що ваш сервер Reverb буде доступний через безпечний протокол WebSocket (wss) за адресою wss://laravel.test:8080.
Ви також можете вручну вибрати сертифікат, визначивши параметри tls у файлі конфігурації config/reverb.php вашого застосунку. У межах масиву параметрів tls ви можете надати будь-які з параметрів, які підтримуються опціями SSL-контексту PHP:
'options' => [
'tls' => [
'local_cert' => '/path/to/cert.pem'
],
],
Запуск сервера
Сервер Reverb можна запустити за допомогою команди Artisan reverb:start:
php artisan reverb:start
За замовчуванням сервер Reverb буде запущено на 0.0.0.0:8080, що робить його доступним з усіх мережевих інтерфейсів.
Якщо вам потрібно вказати користувацький хост або порт, ви можете зробити це за допомогою параметрів --host та --port при запуску сервера:
php artisan reverb:start --host=127.0.0.1 --port=9000
Альтернативно, ви можете визначити змінні середовища REVERB_SERVER_HOST та REVERB_SERVER_PORT у конфігураційному файлі .env вашого застосунку.
Змінні середовища REVERB_SERVER_HOST та REVERB_SERVER_PORT не слід плутати з REVERB_HOST та REVERB_PORT. Перші вказують хост і порт, на яких працює сам сервер Reverb, тоді як друга пара вказує Laravel, куди надсилати повідомлення трансляції. Наприклад, у виробничому середовищі ви можете направляти запити з вашого публічного хосту Reverb на порту 443 до сервера Reverb, що працює на 0.0.0.0:8080. У цьому випадку ваші змінні середовища будуть визначені наступним чином:
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080
REVERB_HOST=ws.laravel.com
REVERB_PORT=443
Налагодження
Щоб покращити продуктивність, Reverb за замовчуванням не виводить жодної налагоджувальної інформації. Якщо ви хочете побачити потік даних, що проходить через ваш сервер Reverb, ви можете надати опцію --debug до команди reverb:start:
php artisan reverb:start --debug
Перезапуск
Оскільки Reverb є довготривалим процесом, зміни у вашому коді не будуть відображені без перезапуску сервера за допомогою команди Artisan reverb:restart.
Команда reverb:restart забезпечує коректне завершення всіх з'єднань перед зупинкою сервера. Якщо ви запускаєте Reverb з менеджером процесів, таким як Supervisor, сервер буде автоматично перезапущено менеджером процесів після завершення всіх з'єднань:
php artisan reverb:restart
Моніторинг
Реверберацію можна контролювати через інтеграцію з Laravel Pulse. Увімкнувши інтеграцію Pulse для Reverb, ви можете відстежувати кількість з'єднань і повідомлень, які обробляються вашим сервером.
Щоб увімкнути інтеграцію, спочатку переконайтеся, що ви встановили Pulse. Потім додайте будь-які з реєстраторів Reverb до файлу конфігурації вашого застосунку config/pulse.php:
use Laravel\Reverb\Pulse\Recorders\ReverbConnections;
use Laravel\Reverb\Pulse\Recorders\ReverbMessages;
'recorders' => [
ReverbConnections::class => [
'sample_rate' => 1,
],
ReverbMessages::class => [
'sample_rate' => 1,
],
// ...
],
Далі додайте картки Pulse для кожного рекордера на вашу панель Pulse:
<x-pulse>
<livewire:reverb.connections cols="full" />
<livewire:reverb.messages cols="full" />
...
</x-pulse>
Активність з'єднання записується шляхом періодичного опитування нових оновлень. Щоб забезпечити правильне відображення цієї інформації на панелі інструментів Pulse, ви повинні запустити демон pulse:check на вашому сервері Reverb. Якщо ви запускаєте Reverb у горизонтально масштабованій конфігурації, ви повинні запускати цей демон лише на одному з ваших серверів.
Запуск Reverb у виробництві
Через тривалу роботу серверів WebSocket, можливо, вам потрібно буде зробити деякі оптимізації вашого сервера та середовища хостингу, щоб забезпечити ефективну обробку сервером Reverb оптимальної кількості з'єднань для ресурсів, доступних на вашому сервері.
Якщо ваш сайт керується за допомогою Laravel Forge, ви можете автоматично оптимізувати ваш сервер для Reverb безпосередньо з панелі "Застосунок". Увімкнувши інтеграцію Reverb, Forge забезпечить готовність вашого сервера до продуктивного використання, включаючи встановлення всіх необхідних розширень та збільшення дозволеної кількості з'єднань.
Відкрити файли
Кожне з'єднання WebSocket утримується в пам'яті до тих пір, поки клієнт або сервер не відключиться. У Unix та Unix-подібних середовищах кожне з'єднання представляється файлом. Однак часто існують обмеження на кількість дозволених відкритих файлів як на рівні операційної системи, так і на рівні застосунку.
Операційна система
На операційній системі на базі Unix ви можете визначити дозволену кількість відкритих файлів за допомогою команди ulimit:
ulimit -n
Ця команда відобразить обмеження на відкриті файли, дозволені для різних користувачів. Ви можете оновити ці значення, відредагувавши файл /etc/security/limits.conf. Наприклад, оновлення максимальної кількості відкритих файлів до 10,000 для користувача forge виглядатиме наступним чином:
# /etc/security/limits.conf
forge soft nofile 10000
forge hard nofile 10000
Цикл подій
Під капотом Reverb використовує цикл подій ReactPHP для управління WebSocket-з'єднаннями на сервері. За замовчуванням цей цикл подій працює на stream_select, який не вимагає жодних додаткових розширень. Однак, stream_select зазвичай обмежений 1,024 відкритими файлами. Таким чином, якщо ви плануєте обробляти більше ніж 1,000 одночасних з'єднань, вам потрібно буде використовувати альтернативний цикл подій, не обмежений такими ж обмеженнями.
Reverb автоматично переключиться на цикл з підтримкою ext-uv, коли він доступний. Це розширення PHP доступне для встановлення через PECL:
pecl install uv
Веб-сервер
У більшості випадків Reverb працює на порту сервера, який не має веб-доступу. Тому, щоб направити трафік до Reverb, слід налаштувати зворотний проксі. Припускаючи, що Reverb працює на хості 0.0.0.0 і порту 8080, і ваш сервер використовує веб-сервер Nginx, зворотний проксі можна визначити для вашого сервера Reverb, використовуючи наступну конфігурацію сайту Nginx:
server {
...
location / {
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header SERVER_PORT $server_port;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://0.0.0.0:8080;
}
...
}
Reverb прослуховує підключення WebSocket на /app і обробляє API-запити на /apps. Ви повинні переконатися, що веб-сервер, який обробляє запити Reverb, може обслуговувати обидва ці URI. Якщо ви використовуєте Laravel Forge для керування вашими серверами, ваш сервер Reverb буде налаштований правильно за замовчуванням.
Зазвичай веб-сервери налаштовані на обмеження кількості дозволених з'єднань, щоб запобігти перевантаженню сервера. Щоб збільшити кількість дозволених з'єднань на веб-сервері Nginx до 10,000, значення worker_rlimit_nofile та worker_connections у файлі nginx.conf слід оновити:
user forge;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
worker_rlimit_nofile 10000;
events {
worker_connections 10000;
multi_accept on;
}
Конфігурація вище дозволить створювати до 10,000 обробників Nginx на процес. Крім того, ця конфігурація встановлює ліміт відкритих файлів Nginx на 10,000.
Порти
Операційні системи на базі Unix зазвичай обмежують кількість портів, які можуть бути відкриті на сервері. Ви можете переглянути поточний дозволений діапазон за допомогою наступної команди:
cat /proc/sys/net/ipv4/ip_local_port_range
# 32768 60999
Вихід вище показує, що сервер може обробляти максимум 28,231 (60,999 - 32,768) з'єднань, оскільки кожне з'єднання вимагає вільного порту. Хоча ми рекомендуємо горизонтальне масштабування для збільшення кількості дозволених з'єднань, ви можете збільшити кількість доступних відкритих портів, оновивши дозволений діапазон портів у конфігураційному файлі вашого сервера /etc/sysctl.conf.
Управління процесами
У більшості випадків слід використовувати менеджер процесів, такий як Supervisor, щоб забезпечити безперервну роботу сервера Reverb. Якщо ви використовуєте Supervisor для запуску Reverb, вам слід оновити налаштування minfds у файлі supervisor.conf вашого сервера, щоб гарантувати, що Supervisor може відкрити файли, необхідні для обробки з'єднань з вашим сервером Reverb:
[supervisord]
...
minfds=10000
Масштабування
Якщо вам потрібно обробляти більше з'єднань, ніж дозволяє один сервер, ви можете масштабувати ваш сервер Reverb горизонтально. Використовуючи можливості публікації / підписки Redis, Reverb здатний керувати з'єднаннями на декількох серверах. Коли один з серверів Reverb вашого застосунку отримує повідомлення, сервер використовує Redis для публікації вхідного повідомлення на всі інші сервери.
Щоб увімкнути горизонтальне масштабування, ви повинні встановити змінну середовища REVERB_SCALING_ENABLED на true у конфігураційному файлі .env вашого застосунку:
REVERB_SCALING_ENABLED=true
Далі, ви повинні мати виділений, центральний сервер Redis, з яким будуть спілкуватися всі сервери Reverb. Reverb використовуватиме з'єднання Redis за замовчуванням, налаштоване для вашого застосунку, щоб публікувати повідомлення на всі ваші сервери Reverb.
Після того як ви увімкнули опцію масштабування Reverb і налаштували сервер Redis, ви можете просто викликати команду reverb:start на декількох серверах, які можуть спілкуватися з вашим сервером Redis. Ці сервери Reverb повинні бути розміщені за балансувальником навантаження, який рівномірно розподіляє вхідні запити між серверами.
