Laravel Reverb
Введение
Laravel Reverb обеспечивает невероятно быструю и масштабируемую связь через WebSocket в реальном времени непосредственно в вашем приложении Laravel и обеспечивает плавную интеграцию с существующим набором инструментов трансляции событий Laravel.
Установка
Для Laravel Reverb требуется PHP 8.2+ и Laravel 10.47+.
Вы можете использовать менеджер пакетов Composer для установки Reverb в ваш проект Laravel:
composer require laravel/reverb
После установки пакета вы можете запустить команду установки Reverb, чтобы опубликовать конфигурацию, добавить необходимые переменные среды и включить трансляцию событий в вашем приложении:
php artisan reverb:install
Конфигурирование
Команда 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' => [
[
'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] (https://www.php.net/manual/en/context.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
Запуск 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
обычно ограничен 1024 открытыми файлами. Таким образом, если вы планируете обрабатывать более 1000 одновременных подключений, вам нужно будет использовать альтернативный цикл событий, не связанный теми же ограничениями.
Reverb автоматически переключится на цикл ext-event
, ext-ev
или ext-uv
, если он доступен. Все эти расширения PHP доступны для установки через PECL:
pecl install event
# or
pecl install ev
# or
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;
}
...
}
Обычно веб-серверы настроены на ограничение количества разрешенных подключений, чтобы предотвратить перегрузку сервера. Чтобы увеличить количество разрешенных подключений на веб-сервере 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;
}
Приведенная выше конфигурация позволит создавать до 10000 рабочих Nginx на каждый процесс. Кроме того, эта конфигурация устанавливает ограничение количества открытых файлов Nginx равным 10000.
Порты
Операционные системы на базе Unix обычно ограничивают количество портов, которые можно открыть на сервере. Вы можете увидеть текущий разрешенный диапазон с помощью следующей команды:
cat /proc/sys/net/ipv4/ip_local_port_range
# 32768 60999
Вывод выше показывает, что сервер может обрабатывать максимум 28231 (60999–32768) соединений, поскольку для каждого соединения требуется свободный порт. Хотя мы рекомендуем горизонтальное масштабирование для увеличения количества разрешенных подключений, вы можете увеличить количество доступных открытых портов, обновив диапазон разрешенных портов в файле конфигурации вашего сервера /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 должны быть размещены за балансировщиком нагрузки, который равномерно распределяет входящие запросы между серверами.