Skip to content

Laravel Reverb

소개

Laravel Reverb는 매우 빠르고 확장 가능한 실시간 WebSocket 통신을 Laravel 애플리케이션에 직접 제공하며, 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

허용된 오리진

클라이언트 요청이 시작될 수 있는 오리진을 정의하려면 config/reverb.php 설정 파일의 apps 섹션 내에 있는 allowed_origins 설정 값을 업데이트하면 됩니다. 허용된 오리진 목록에 없는 오리진에서 온 요청은 거부됩니다. *를 사용하여 모든 오리진을 허용할 수 있습니다.

'apps' => [
[
'id' => 'my-app-id',
'allowed_origins' => ['laravel.com'],
// ...
]
]

추가 애플리케이션

일반적으로 Reverb는 설치된 애플리케이션에 대한 WebSocket 서버를 제공합니다. 그러나 단일 Reverb 설치를 사용하여 둘 이상의 애플리케이션을 제공할 수 있습니다.

예를 들어, Reverb를 통해 여러 애플리케이션에 대한 WebSocket 연결을 제공하는 단일 Laravel 애플리케이션을 유지 관리할 수 있습니다. 이는 애플리케이션의 config/reverb.php 설정 파일에서 여러 apps를 정의하여 수행할 수 있습니다.

'apps' => [
[
'app_id' => 'my-app-one',
// ...
],
[
'app_id' => 'my-app-two',
// ...
],
],

SSL

대부분의 경우, 보안 WebSocket 연결은 요청이 Reverb 서버로 프록시되기 전에 업스트림 웹 서버(Nginx 등)에 의해 처리됩니다.

그러나 로컬 개발과 같이 Reverb 서버가 보안 연결을 직접 처리하는 것이 유용할 수 있습니다. Laravel Herd의 보안 사이트 기능을 사용하거나 Laravel Valet을 사용하고 애플리케이션에 대해 보안 명령어를 실행한 경우, 사이트용으로 생성된 Herd / Valet 인증서를 사용하여 Reverb 연결을 보호할 수 있습니다. 이렇게 하려면 REVERB_HOST 환경 변수를 사이트 호스트 이름으로 설정하거나 Reverb 서버를 시작할 때 호스트 이름 옵션을 명시적으로 전달합니다.

php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"

Herd 및 Valet 도메인은 localhost로 확인되므로 위 명령을 실행하면 wss://laravel.test:8080에서 보안 WebSocket 프로토콜(wss)을 통해 Reverb 서버에 액세스할 수 있습니다.

애플리케이션의 config/reverb.php 구성 파일에서 tls 옵션을 정의하여 수동으로 인증서를 선택할 수도 있습니다. tls 옵션 배열 내에서 PHP의 SSL 컨텍스트 옵션에서 지원하는 모든 옵션을 제공할 수 있습니다.

'options' => [
'tls' => [
'local_cert' => '/path/to/cert.pem'
],
],

서버 실행

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_HOSTREVERB_SERVER_PORT 환경 변수를 정의할 수도 있습니다.

REVERB_SERVER_HOSTREVERB_SERVER_PORT 환경 변수는 REVERB_HOSTREVERB_PORT와 혼동해서는 안 됩니다. 전자는 Reverb 서버 자체를 실행할 호스트와 포트를 지정하고, 후자는 Laravel이 브로드캐스트 메시지를 보낼 위치를 지정합니다. 예를 들어, 프로덕션 환경에서 포트 443의 공용 Reverb 호스트 이름에서 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

디버깅

성능 향상을 위해 Reverb는 기본적으로 디버그 정보를 출력하지 않습니다. Reverb 서버를 통과하는 데이터 스트림을 보려면 reverb:start 명령어에 --debug 옵션을 제공하면 됩니다.

php artisan reverb:start --debug

재시작

Reverb는 장기 실행 프로세스이므로 reverb:restart Artisan 명령어를 통해 서버를 재시작하지 않으면 코드 변경 사항이 반영되지 않습니다.

reverb:restart 명령어는 서버를 중지하기 전에 모든 연결이 정상적으로 종료되도록 합니다. Supervisor와 같은 프로세스 관리자를 사용하여 Reverb를 실행 중인 경우, 모든 연결이 종료된 후 프로세스 관리자에 의해 서버가 자동으로 재시작됩니다.

php artisan reverb:restart

모니터링

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>

프로덕션 환경에서 Reverb 실행하기

WebSocket 서버는 장시간 실행되는 특성으로 인해, Reverb 서버가 서버 리소스에 맞춰 최적의 연결 수를 효과적으로 처리할 수 있도록 서버 및 호스팅 환경을 최적화해야 할 수 있습니다.

lightbulb

사이트가 Laravel Forge로 관리되는 경우, "Application" 패널에서 직접 Reverb에 맞게 서버를 자동으로 최적화할 수 있습니다. Reverb 통합을 활성화하면 Forge는 필요한 확장 프로그램 설치 및 허용되는 연결 수 증가를 포함하여 서버가 프로덕션 준비를 완료하도록 보장합니다.

열린 파일

각 WebSocket 연결은 클라이언트 또는 서버가 연결을 끊을 때까지 메모리에 유지됩니다. Unix 및 Unix와 유사한 환경에서는 각 연결이 파일로 표시됩니다. 그러나 운영 체제 및 애플리케이션 수준 모두에서 허용되는 열린 파일 수에 제한이 있는 경우가 많습니다.

운영 체제

Unix 기반 운영 체제에서는 ulimit 명령을 사용하여 허용되는 열린 파일 수를 확인할 수 있습니다.

ulimit -n

이 명령은 다른 사용자에 대해 허용되는 열린 파일 제한을 표시합니다. /etc/security/limits.conf 파일을 편집하여 이러한 값을 업데이트할 수 있습니다. 예를 들어, forge 사용자의 최대 열린 파일 수를 10,000으로 업데이트하는 방법은 다음과 같습니다.

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

이벤트 루프

내부적으로 Reverb는 서버에서 WebSocket 연결을 관리하기 위해 ReactPHP 이벤트 루프를 사용합니다. 기본적으로 이 이벤트 루프는 추가 확장 프로그램이 필요 없는 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 웹 서버를 활용한다고 가정하면 다음 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;
}
 
...
}
exclamation

Reverb는 /app에서 WebSocket 연결을 수신하고 /apps에서 API 요청을 처리합니다. Reverb 요청을 처리하는 웹 서버가 이러한 두 URI를 모두 처리할 수 있는지 확인해야 합니다. 서버 관리에 Laravel Forge를 사용하고 있다면 Reverb 서버는 기본적으로 올바르게 구성됩니다.

일반적으로 웹 서버는 서버 과부하를 방지하기 위해 허용되는 연결 수를 제한하도록 구성됩니다. Nginx 웹 서버에서 허용되는 연결 수를 10,000개로 늘리려면 nginx.conf 파일의 worker_rlimit_nofileworker_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;
}

위 구성은 프로세스당 최대 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 구성 파일에서 허용되는 포트 범위를 업데이트하여 사용 가능한 개방 포트 수를 늘릴 수 있습니다.

프로세스 관리

대부분의 경우, Reverb 서버가 지속적으로 실행되도록 Supervisor와 같은 프로세스 관리자를 사용해야 합니다. Supervisor를 사용하여 Reverb를 실행하는 경우, Supervisor가 Reverb 서버에 대한 연결을 처리하는 데 필요한 파일을 열 수 있도록 서버의 supervisor.conf 파일의 minfds 설정을 업데이트해야 합니다.

[supervisord]
...
minfds=10000

확장

단일 서버가 허용하는 것보다 더 많은 연결을 처리해야 하는 경우 Reverb 서버를 수평으로 확장할 수 있습니다. Redis의 게시/구독 기능을 활용하여 Reverb는 여러 서버에서 연결을 관리할 수 있습니다. 애플리케이션의 Reverb 서버 중 하나에서 메시지를 받으면 서버는 Redis를 사용하여 들어오는 메시지를 다른 모든 서버에 게시합니다.

수평 확장을 활성화하려면 애플리케이션의 .env 구성 파일에서 REVERB_SCALING_ENABLED 환경 변수를 true로 설정해야 합니다.

REVERB_SCALING_ENABLED=true

다음으로, 모든 Reverb 서버가 통신할 수 있는 중앙 집중식 Redis 서버가 필요합니다. Reverb는 애플리케이션에 구성된 기본 Redis 연결을 사용하여 모든 Reverb 서버에 메시지를 게시합니다.

Reverb의 스케일링 옵션을 활성화하고 Redis 서버를 구성한 후에는 Redis 서버와 통신할 수 있는 여러 서버에서 reverb:start 명령을 호출하기만 하면 됩니다. 이러한 Reverb 서버는 서버 간에 들어오는 요청을 균등하게 분산하는 로드 밸런서 뒤에 배치해야 합니다.