라라벨 큐 와 잡(Queue & Job)

|

소개

라라벨 큐(Queue) 와 잡(Job) 은 시간이 많이 걸리는 작업백그라운드에서 처리하는데 사용됩니다.

라라벨 큐(Queue)

큐는 작업을 나중에 실행하기 위해 저장하는 대기열입니다.
이렇게 하면 브라우저가 서버로부터 응답을 기다리는 동안 사용자가 긴 처리 시간을 기다릴 필요가 없어집니다.
예를들어 이메일 발송, 대량 데이터 처리, 비디오 인코딩 등의 작업백그라운드에서 실행할 수 있게 됩니다.

  • 데이터베이스
  • Redis
  • Amazon SQS
  • Beanstalkd 등등

라라벨에서는 다양한 큐 백엔드를 지원합니다.
우리는 데이터베이스 기반으로 한 큐를 실행해보겠습니다.

설정

'default' => env('QUEUE_DRIVER', 'database'),

config/queue.php 에서 default 를 지정해줍니다.

큐 전원 켜기

php artisan queue:work --timeout=600

라라벨 큐는 전원을 켜줘야 합니다. 큐를 켜기 위해서는 다음의 명령어를 입력해야 합니다.

세션 나가도 큐 전원 유지하기

nohup php artisan queue:work --tries=5 --timeout=6000 --daemon > /dev/null 2>&1 &


정확히는 백그라운드에서 nohup 을 사용하여 작동되도록 만들어야 합니다.
이렇게 입력하게 되면 터미널 세션에서 나가게 되더라도 작동되게 됩니다.

  • nohub : 리눅스에서 프로세스를 실행한 터미널의 세션 연결이 끊어져도 지속적으로 동작할 수 있게 해줍니다.
    (터미널에서 세션 로그아웃이 발생하면 해당 터미널에서 실행한 프로세스들에게 HUP signal 이 전달하여 종료시키게 되는데, 이 HUP signal 을 프로세스가 무시하도록 하기 때문에 nohup 이라 함)
ps aux | grep queue

작동이 잘 되는지 체크하려면 위의 명령어를 입력하여 체크하면 됩니다.

세부 설명

php artisan queue:work --queue=high,default

–queue 옵션을 확인해보면 high 큐의 작업이 모두 처리된 뒤에 default 큐의 작업이 진행됩니다.

YourJob::dispatch()->onQueue('high');

작업을 디스패치할 때 명시적으로 큐를 지정할 수 있습니다.

  • dispatch : 작업을 큐에 추가하는데 사용되는 메서드

실전 사용

데이터베이스 생성하기

sail php artisan queue:table
sail php artisan migrate

database 큐 드라이버를 사용하려면 Job 들을 담아둘 데이터베이스 테이블이 필요합니다.
이 때 터미널 명령어를 실행하면 다음과 같은 데이터베이스 생성 코드가 자동으로 작성되어 있을 겁니다.

라라벨 잡 테이블 생성하기

생성된 파일을 보면 job 파일이 생긴 것을 확인할 수 있습니다. 바로 마이그레이션 해봅시다.

데이터베이스를 확인해보면 다음과 같은 결과를 확인할 수 있습니다.

env 파일 수정

QUEUE_CONNECTION=database

기본 큐 연결을 데이터베이스로 변경하기 위해 수정합니다.

잡(Job)

잡은 큐에 넣을 수 있는 작업의 실제 구현을 말합니다.
잡 클래스는 보통 app/Jobs 디렉토리에 저장되며 이 클래스에서는 큐에 넣고 싶은 작업을 정의합니다.

잡 클래스 생성하기

php artisan make:job SendEmailJob

잡 클래스 구현

// app/Jobs/SendEmailJob.php
namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $details;

    // 이 작업을 'high' 큐에 배치 (이름지정)
    // public $queue = 'high';

    public function __construct($details)
    {
        $this->details = $details;
    }

    public function handle()
    {
        // 이메일 발송 로직
    }
}

저는 여기에 $details 라는 protected 변수를 추가했습니다.
이렇게 하게 되면 큐 작업을 실행할 때 $details 를 변수로 활용할 수 있게 됩니다.

만약 우선순위를 매긴다면 위와 같이 $queue 변수에 high, default, low 등 여러가지를 적용할 수 있습니다. 어차피 터미널 명령어에 입력된 순서대로 처리가 되기 때문에 우리가 마음대로 수정하고 추가해도 무방합니다.

다음은 큐 이름 예제입니다.

  • emails: 이메일 전송 작업 전용 큐
  • notifications: 사용자 알림 처리 전용 큐
  • reports: 시간이 많이 걸리는 보고서 생성 작업 전용 큐
  • imports: 대량 데이터 가져오기 작업 전용 큐

잡을 큐에 추가하기

SendEmailJob::dispatch($details);

이러한 방식을 사용하면 라라벨에서는 시간이 많이 소요되는 작업을 효율적으로 관리할 수 있습니다.
큐와 잡을 사용하면 앱 성능을 크게 향상시키는 장점을 가질 수 있게 됩니다.

실패한 작업 관리

php artisan queue:failed-table
php artisan migrate

작업 중 실패한 작업을 관리하기 위해 기록하는 테이블을 생성합니다. 라라벨 10기준 기본 설치시 적용되어있습니다.

php artisan queue:failed

실패한 queue 를 조회할 수 있습니다.

php artisan queue:retry all

전체 queue 를 재시작하는 방법입니다.

php artisan queue:retry {id}

여기서 id 는 다시 시도하고싶은 id 입니다.

자동 실행열에 추가

큐를 자동 실행하도록 설정하려면 다음과 같이 진행하면 됩니다.
여기서의 핵심은 php artisan queue:work 를 실행해야 한다는 겁니다.

#!/bin/bash
# 라라벨 큐 리스너를 시작하는 스크립트

cd /path/to/your/laravel/project
php artisan queue:work --daemon &> /var/log/laravel-queue.log &

run-queue.sh 파일을 생성합니다. 라라벨 큐 리스너를 위한 쉘 스크립트입니다.

#!/bin/bash
# tcpdump를 사용하여 네트워크 트래픽을 모니터링하는 스크립트

tcpdump -i eth0 -w /var/log/tcpdump-capture.pcap &

run-tcpdump.sh 파일을 생성합니다. 모니터링 용도이기 때문에 필요 없다면 스킵하세요.

[Unit]
Description=Laravel Queue Worker and tcpdump

[Service]
Type=simple
ExecStart=/bin/bash -c '/path/to/run-queue.sh; /path/to/run-tcpdump.sh'

[Install]
WantedBy=multi-user.target

/etc/systemd/system/laravel-queue.service 파일을 생성합니다.

/bin/bash -c '명령어1; 명령어2; 명령어3'

/bin/bash -c 명령어는 /bin/bash 쉘을 사용해서 다음의 문자열을 쉘 명령어로 실행하라는 의미입니다.

sudo systemctl daemon-reload
sudo systemctl enable laravel-queue.service
sudo systemctl start laravel-queue.service

이 구성은 서버가 시작될 때 마다 라라벨 큐 리스너와 tcpdump 가 자동으로 실행되도록 합니다.
필요에 따라 tcpdump 스크립트의 옵션을 조정하여 특정 요구사항에 맞게 네트워크 트래픽을 모니터링 할 수 있습니다.

Cron 과의 차이점

  • 실행 위치(트리거) : Cron 작업은 시간에 기반하여 실행됩니다. 라라벨의 큐와 잡은 이벤트(사용자 요청, 특정 조건 충족 등) 에 의해 실행됩니다.
  • 관리 방식 : Cron 작업은 서버의 crontab 을 통해 관리되지만 라라벨의 큐와 잡은 라라벨 애플리케이션 내에서 관리됩니다.
  • 목적 및 사용 사례 : Cron 은 정기적이고 반복적인 작업에 적합하며, 라라벨의 큐 및 잡은 요청 시간을 단축시키고 사용자 경험을 향상시키기 위한 비동기 작업 처리에 적합합니다.

참조

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다