Reverb
Laravel Reverb
介绍
Laravel Reverb 为你的 Laravel 应用带来了快速的、可扩展的实时 WebSocket 通信,并提供与 Laravel 现有事件广播工具套件的无缝集成。
安装
你可以使用 install:broadcasting
Artisan 命令安装 Reverb:
php artisan install:broadcasting
配置
在底层,install:broadcasting
Artisan 命令会运行 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)
你也可以通过更新 config/reverb.php
配置文件中 apps
部分的 allowed_origins
配置值来定义客户端请求可以来源的域。任何不在允许来源列表中的请求都会被拒绝。你可以使用 *
来允许所有来源:
'apps' => [
[
'app_id' => 'my-app-id',
'allowed_origins' => ['laravel.com'],
// ...
]
]
额外应用(Additional Applications)
通常情况下,Reverb 会为安装它的应用提供一个 WebSocket 服务器。然而,也可以使用单个 Reverb 安装为多个应用提供服务。
例如,你可能希望维护一个单一的 Laravel 应用,通过 Reverb 为多个应用提供 WebSocket 连接。这可以通过在应用的 config/reverb.php
配置文件中定义多个 apps
来实现:
'apps' => [
[
'app_id' => 'my-app-one',
// ...
],
[
'app_id' => 'my-app-two',
// ...
],
],
SSL
在大多数情况下,安全的 WebSocket 连接由上游 Web 服务器(如 Nginx)处理,然后再将请求代理到你的 Reverb 服务器。
但是,有时在本地开发期间,让 Reverb 服务器直接处理安全连接会很有用。如果你使用 Laravel Herd 的安全站点功能,或者使用 Laravel Valet 并对你的应用运行了 secure 命令,你可以使用为你的网站生成的 Herd / Valet 证书来保护 Reverb 连接。为此,将 REVERB_HOST
环境变量设置为你站点的主机名,或者在启动 Reverb 服务器时显式传递 hostname
选项:
php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"
由于 Herd 和 Valet 域名解析到 localhost
,运行上述命令将使你的 Reverb 服务器可以通过安全 WebSocket 协议(wss
)访问,地址为 wss://laravel.test:8080
。
你也可以通过在应用的 config/reverb.php
配置文件中定义 tls
选项手动选择证书。在 tls
选项数组中,你可以提供 PHP SSL 上下文选项 支持的任何选项:
'options' => [
'tls' => [
'local_cert' => '/path/to/cert.pem'
],
],
启动服务器(Running the Server)
Reverb 服务器可以通过 reverb:start
Artisan 命令启动:
php artisan reverb:start
默认情况下,Reverb 服务器会启动在 0.0.0.0:8080
,使其可从所有网络接口访问。
如果需要指定自定义主机或端口,可以在启动服务器时通过 --host
和 --port
选项实现:
php artisan reverb:start --host=127.0.0.1 --port=9000
或者,你也可以在应用的 .env
配置文件中定义 REVERB_SERVER_HOST
和 REVERB_SERVER_PORT
环境变量。
需要注意的是,REVERB_SERVER_HOST
和 REVERB_SERVER_PORT
环境变量不要与 REVERB_HOST
和 REVERB_PORT
混淆。前者指定 Reverb 服务器自身运行的主机和端口,而后者用于告诉 Laravel 向哪里发送广播消息。例如,在生产环境中,你可以将公共 Reverb 主机名的 443 端口请求路由到运行在 0.0.0.0:8080
的 Reverb 服务器。在这种情况下,你的环境变量可以这样定义:
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080
REVERB_HOST=ws.laravel.com
REVERB_PORT=443
调试(Debugging)
为了提升性能,Reverb 默认不会输出任何调试信息。如果你希望查看通过 Reverb 服务器传输的数据流,可以在运行 reverb:start
命令时添加 --debug
选项:
php artisan reverb:start --debug
重启(Restarting)
由于 Reverb 是一个长时间运行的进程,对代码的修改在不重启服务器的情况下不会生效。你需要通过 reverb:restart
Artisan 命令来重启服务器。
reverb:restart
命令会在停止服务器之前,确保所有连接被优雅地终止。如果你使用 Supervisor 等进程管理器运行 Reverb,所有连接终止后,进程管理器会自动重启服务器:
php artisan reverb:restart
监控(Monitoring)
Reverb 可以通过与 Laravel Pulse 的集成进行监控。启用 Reverb 的 Pulse 集成后,你可以跟踪服务器处理的连接数和消息数量。
要启用该集成,首先需要确保你已经 安装 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 仪表盘上正确显示,你必须在 Reverb 服务器上运行 pulse:check
守护进程。如果你在 水平扩展 配置中运行 Reverb,该守护进程只需要在其中一台服务器上运行即可。
在生产环境中运行 Reverb(Running Reverb in Production)
由于 WebSocket 服务器是长时间运行的,你可能需要对服务器和托管环境进行一些优化,以确保你的 Reverb 服务器能够根据服务器可用资源有效处理最佳数量的连接。
[!注意]
如果你的网站由 Laravel Forge 管理,你可以直接在“应用程序”面板中自动优化服务器以支持 Reverb。启用 Reverb 集成后,Forge 会确保服务器具备生产环境准备条件,包括安装所需扩展以及增加允许的连接数量。
打开的文件(Open Files)
每个 WebSocket 连接会保存在内存中,直到客户端或服务器断开连接。在 Unix 和类 Unix 系统中,每个连接都对应一个文件。然而,操作系统和应用程序级别通常对允许打开的文件数量有限制。
操作系统(Operating System)
在基于 Unix 的操作系统中,你可以使用 ulimit
命令查看允许打开的文件数量:
ulimit -n
此命令会显示不同用户允许的打开文件限制。你可以通过编辑 /etc/security/limits.conf
文件来更新这些值。例如,将 forge
用户的最大打开文件数更新为 10,000,可以这样设置:
# /etc/security/limits.conf
forge soft nofile 10000
forge hard nofile 10000
事件循环(Event Loop)
在底层,Reverb 使用 ReactPHP 事件循环来管理服务器上的 WebSocket 连接。默认情况下,该事件循环由 stream_select
提供支持,它不需要额外的扩展。然而,stream_select
通常限制在 1,024 个打开文件。因此,如果你计划处理超过 1,000 个并发连接,你需要使用不受同样限制的替代事件循环。
Reverb 在可用时会自动切换到由 ext-uv
提供支持的事件循环。这个 PHP 扩展可以通过 PECL 安装:
pecl install uv
Web 服务器(Web Server)
在大多数情况下,Reverb 在服务器上运行于非面向 Web 的端口。因此,为了将流量路由到 Reverb,你应配置反向代理。假设 Reverb 运行在主机 0.0.0.0
和端口 8080
上,并且你的服务器使用 Nginx Web 服务器,可以通过以下 Nginx 站点配置为 Reverb 服务器定义反向代理:
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 在/app
监听 WebSocket 连接,并在/apps
处理 API 请求。你应确保处理 Reverb 请求的 Web 服务器可以提供这两个 URI。如果你使用 Laravel Forge 管理服务器,Reverb 服务器默认会被正确配置。
通常,Web 服务器会限制允许的连接数量,以防止服务器过载。要将 Nginx Web 服务器允许的连接数增加到 10,000,需要更新 nginx.conf
文件中的 worker_rlimit_nofile
和 worker_connections
值:
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;
}
上述配置将允许每个 Nginx 进程生成最多 10,000 个工作进程。此外,该配置将 Nginx 的打开文件限制设置为 10,000。
端口(Ports)
基于 Unix 的操作系统通常会限制服务器上可打开的端口数量。你可以通过以下命令查看当前允许的端口范围:
cat /proc/sys/net/ipv4/ip_local_port_range
# 32768 60999
上面的输出显示服务器最多可以处理 28,231(60,999 - 32,768)个连接,因为每个连接都需要一个可用端口。虽然我们推荐使用水平扩展来增加允许的连接数,你也可以通过更新服务器 /etc/sysctl.conf
配置文件中的允许端口范围来增加可用的开放端口数量。
进程管理(Process Management)
在大多数情况下,你应使用进程管理器(如 Supervisor)来确保 Reverb 服务器持续运行。如果你使用 Supervisor 来运行 Reverb,应更新服务器 supervisor.conf
文件中的 minfds
设置,以确保 Supervisor 能够打开处理 Reverb 服务器连接所需的文件:
[supervisord]
...
minfds=10000
扩展(Scaling)
如果你需要处理的连接数量超过单台服务器允许的数量,可以通过水平扩展 Reverb 服务器来实现。利用 Redis 的发布/订阅功能,Reverb 能够在多台服务器间管理连接。当你的应用某台 Reverb 服务器接收到消息时,该服务器将使用 Redis 将收到的消息发布给其他所有服务器。
要启用水平扩展,你应在应用的 .env
配置文件中将 REVERB_SCALING_ENABLED
环境变量设置为 true
:
REVERB_SCALING_ENABLED=true
接下来,你需要一台专用的中央 Redis 服务器,所有 Reverb 服务器将与其通信。Reverb 会使用为你的应用配置的默认 Redis 连接将消息发布到所有 Reverb 服务器。
一旦启用了 Reverb 的扩展选项并配置了 Redis 服务器,你只需在能够与 Redis 服务器通信的多台服务器上执行 reverb:start
命令。这些 Reverb 服务器应放置在负载均衡器后面,以便将传入请求均匀分配到各个服务器。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: