Go 언어에서 정기 작업 스케줄링 구현

1. 의존성 설치

go get github.com/robfig/cron/v3@v3.0.0

2. 기본 정기 작업 예제

package main

import (
	"fmt"
	"github.com/robfig/cron/v3"
	"time"
)

func main() {
	// 초 단위까지 정밀하게 동작하는 스케줄러 생성
	scheduler := cron.New(cron.WithSeconds())

	// 실행할 작업 정의
	operation := func() {
		fmt.Println("안녕하세요, 현재 시간:", time.Now())
	}

	// 매 5초마다 실행되는 표현식
	schedule := "*/5 * * * * ?"

	// 작업 등록
	_ = scheduler.AddFunc(schedule, operation)

	// 스케줄러 시작
	scheduler.Start()

	// 메인 루틴을 블록 상태로 유지 (실제 프로덕션에서는 종료 조건 추가 필요)
	select {}
}

3. Cron 표현식 구성 요소

Cron 표현식은 6개의 필드로 구성되며, 각각은 다음과 같은 의미를 가집니다:

필드범위설명
초 (Seconds)0-59정확한 초 단위 제어 가능
분 (Minutes)0-59
시 (Hours)0-23
일 (Day of Month)1-31
월 (Month)1-12 또는 JAN-DEC
요일 (Day of Week)0-6 (0=일요일)0 또는 7은 일요일

3.1 특수 문자 설명

  • *: 해당 필드의 모든 값을 의미
  • /: 간격 지정 (예: 0/10 → 0,10,20,...)
  • ,: 복수 값 지정 (예: 1,3,5)
  • -: 범위 지정 (예: 9-17)
  • ?: 일 또는 요일 중 하나에만 사용되며, 특정 값을 지정하지 않음을 의미

3.2 자주 사용하는 예시

// 5초마다 실행
*/5 * * * * ?

// 1분마다 실행
0 */1 * * * ?

// 매일 밤 11시 실행
0 0 23 * * ?

// 매월 1일 오전 1시 실행
0 0 1 1 * ?

// 월요일과 수요일 오후 10시 30분 실행
0 30 22 * * 1,3

// 매시간 26, 29, 33분에 실행
0 26,29,33 * * * ?

// 매일 0시, 13시, 18시, 21시 실행
0 0 0,13,18,21 * * ?

// 매년 3월의 목요일 오후 2시 10분 및 40분 실행
0 10,40 14 ? 3 4

3.3 미리 정의된 형식

다음과 같은 약어를 사용하여 표현식을 간단히 작성할 수 있습니다:

형식설명해당 표현식
@yearly매년 1월 1일 자정0 0 0 1 1 *
@monthly매월 1일 자정0 0 0 1 * *
@weekly매주 토요일 자정0 0 0 * * 0
@daily매일 자정0 0 0 * * *
@hourly매시간 정각0 0 * * * *
@every <기간>지정된 기간마다 실행예: @every 1h30m
c := cron.New()
c.AddFunc("@every 1h30m", func() {
    fmt.Println("매 1시간 30분마다 실행")
})

4. 다중 작업 처리

type TaskA struct {
    ID string
}

func (t *TaskA) Run() {
    fmt.Printf("작업 A 실행: %s\n", t.ID)
}

type TaskB struct {
    Name string
}

func (b *TaskB) Run() {
    fmt.Printf("작업 B 실행: %s\n", b.Name)
}

func main() {
    scheduler := cron.New(cron.WithSeconds())

    schedule := "*/10 * * * * ?" // 10초마다

    // 함수형 작업 등록
    _ = scheduler.AddFunc(schedule, func() {
        fmt.Println("함수 기반 작업 실행:", time.Now())
    })

    // 구조체 기반 작업 등록
    _ = scheduler.AddJob(schedule, &TaskA{ID: "task-001"})
    _ = scheduler.AddJob(schedule, &TaskB{Name: "job-b-002"})

    scheduler.Start()
    defer scheduler.Stop()

    select {}
}

5. 실용적 적용 예시

func init() {
    taskScheduler := cron.New(cron.WithSeconds())

    _, err := taskScheduler.AddFunc("*/1 * * * * *", func() {
        processor := OrderProcessor{}
        processor.ProcessPendingOrders(1, 10)
    })

    if err == nil {
        taskScheduler.Start()
    }
}

태그: go cron 정기 작업 스케줄링 동시성

7월 2일 23:17에 게시됨