Skip to main content

태스크 스케줄링이란

종래에는 서버에서 정기 실행이 필요한 태스크마다 cron 엔트리를 손으로 써야 했습니다. 그러나 이 방법으로는 스케줄 정의가 소스 코드 외에 존재하기 때문에, 버전 관리를 할 수 없고, 확인·변경할 때마다 SSH 로그인이 필요해집니다. Laravel의 스케줄러를 사용하면 애플리케이션 내에서 스케줄을 유창하게 정의할 수 있습니다. 서버에 등록할 cron 엔트리는 1행만으로 끝나며, 스케줄 정의는 코드와 함께 버전 관리됩니다. 스케줄은 routes/console.php에 정의하는 것이 표준적인 스타일입니다.
schedule:list Artisan 명령으로, 정의된 태스크 일람과 다음 실행 예정 시각을 확인할 수 있습니다.

스케줄러의 실행 플로우

스케줄 정의 방법

스케줄의 정의는 routes/console.php에 기술합니다. bootstrap/app.phpwithSchedule 메서드를 사용해 정의하는 방법도 있습니다.

스케줄 가능한 태스크의 종류

Artisan 명령의 스케줄

command 메서드로 Artisan 명령을 스케줄합니다. 명령명 또는 클래스명으로 지정할 수 있습니다.
클로저로 정의한 Artisan 명령에도, 정의의 직후에 스케줄 메서드를 체인할 수 있습니다.

큐 잡의 스케줄

job 메서드로 큐 잡을 스케줄합니다. 클로저를 사용하지 않고 잡을 큐에 쌓는 편리한 방법입니다.
큐명이나 접속처를 지정할 수도 있습니다.

셸 명령의 스케줄

exec 메서드로 OS 명령을 실행합니다.

클로저의 스케줄

call 메서드로 임의의 PHP 클로저를 스케줄합니다.
__invoke 메서드를 가진 Invocable 오브젝트도 전달할 수 있습니다.

스케줄 빈도의 설정

주요 빈도 메서드

자주 사용하는 빈도 메서드를 이하에 나타냅니다.

cron 식으로 직접 지정

cron 메서드로 cron 식을 직접 지정할 수도 있습니다.

빈도와 요일의 조합

빈도 메서드와 요일 제약을 조합해, 보다 세밀한 스케줄을 만들 수 있습니다.

타임 존의 설정

timezone 메서드로 개별 태스크의 타임 존을 지정할 수 있습니다.
모든 태스크에 공통의 타임 존을 설정하고 싶은 경우는 config/app.phpschedule_timezone을 사용합니다.
서머타임이 적용되는 타임 존을 사용하는 경우, 전환 타이밍에 태스크가 2회 실행되거나, 전혀 실행되지 않을 수 있습니다. 가능한 한 UTC를 사용할 것을 권장합니다.

조건 제약

when / skip

when은 클로저가 true를 반환한 경우에만 태스크를 실행합니다. skip은 그 반대로, true를 반환한 경우에 스킵합니다.

environments

environments 메서드로 특정의 환경에서만 실행하도록 제한할 수 있습니다.

시각의 제약

between / unlessBetween으로 실행 시간대를 제한할 수 있습니다.

요일의 제약

중복 방지

기본적으로는 이전 태스크가 아직 실행 중이어도 다음 실행이 개시됩니다. withoutOverlapping을 사용하면, 이전 실행이 끝날 때까지 다음 실행을 대기시킬 수 있습니다.
락의 유효 기한(분)을 지정할 수도 있습니다. 기본값은 24시간입니다.
withoutOverlapping은 애플리케이션의 캐시를 사용해 락을 관리합니다. 태스크가 예기치 못한 문제로 스택된 경우는 schedule:clear-cache로 락을 해제할 수 있습니다.

여러 서버에서의 실행 제어

여러 서버에서 스케줄러가 동작하고 있는 경우, onOneServer를 사용함으로써 1대의 서버에서만 태스크를 실행할 수 있습니다.
이 기능을 사용하려면 애플리케이션의 기본 캐시 드라이버를 database, memcached, dynamodb, 또는 redis로 설정하고, 모든 서버가 같은 캐시 서버에 접속하고 있어야 합니다.

onOneServer()에 의한 분산 실행 제어 플로우

태스크의 그룹화

여러 태스크에 같은 설정을 적용하는 경우는 group 메서드를 사용해 정리할 수 있습니다.

백그라운드 실행

같은 시각에 스케줄된 태스크는, 기본적으로는 정의 순으로 차례로 실행됩니다. 장시간 걸리는 태스크가 있으면 후속 태스크의 개시가 늦어집니다. runInBackground를 사용하면 태스크를 백그라운드에서 병렬 실행할 수 있습니다.
runInBackgroundcommandexec 메서드에서만 사용할 수 있습니다.

메인터넌스 모드

애플리케이션이 메인터넌스 모드일 때, 스케줄 태스크는 실행되지 않습니다. 메인터넌스 모드 중에도 강제적으로 실행시키고 싶은 경우는 evenInMaintenanceMode를 사용합니다.

메인터넌스 모드의 대응 플로우

스케줄러의 일시 정지

코드를 변경하지 않고 스케줄러를 일시 정지할 수 있습니다.
정지 중에도 특정 태스크만 계속 실행하고 싶은 경우는 evenWhenPaused를 사용합니다. 헬스체크나 시스템 모니터링 등, 메인터넌스 중에도 계속이 필요한 태스크에 유용합니다.

출력의 핸들링

파일에의 출력

sendOutputTo로 태스크의 출력을 파일에 저장할 수 있습니다.
appendOutputTo를 사용하면 기존의 파일에 추가 기재합니다.

메일에의 출력

emailOutputTo로 태스크의 출력을 메일로 송신할 수 있습니다. 사전에 Laravel의 메일 설정이 필요합니다.
실패 시에만 메일을 보내는 경우는 emailOutputOnFailure를 사용합니다.

태스크 훅

before / after 메서드로, 태스크의 실행 전후에 처리를 삽입할 수 있습니다.
성공·실패 시의 훅은 onSuccess / onFailure로 정의합니다.

서버에의 배포

1

cron 엔트리를 추가

서버의 crontab에 이하의 1행을 추가하는 것만으로, Laravel의 스케줄러가 매분 실행됩니다.
crontab -e 명령으로 편집할 수 있습니다.
2

스케줄러의 동작을 확인

정의된 태스크의 일람과 다음 실행 시각을 확인합니다.
Laravel Cloud를 사용하면, cron의 설정 없이 스케줄 태스크를 관리할 수 있습니다.

로컬 개발에서의 실행

로컬 환경에서는 cron을 사용하지 않고, schedule:work 명령으로 스케줄러를 상시 기동할 수 있습니다.
이 명령은 포어그라운드에서 동작하고, 매분 스케줄러를 호출합니다. Ctrl+C로 정지할 때까지 계속 동작합니다.

서브 분 스케줄 (1분 미만의 빈도)

통상의 cron은 1분이 최소 단위이지만, Laravel에서는 1초 단위의 스케줄도 설정할 수 있습니다.
서브 분 태스크가 정의되어 있는 경우, schedule:run은 그 분이 끝날 때까지 계속 동작하여, 모든 서브 분 태스크를 처리합니다.
서브 분 태스크는 큐 잡이나 백그라운드 명령에 처리를 위양할 것을 권장합니다. 태스크 자체가 장시간 걸리면, 후속의 서브 분 태스크의 실행이 늦어지기 때문입니다.
배포 중에 실행 중인 schedule:run을 중단하려면, 배포 스크립트에 이하를 추가합니다.

자주 사용하는 명령 정리

마지막 수정일 2026년 7월 13일