Laravel Horizon
- Introduction
- Installation
- Balancing Strategies
- Upgrading Horizon
- Running Horizon
- Tags
- Notifications
- Metrics
- Deleting Failed Jobs
- Clearing Jobs From Queues
Introduction
Laravel Horizon을 살펴보기 전에 먼저 Laravel의 기본 queue services에 익숙해져야 합니다. Horizon은 Laravel의 큐에 추가 기능을 제공하므로, Laravel이 제공하는 기본 큐 기능을 아직 잘 모른다면 혼란스러울 수 있습니다.
Laravel Horizon은 Laravel 기반 Redis queues를 위한 아름다운 대시보드와 코드 기반 설정을 제공합니다. Horizon을 사용하면 잡 처리량, 실행 시간, 잡 실패와 같은 큐 시스템의 주요 메트릭을 손쉽게 모니터링할 수 있습니다.
Horizon을 사용하면 모든 큐 워커 설정이 하나의 단순한 설정 파일에 저장됩니다. 애플리케이션의 워커 구성을 버전 관리되는 파일에 정의함으로써, 배포 시 손쉽게 큐 워커의 스케일 조정이나 설정 변경이 가능합니다.
Installation
Laravel Horizon을 사용하려면 큐를 구동하는 데 Redis를 사용해야 합니다. 따라서 애플리케이션의
config/queue.php설정 파일에서 큐 연결이redis로 설정되어 있는지 확인해야 합니다. 현재 Horizon은 Redis Cluster와 호환되지 않습니다.
Composer 패키지 매니저를 사용하여 Horizon을 프로젝트에 설치할 수 있습니다.
composer require laravel/horizon
설치 후에는 horizon:install Artisan 명령어로 Horizon의 에셋을 퍼블리시합니다.
php artisan horizon:install
Configuration
에셋을 퍼블리시한 후, Horizon의 주요 설정 파일은 config/horizon.php에 생성됩니다. 이 파일에서는 애플리케이션의 큐 워커 옵션을 세부적으로 설정할 수 있습니다. 각 설정에는 목적에 대한 설명이 달려 있으니, 이 파일을 꼼꼼히 살펴보는 것이 좋습니다.
Horizon은 내부적으로
horizon이라는 이름의 Redis 연결을 사용합니다. 이 Redis 연결 이름은 예약되어 있으므로database.php설정 파일에서 다른 Redis 연결에 할당하거나horizon.php설정 파일에서use옵션의 값으로 지정해서는 안 됩니다.
Content Security Policy (CSP) Nonce
Horizon 뷰에서 사용하는 script 및 style 태그에 nonce attribute를 Content Security Policy의 일부로 사용하려면 Horizon::cspNonce 메서드를 사용해 사용할 nonce를 지정할 수 있습니다. 일반적으로 이 메서드는 미들웨어에서 호출하여 각 요청에 새로운 nonce가 할당되도록 해야 합니다:
use Closure;
use Illuminate\Http\Request;
use Laravel\Horizon\Horizon;
use Symfony\Component\HttpFoundation\Response;
public function handle(Request $request, Closure $next): Response
{
Horizon::cspNonce('csp-nonce');
return $next($request);
}
애플리케이션의 config/horizon.php 설정 파일에서 middleware 옵션에 이 미들웨어를 추가할 수 있습니다:
'middleware' => [
'web',
App\Http\Middleware\AddHorizonCspNonce::class,
],
Environments
Horizon 설치 후 가장 먼저 제어해야 하는 주요 옵션은 environments 설정입니다. 이 옵션은 애플리케이션이 동작하는 여러 환경(environment)에 따라 각 워커 프로세스 옵션을 정의합니다. 기본적으로는 production과 local 환경이 정의되어 있지만, 필요한 만큼 환경을 추가할 수 있습니다.
'environments' => [
'production' => [
'supervisor-1' => [
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
],
],
'local' => [
'supervisor-1' => [
'maxProcesses' => 3,
],
],
],
다음과 같이 와일드카드 환경(*)도 정의할 수 있으며, 일치하는 환경이 없을 때 사용됩니다.
'environments' => [
// ...
'*' => [
'supervisor-1' => [
'maxProcesses' => 3,
],
],
],
Horizon을 시작하면 애플리케이션이 실행 중인 환경에 대한 워커 프로세스 설정 옵션을 사용합니다. 일반적으로 환경은 APP_ENV environment variable의 값으로 결정됩니다. 예를 들어 기본 local Horizon 환경은 워커 프로세스 3개를 시작하고 각 큐에 할당된 워커 프로세스 수를 자동으로 균형 조정하도록 설정되어 있습니다. 기본 production 환경은 최대 10개의 워커 프로세스를 시작하고 각 큐에 할당된 워커 프로세스 수를 자동으로 균형 조정하도록 설정되어 있습니다.
Horizon을 실행하려는 각 environment에 대한 항목이
horizon설정 파일의environments부분에 포함되어 있는지 확인해야 합니다.
Supervisors
Horizon의 기본 설정 파일을 살펴보면, 각 환경에는 하나 이상의 "supervisor(감독자)"를 포함할 수 있습니다. 기본적으로 supervisor-1이라는 이름이 설정되어 있지만, 원하는 대로 이름을 지정할 수 있습니다. 각 supervisor는 하나의 워커 프로세스 그룹을 "감독하고", 큐 간 워커 프로세스의 적절한 분배를 관리합니다.
특정 환경 내에서 추가 supervisor를 정의하면, 새로운 워커 프로세스 그룹을 생성하여 각기 다른 큐에 서로 다른 분산 전략이나 워커 수를 적용할 수 있습니다.
Maintenance Mode
애플리케이션이 maintenance mode 상태인 동안에는 Horizon 설정 파일에서 supervisor의 force 옵션을 true로 설정하지 않는 한 Horizon이 큐에 대기 중인 잡을 처리하지 않습니다:
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'force' => true,
],
],
],
Default Values
Horizon의 기본 설정 파일에는 defaults라는 옵션이 있습니다. 이 옵션은 supervisors에 대한 기본값을 지정합니다. supervisor의 기본값은 각 환경의 supervisor 설정에 병합되어, 중복 구성을 줄이고 관리가 편리해집니다.
Dashboard Authorization
Horizon 대시보드는 /horizon 라우트를 통해 이용할 수 있습니다. 기본적으로는 local 환경에서만 이 대시보드에 액세스할 수 있습니다. 하지만 app/Providers/HorizonServiceProvider.php 파일에는 authorization gate 정의가 있습니다. 이 authorization gate는 로컬이 아닌 환경에서 Horizon에 대한 액세스를 제어합니다. 필요에 따라 이 gate를 수정하여 Horizon 설치에 대한 액세스를 제한할 수 있습니다:
/**
* Register the Horizon gate.
*
* This gate determines who can access Horizon in non-local environments.
*/
protected function gate(): void
{
Gate::define('viewHorizon', function (User $user) {
return in_array($user->email, [
]);
});
}
Alternative Authentication Strategies
Laravel은 게이트 클로저에 인증된 사용자를 자동으로 주입합니다. 만약 IP 제한 등 다른 방식으로 Horizon 보안을 설정 중이라면, 사용자가 굳이 "로그인"할 필요가 없을 수 있습니다. 이런 경우 위 클로저의 시그니처를 function (User $user)에서 function (User $user = null)로 변경하여 인증 요구를 없앨 수 있습니다.
Max Job Attempts
이러한 옵션을 조정하기 전에 Laravel의 기본 queue services와 'attempts' 개념을 숙지했는지 확인하세요.
supervisor 설정 내에서 각 작업이 시도할 수 있는 최대 횟수를 지정할 수 있습니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'tries' => 10,
],
],
],
이 옵션은 Artisan 명령어로 큐를 처리할 때 사용하는
--tries옵션과 유사합니다.
WithoutOverlapping, RateLimited과 같은 미들웨어를 사용할 경우 시도 횟수를 소비하므로 tries 옵션을 조정하는 것이 중요합니다. 이를 처리하려면 supervisor 단위에서 tries 설정 값을 조정하거나, 작업 클래스에 $tries 속성을 정의하여 적절히 조정해야 합니다.
tries 옵션을 명시하지 않으면 Horizon 기본값은 한 번만 실행하며, 작업 클래스에 $tries 속성이 있으면 Horizon 설정보다 우선됩니다.
tries나 $tries를 0으로 설정하면 무한정 시도가 가능합니다. 시도 횟수에 제한이 불분명할 때 유용합니다. 단, 무한 반복 실패를 막으려면 작업 클래스에 $maxExceptions 속성을 설정하여 예외 허용 횟수를 제한할 수 있습니다.
Job Timeout
supervisor 단위로 timeout 값을 설정할 수 있습니다. 이 값은 워커 프로세스가 하나의 작업을 강제로 종료시키기 전까지 최대 수행할 수 있는 초단위 시간입니다. 제한 시간 초과 시, 작업은 큐 설정에 따라 재시도되거나 실패로 처리됩니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'timeout' => 60,
],
],
],
auto밸런싱 전략을 사용할 때 Horizon은 진행 중인 워커를 "멈춘" 상태로 간주하며, 스케일 다운 중 Horizon 타임아웃이 지나면 해당 워커를 강제로 종료합니다. 항상 Horizon 타임아웃이 잡 수준의 타임아웃보다 긴지 확인해야 합니다. 그렇지 않으면 잡이 실행 중간에 종료될 수 있습니다. 또한timeout값은config/queue.php설정 파일에 정의된retry_after값보다 항상 몇 초 이상 짧아야 합니다. 그렇지 않으면 잡이 두 번 처리될 수 있습니다.
Job Backoff
supervisor 단위에서 backoff 값을 설정하면, 예외 발생 후 작업 재시도까지 대기할 시간을 지정할 수 있습니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'backoff' => 10,
],
],
],
backoff 값에 배열을 사용하면 "지수적(exponential)" 백오프 설정도 가능합니다. 예를 들어 아래처럼 배열로 설정한 경우, 첫 번째 재시도는 1초, 두 번째는 5초, 세 번째는 10초를 대기하며, 이후엔 계속 10초 동안 대기합니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'backoff' => [1, 5, 10],
],
],
],
Other Worker Options
tries, timeout, backoff 외에도 각 supervisor는 워커 프로세스의 동작 방식과 자동으로 재시작되는 시점을 제어하는 여러 옵션을 지원합니다. 메모리 누수를 방지하는 데 도움이 되므로 장시간 실행되는 프로세스에서는 워커를 주기적으로 재시작하는 것이 좋습니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'memory' => 128,
'maxJobs' => 1000,
'maxTime' => 3600,
'sleep' => 3,
'rest' => 0,
'nice' => 0,
],
],
],
memory는 단일 워커 프로세스가 재시작되기 전에 사용할 수 있는 최대 메모리 양을 메가바이트 단위로 정의합니다. 기본값은128입니다.maxJobs는 워커가 재시작되기 전에 처리해야 하는 잡의 수를 정의합니다.0은 처리한 잡의 수를 기준으로 워커를 재시작하지 않음을 나타냅니다. 기본값은0입니다.maxTime은 워커가 재시작되기 전에 실행되어야 하는 시간을 초 단위로 정의합니다.0은 시간을 기준으로 워커를 재시작하지 않음을 나타냅니다. 기본값은0입니다.sleep은 사용 가능한 잡이 없을 때 워커가 새 잡을 다시 확인하기 전에 대기할 시간을 초 단위로 정의합니다. 기본값은3입니다.rest는 각 잡을 처리하는 사이에 일시 중지할 시간을 초 단위로 정의합니다. 기본값은0입니다.nice는 워커 프로세스의 "niceness"(스케줄링 우선순위)를 정의합니다. 값이 클수록 프로세스의 우선순위가 낮아집니다. 기본값은0입니다.
Silenced Jobs
특정 작업이 대시보드의 "완료된 작업" 목록에 표시되는 것을 원하지 않는 경우, 해당 작업을 음소거(silence)할 수 있습니다. 이를 위해, 작업 클래스명을 horizon 설정 파일의 silenced 옵션에 추가하세요.
'silenced' => [
App\Jobs\ProcessPodcast::class,
],
개별 작업 클래스 외에도, tags 기반으로도 음소거를 지원합니다. 동일 태그를 가진 여러 작업을 숨길 때 유용합니다.
'silenced_tags' => [
'notifications'
],
또는, 음소거 대상 작업이 Laravel\Horizon\Contracts\Silenced 인터페이스를 구현하도록 할 수도 있습니다. 이 경우, silenced 설정 배열에 추가하지 않아도 자동으로 음소거됩니다.
use Laravel\Horizon\Contracts\Silenced;
class ProcessPodcast implements ShouldQueue, Silenced
{
use Queueable;
// ...
}
Balancing Strategies
각 supervisor는 하나 이상의 큐를 처리할 수 있습니다. Laravel의 기본 큐 시스템과 달리, Horizon은 워커 분산 전략으로 auto, simple, false 중 하나를 선택할 수 있습니다.
Auto Balancing
기본값인 auto 전략은 각 큐의 현재 작업량에 따라 워커 프로세스 수를 자동으로 조정합니다. 예를 들어, notifications 큐에 1,000개의 작업이 대기 중이고, default 큐는 비어 있다면, Horizon은 notifications 큐에 더 많은 워커를 할당하여 큐를 빠르게 소화하도록 합니다.
auto 전략을 사용할 때는 minProcesses와 maxProcesses 옵션도 설정할 수 있습니다.
minProcesses는 큐마다 필요한 최소 워커 프로세스 수를 정의합니다. 이 값은 1 이상이어야 합니다.maxProcesses는 Horizon이 모든 큐에 걸쳐 확장할 수 있는 워커 프로세스의 최대 총 개수를 정의합니다. 일반적으로 이 값은 큐의 수에minProcesses값을 곱한 수보다 커야 합니다. supervisor가 프로세스를 생성하지 않도록 하려면 이 값을 0으로 설정할 수 있습니다.
예를 들어, 큐마다 최소 1개의 프로세스를 유지하면서, 전체 워커 수는 최대 10개로 제한할 수 있습니다.
'environments' => [
'production' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default', 'notifications'],
'balance' => 'auto',
'autoScalingStrategy' => 'time',
'minProcesses' => 1,
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
],
],
],
autoScalingStrategy 옵션은 Horizon이 큐에 워커를 증설할 때 어떤 기준을 사용할지 결정합니다.
time전략은 큐를 비우는 데 걸리는 총 예상 시간을 기준으로 워커를 할당합니다.size전략은 큐에 있는 전체 잡 수를 기준으로 워커를 할당합니다.
balanceMaxShift와 balanceCooldown 값으로 Horizon이 워커 수를 증/감하는 속도를 조절할 수 있습니다. 위 설정에서는 3초마다 최대 1개의 프로세스가 생성 또는 제거됩니다. 애플리케이션 특성에 맞게 이 값을 조절할 수 있습니다.
Queue Priorities and Auto Balancing
auto 전략 사용 시, supervisor 설정 내 큐의 나열 순서는 우선순위에 영향을 주지 않습니다. 각 큐의 부하에 따라 동적으로 워커가 할당되고, autoScalingStrategy에 의해 분배됩니다.
예를 들어 아래와 같이 구성해도, high 큐가 default 큐보다 우선 처리되지 않습니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'queue' => ['high', 'default'],
'minProcesses' => 1,
'maxProcesses' => 10,
],
],
],
큐 간 처리 우선순위를 명확히 설정하려면, supervisor를 여러 개 만들어 각각 다른 큐에 자원을 명시적으로 할당하세요.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'queue' => ['default'],
'minProcesses' => 1,
'maxProcesses' => 10,
],
'supervisor-2' => [
// ...
'queue' => ['images'],
'minProcesses' => 1,
'maxProcesses' => 1,
],
],
],
이 예시에서는 기본 queue는 10개까지 확장 가능하고, images 큐는 1개의 프로세스만 사용하도록 보장됩니다. 이렇게 하면 각 큐별로 독립적 스케일링이 가능합니다.
리소스를 많이 사용하는 잡을 디스패치할 때는 제한된
maxProcesses값을 가진 전용 큐에 할당하는 것이 좋을 때가 있습니다. 그렇지 않으면 이러한 잡이 CPU 리소스를 과도하게 사용해 시스템에 과부하를 일으킬 수 있습니다.
Simple Balancing
simple 전략은 지정된 큐에 워커 프로세스를 균등하게 분배합니다. 이 전략에서는 워커 프로세스가 고정되며 자동 확장이 없습니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'queue' => ['default', 'notifications'],
'balance' => 'simple',
'processes' => 10,
],
],
],
위 예시에서는 10개의 프로세스가 2개 큐에 각 5개씩 균등 할당됩니다.
개별 큐별로 워커 수를 따로 조절하려면, supervisor를 여러 개 정의하면 됩니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'queue' => ['default'],
'balance' => 'simple',
'processes' => 10,
],
'supervisor-notifications' => [
// ...
'queue' => ['notifications'],
'balance' => 'simple',
'processes' => 2,
],
],
],
이렇게 하면 default 큐에는 10개, notifications 큐에는 2개의 프로세스가 할당됩니다.
No Balancing
balance 옵션을 false로 설정할 경우, Laravel 기본 큐 시스템과 마찬가지로 큐에 나열된 순서대로 작업을 처리합니다. 단, 작업이 누적되면 워커 수는 여전히 확장됩니다.
'environments' => [
'production' => [
'supervisor-1' => [
// ...
'queue' => ['default', 'notifications'],
'balance' => false,
'minProcesses' => 1,
'maxProcesses' => 10,
],
],
],
위 예시에서는 default 큐 작업이 항상 notifications 큐 작업보다 우선 처리됩니다. 만약 default 큐에 1,000개 작업, notifications 큐에 10개가 있다면, default 큐의 작업을 모두 처리한 후에야 notifications 큐 작업을 처리하게 됩니다.
워커 확장 범위는 minProcesses와 maxProcesses 옵션으로 제어할 수 있습니다.
minProcesses는 전체 워커 프로세스의 최소 개수를 정의합니다. 이 값은 1 이상이어야 합니다.maxProcesses는 Horizon이 확장할 수 있는 전체 워커 프로세스의 최대 개수를 정의합니다.
Upgrading Horizon
Horizon의 주요 버전을 업그레이드할 때는 반드시 the upgrade guide를 꼼꼼히 검토해야 합니다.
Running Horizon
config/horizon.php 파일에서 supervisor와 worker를 모두 설정했다면, horizon Artisan 명령어로 Horizon을 시작할 수 있습니다. 이 단일 명령어가 현재 환경에 맞는 모든 워커 프로세스를 구동합니다.
php artisan horizon
처리 중인 Horizon 프로세스를 일시정지 또는 재개하려면 horizon:pause와 horizon:continue Artisan 명령어를 사용할 수 있습니다.
php artisan horizon:pause
php artisan horizon:continue
특정 Horizon supervisors를 일시정지하거나 재개하려면 horizon:pause-supervisor와 horizon:continue-supervisor Artisan 명령어를 사용하세요.
php artisan horizon:pause-supervisor supervisor-1
php artisan horizon:continue-supervisor supervisor-1
현재 Horizon 프로세스 상태를 확인하려면 horizon:status Artisan 명령어를 사용하세요.
php artisan horizon:status
특정 Horizon supervisor의 상태를 확인하려면 horizon:supervisor-status Artisan 명령어를 사용하세요.
php artisan horizon:supervisor-status supervisor-1
Horizon 프로세스를 정상적으로 종료하려면 horizon:terminate Artisan 명령어를 사용할 수 있습니다. 현재 처리 중인 작업이 마무리되고 Horizon이 종료됩니다.
php artisan horizon:terminate
Automatically Restarting Horizon
로컬 개발 중에는 horizon:listen 명령어를 사용할 수 있습니다. horizon:listen 명령어를 사용하면, 코드가 변경될 때마다 Horizon을 수동으로 재시작하지 않아도 됩니다. 사용 전 반드시 Node를 로컬 환경에 설치해야 하며, 프로젝트에 Chokidar 파일 감시 라이브러리도 설치해야 합니다.
npm install --save-dev chokidar
Chokidar 설치 후, horizon:listen 명령어로 Horizon을 시작할 수 있습니다.
php artisan horizon:listen
Docker나 Vagrant 환경에서는 --poll 옵션을 사용하세요.
php artisan horizon:listen --poll
감시할 파일 및 디렉터리는 애플리케이션의 config/horizon.php에서 watch 옵션으로 설정할 수 있습니다.
'watch' => [
'app',
'bootstrap',
'config',
'database',
'public/**/*.php',
'resources/**/*.php',
'routes',
'composer.lock',
'.env',
],
Deploying Horizon
실제 서버에 Horizon을 배포할 때는 프로세스 모니터를 이용해 php artisan horizon 명령어를 관리하며, 예기치 않게 종료될 때 재시작하도록 설정하세요. 아래에서 프로세스 모니터 설치 방법을 안내합니다.
배포 과정에서는 Horizon 프로세스가 종료되도록 지시하여, 프로세스 모니터가 이를 재시작하면서 코드 변경 사항을 반영하도록 해야 합니다.
php artisan horizon:terminate
Installing Supervisor
Supervisor는 Linux 운영체제용 프로세스 모니터로, horizon 프로세스가 중단될 경우 자동 재시작합니다. Ubuntu에 Supervisor를 설치하려면 아래 명령어를 사용할 수 있습니다. 다른 OS에서는 운영체제의 패키지 매니저로 Supervisor를 설치하세요.
sudo apt-get install supervisor
Supervisor를 직접 설정하는 일이 부담스럽다면 Laravel 애플리케이션의 백그라운드 프로세스를 관리할 수 있는 Laravel Cloud를 사용해 보세요.
Supervisor Configuration
Supervisor 설정 파일은 보통 서버의 /etc/supervisor/conf.d 디렉터리에 저장됩니다. 이 디렉터리 내에 여러 개의 설정 파일을 생성하여, 각 프로세스를 어떻게 모니터링할지 지정할 수 있습니다. 예시로, horizon.conf 파일을 생성해서 horizon 프로세스를 시작/모니터링합니다.
[program:horizon]
process_name=%(program_name)s
command=php /home/forge/example.com/artisan horizon
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/example.com/horizon.log
stopwaitsecs=3600
stopwaitsecs 값은 최장 실행 작업의 소요 시간보다 항상 크게 지정해야 합니다. 그렇지 않으면 Supervisor가 작업이 끝나기 전에 프로세스를 강제로 종료할 수 있습니다.
위 예시는 Ubuntu 기반 서버에서 유효하지만, 다른 서버 운영 체제에서는 Supervisor 설정 파일의 위치와 예상되는 파일 확장자가 다를 수 있습니다. 자세한 내용은 서버의 문서를 참고하세요.
Starting Supervisor
설정 파일 생성 후, 다음 명령어로 Supervisor 설정을 갱신하고 모니터링을 시작할 수 있습니다.
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start horizon
Supervisor 실행에 관한 자세한 정보는 Supervisor documentation을 참고하세요.
Tags
Horizon은 작업, 메일(메일러블), 브로드캐스트 이벤트, 알림, 큐에 등록된 이벤트 리스너 등에 "태그"를 지정할 수 있습니다. Horizon은 대다수 작업을 대상으로 자동으로 태그를 지정하며, 이는 해당 작업에 연결된 Eloquent 모델을 기준으로 합니다. 예를 들어, 아래 작업 클래스를 살펴보세요.
<?php
namespace App\Jobs;
use App\Models\Video;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class RenderVideo implements ShouldQueue
{
use Queueable;
/**
* Create a new job instance.
*/
public function __construct(
public Video $video,
) {}
/**
* Execute the job.
*/
public function handle(): void
{
// ...
}
}
이 작업이 id 속성값이 1인 App\Models\Video 인스턴스와 함께 큐에 등록된다면, 자동으로 App\Models\Video:1이라는 태그가 부여됩니다. Horizon이 작업 속성에서 Eloquent 모델을 찾아, 클래스명 및 기본 키(primary key) 조합으로 태그를 생성하기 때문입니다.
use App\Jobs\RenderVideo;
use App\Models\Video;
$video = Video::find(1);
RenderVideo::dispatch($video);
Manually Tagging Jobs
큐 작업에 직접 지정할 태그를 정의하려면, 클래스에 tags 메서드를 정의하세요.
class RenderVideo implements ShouldQueue
{
/**
* Get the tags that should be assigned to the job.
*
* @return array<int, string>
*/
public function tags(): array
{
return ['render', 'video:'.$this->video->id];
}
}
Manually Tagging Event Listeners
이벤트 리스너가 큐에 등록되어 있을 때 Horizon이 태그를 가져오는 방식은, 이벤트 인스턴스를 tags 메서드에 전달하는 것입니다. 이를 이용해 이벤트 데이터를 이용한 태그 지정이 가능합니다.
class SendRenderNotifications implements ShouldQueue
{
/**
* Get the tags that should be assigned to the listener.
*
* @return array<int, string>
*/
public function tags(VideoRendered $event): array
{
return ['video:'.$event->video->id];
}
}
Notifications
Horizon에서 Slack 또는 SMS 알림을 전송하도록 구성할 때는 prerequisites for the relevant notification channel을 검토해야 합니다.
특정 큐의 대기 시간이 과도하게 길어졌을 때 알림을 받고 싶다면, Horizon::routeMailNotificationsTo, Horizon::routeSlackNotificationsTo, Horizon::routeSmsNotificationsTo 메서드를 사용할 수 있습니다. 이 메서드는 App\Providers\HorizonServiceProvider의 boot 메서드에서 호출하세요.
/**
* Bootstrap any application services.
*/
public function boot(): void
{
parent::boot();
Horizon::routeSmsNotificationsTo('15556667777');
Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
}
Configuring Notification Wait Time Thresholds
큐 대기 시간이 얼마나 길 경우를 "장시간 대기"로 간주할지, 애플리케이션의 config/horizon.php의 waits 옵션으로 지정할 수 있습니다. 각 연결/큐 조합별 임계값을 초 단위로 다음과 같이 조정하세요. 정의하지 않은 조합은 기본값 60초가 적용됩니다.
'waits' => [
'redis:critical' => 30,
'redis:default' => 60,
'redis:batch' => 120,
],
큐의 임계값을 0으로 설정하면 해당 큐에 대해 긴 대기 시간 알림이 비활성화됩니다.
Metrics
Horizon은 작업 및 큐 대기 시간, 처리량 관련 정보를 확인할 수 있는 메트릭 대시보드를 제공합니다. 대시보드에 데이터를 채우려면, routes/console.php 파일에서 Horizon의 snapshot Artisan 명령어가 5분마다 실행되도록 스케줄링해야 합니다.
use Illuminate\Support\Facades\Schedule;
Schedule::command('horizon:snapshot')->everyFiveMinutes();
애플리케이션의 config/horizon.php 설정 파일에서 metrics.trim_snapshots 옵션을 사용해 Horizon이 메트릭 그래프에 보관할 스냅샷 수를 설정할 수 있습니다. 이 옵션은 스냅샷의 보관 기간이 아니라 개수를 제한하므로, 보관 기간은 horizon:snapshot 명령어가 실행되는 빈도에 따라 달라집니다:
'metrics' => [
'trim_snapshots' => [
'job' => 24,
'queue' => 24,
],
],
모든 메트릭 데이터를 삭제하고 싶다면, horizon:clear-metrics Artisan 명령어를 사용하세요.
php artisan horizon:clear-metrics
Deleting Failed Jobs
개별 실패 작업을 삭제하려면 horizon:forget 명령어를 사용하면 됩니다. horizon:forget 명령어는 실패한 작업의 ID 또는 UUID 하나만 인수로 받습니다.
php artisan horizon:forget 5
모든 실패 작업을 삭제하려면, horizon:forget 명령어에 --all 옵션을 제공하세요.
php artisan horizon:forget --all
Clearing Jobs From Queues
애플리케이션 기본 큐에 누적된 모든 작업을 삭제하고 싶다면, horizon:clear Artisan 명령어를 사용하세요.
php artisan horizon:clear
특정 큐의 작업만 삭제하려면 queue 옵션을 지정하세요.
php artisan horizon:clear --queue=emails