πŸŽ‰ berenickt λΈ”λ‘œκ·Έμ— 온 κ±Έ ν™˜μ˜ν•©λ‹ˆλ‹€. πŸŽ‰
Back
NestJs
41-Task Scheduling

1. Task Scheduling

μž‘μ—… μŠ€μΌ€μ€„λ§(Task Scheduling)은 컴퓨터 μ‹œμŠ€ν…œμ—μ„œ μž‘μ—…μ΄λ‚˜ ν”„λ‘œμ„ΈμŠ€λ₯Ό 효율적으둜 κ΄€λ¦¬ν•˜κ³  μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ μž‘μ—…μ˜ μˆœμ„œμ™€ 타이밍을 κ²°μ •ν•˜λŠ” 과정이닀. μž‘μ—… μŠ€μΌ€μ€„λ§μ€ 운영 체제, λ°μ΄ν„°λ² μ΄μŠ€ 관리 μ‹œμŠ€ν…œ, λΆ„μ‚° μ‹œμŠ€ν…œ λ“± λ‹€μ–‘ν•œ λΆ„μ•Όμ—μ„œ μ€‘μš”ν•œ 역할을 ν•œλ‹€.

1.1 μž‘μ—… μŠ€μΌ€μ€„λ§μ˜ μ£Όμš” λͺ©ν‘œ

  • νš¨μœ¨μ„± : μ‹œμŠ€ν…œ μžμ›μ„ μ΅œλŒ€ν•œ ν™œμš©ν•˜μ—¬ μž‘μ—…μ„ 효율적으둜 μ²˜λ¦¬ν•œλ‹€.
  • 응닡 μ‹œκ°„ μ΅œμ†Œν™” : μž‘μ—…μ˜ 응닡 μ‹œκ°„μ„ μ΅œμ†Œν™”ν•˜μ—¬ μ‚¬μš©μž κ²½ν—˜μ„ ν–₯μƒμ‹œν‚¨λ‹€.
  • 곡정성 : λͺ¨λ“  μž‘μ—…μ΄ κ³΅μ •ν•˜κ²Œ μžμ›μ„ 할당받을 수 μžˆλ„λ‘ ν•œλ‹€.
  • μš°μ„ μˆœμœ„ 관리 : μ€‘μš”ν•œ μž‘μ—…μ΄ μš°μ„ μ μœΌλ‘œ 처리될 수 μžˆλ„λ‘ μš°μ„ μˆœμœ„λ₯Ό κ΄€λ¦¬ν•œλ‹€.

1.2 μž‘μ—… μŠ€μΌ€μ€„λ§μ˜ μœ ν˜•

  1. μ„ μ ν˜• μŠ€μΌ€μ€„λ§(Preemptive Scheduling)
    • μž‘μ—…μ΄ μ‹€ν–‰ 쀑일 λ•Œ, 더 높은 μš°μ„ μˆœμœ„μ˜ μž‘μ—…μ΄ λ„μ°©ν•˜λ©΄ ν˜„μž¬ μž‘μ—…μ„ μ€‘λ‹¨ν•˜κ³  μƒˆλ‘œμš΄ μž‘μ—…μ„ μ‹€ν–‰ν•œλ‹€.
    • e.g. λΌμš΄λ“œ 둜빈(Round Robin), μš°μ„ μˆœμœ„ μŠ€μΌ€μ€„λ§(Priority Scheduling)
  2. λΉ„μ„ μ ν˜• μŠ€μΌ€μ€„λ§(Non-preemptive Scheduling)
    • μž‘μ—…μ΄ 싀행을 μ‹œμž‘ν•˜λ©΄, μž‘μ—…μ΄ μ™„λ£Œλ  λ•ŒκΉŒμ§€ λ‹€λ₯Έ μž‘μ—…μ΄ μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.
    • e.g. FCFS(First-Come, First-Served), SJF(Shortest Job First)

1.3 μž‘μ—… μŠ€μΌ€μ€„λ§ μ•Œκ³ λ¦¬μ¦˜

  • FCFS (First-Come, First-Served) : λ¨Όμ € λ„μ°©ν•œ μž‘μ—…μ„ λ¨Όμ € μ²˜λ¦¬ν•œλ‹€.
  • SJF (Shortest Job First) : μ‹€ν–‰ μ‹œκ°„μ΄ κ°€μž₯ 짧은 μž‘μ—…μ„ λ¨Όμ € μ²˜λ¦¬ν•œλ‹€.
  • Round Robin : 각 μž‘μ—…μ„ 일정 μ‹œκ°„ λ™μ•ˆ λ²ˆκ°ˆμ•„ κ°€λ©° μ²˜λ¦¬ν•œλ‹€.
  • Priority Scheduling : μš°μ„ μˆœμœ„κ°€ 높은 μž‘μ—…μ„ λ¨Όμ € μ²˜λ¦¬ν•œλ‹€.
  • Multilevel Queue Scheduling : μž‘μ—…μ„ μ—¬λŸ¬ 개의 큐둜 λ‚˜λˆ„μ–΄ 각 큐에 λ‹€λ₯Έ μŠ€μΌ€μ€„λ§ μ•Œκ³ λ¦¬μ¦˜μ„ μ μš©ν•œλ‹€.

1.1 Task Scheduling의 μš©λ„

  • 메일링 λ¦¬μŠ€νŠΈμ— μΆ”μ²œ μ˜ν™” 리슀트λ₯Ό 주기적으둜 λ³΄λ‚΄μ€„λ•Œ.
  • 총 μ’‹μ•„μš” κ°―μˆ˜λ‚˜ 총 쑰회수처럼 νŠΉμ • 데이터λ₯Ό 주기적으둜 μ—…λ°μ΄νŠΈν• λ•Œ
  • 주기적으둜 λ°μ΄ν„°λ‚˜ νŒŒμΌμ„ μ •λ¦¬ν• λ•Œ
  • 주기적으둜 데이터 뢄석 리포트λ₯Ό μ œμž‘ν• λ•Œ
  • 주기적으둜 λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό λ°±μ—…ν• λ•Œ

2. Cron 문법

  • 초 0-59 : 0μ΄ˆλΆ€ν„° 59μ΄ˆκΉŒμ§€μ˜ 숫자λ₯Ό μž…λ ₯ν•œλ‹€
  • λΆ„ 0-59 : 0λΆ„λΆ€ν„° 59λΆ„κΉŒμ§€μ˜ 숫자λ₯Ό μž…λ ₯ν•œλ‹€
  • μ‹œ 0-23 : 0μ‹œλΆ€ν„° 23μ‹œκΉŒμ§€μ˜ 숫자λ₯Ό μž…λ ₯ν•œλ‹€
  • 일 1-31 : 1일뢀터 31μΌκΉŒμ§€μ˜ 숫자λ₯Ό μž…λ ₯ν•œλ‹€
  • μ›” 1-12 : 1μ›”λΆ€ν„° 12μ›”κΉŒμ§€μ˜ 숫자λ₯Ό μž…λ ₯ν•œλ‹€
  • μš”μΌ 0-7 : 0λΆ€ν„° 7κΉŒμ§€μ˜ μˆ«μžκ°€ 각 [일,μ›”,ν™”,수,λͺ©,금,ν† ,일]에 ν•΄λ‹Ήλœλ‹€. μΌμš”μΌμ€ λ‘λ²ˆ μžˆλ‹€
1
* * * * * * μ‹€ν–‰ν•  μ»€λ§¨λ“œ
2
- - - - - -
3
| | | | | |
4
| | | | | +-- μš”μΌ (0 - 7) (μΌμš”μΌμ€ 0κ³Ό 7이 λͺ¨λ‘ κ°€λŠ₯)
5
| | | | +---- μ›” (1 - 12)
6
| | | +------ 일 (1 - 31)
7
| | +-------- μ‹œ (0 - 23)
8
| +---------- λΆ„ (0 - 59)
9
+------------ 초 (0 - 59)
  • *[별] : ν•„λ“œμ˜ λͺ¨λ“  값을 λ§€μΉ­ν•œλ‹€. (e.g. 1μ΄ˆλ§ˆλ‹€ μ‹€ν–‰)
  • , [컴마] : μ—¬λŸ¬κ°œμ˜ 값을 κ΅¬λΆ„ν•œλ‹€. (e.g. β€˜μΌβ€™ μœ„μΉ˜μ— 1,2,3 μž…λ ₯ β†’ 1일, 2일, 3일에 μ‹€ν–‰)
  • -[ν•˜μ΄ν”ˆ] : λ²”μœ„λ₯Ό ν‘œν˜„ν•œλ‹€. (e.g. β€˜μš”μΌβ€™ μœ„μΉ˜μ— 1-3 μž…λ ₯β†’ μ›”μš”μΌλΆ€ν„° μˆ˜μš”μΌμ— ν•΄λ‹Ήλ λ•Œ)
  • / [μŠ¬λž˜μ‹œ] : 배수λ₯Ό ν‘œν˜„ν•œλ‹€. (e.g. β€˜λΆ„β€™ μœ„μΉ˜μ— */15 μž…λ ₯ β†’ 15λΆ„λ§ˆλ‹€ μ‹€ν–‰ (0, 15, 30, 45λΆ„)
  • L [μ•ŒνŒŒλ²³ μ—˜] : λ‹¬μ˜ λ§ˆμ§€λ§‰ 날을 μ˜λ―Έν•œλ‹€. (e.g. β€˜μš”μΌβ€™ μœ„μΉ˜μ— 5L μž…λ ₯ β†’ λ‹¬μ˜ λ§ˆμ§€λ§‰ κΈˆμš”μΌ)
  • W [μ•ŒνŒŒλ²³ λ”λΈ”μœ ] : β€˜μΌβ€™ μœ„μΉ˜μ— μž…λ ₯μ‹œ κ°€κΉŒμš΄ 평일 (e.g. β€˜μΌβ€™ μœ„μΉ˜μ— 15W μž…λ ₯ β†’ 15일에 κ°€μž₯ κ°€κΉŒμš΄ 평일)
  • # [μƒΎ] : λͺ‡λ²ˆμ§Έ μš”μΌμΈμ§€ ν‘œν˜„ν•œλ‹€. (e.g. β€˜μš”μΌβ€™ μœ„μΉ˜μ— 5#3 μž…λ ₯ β†’ λ‹¬μ˜ μ„Έλ²ˆμ§Έ κΈˆμš”μΌ)

2.1 Cron 예제

1
# 0μ΄ˆλ§ˆλ‹€ μ‹€ν–‰(1뢄에 ν•œλ²ˆ μ‹€ν–‰)
2
0 * * * * *
3
4
# μ •ν™•νžˆ μžμ •μ— μ‹€ν–‰ (0초 0λΆ„ 0μ‹œ)
5
0 0 0 * * *
6
7
# μΌμš”μΌ 3μ‹œ 0λΆ„ 30μ΄ˆμ— μ‹€ν–‰ (μΌμš”μΌ 3:00:30AM)
8
30 0 3 * * 0
9
10
# λ§€μ›” λ§ˆμ§€λ§‰ λ‚  5μ‹œ 30λΆ„ 45μ΄ˆμ— μ‹€ν–‰ (λ§€μ›” λ§ˆμ§€λ§‰ λ‚  5:30:45PM)
11
45 30 17 L * *
12
13
# μ›”,수,금 10μ‹œ15뢄에 μ‹€ν–‰ (μ›”,수,금 10:15:00AM)
14
0 15 10 * * 1,3,5
15
16
# 0초 5λΆ„λ§ˆλ‹€ μ‹€ν–‰ (5λΆ„λ§ˆλ‹€ μ‹€ν–‰, μ‹œ 정각에 μ‹œμž‘)
17
0 */5 * * * *
18
19
# 8μ‹œμ™€ 20μ‹œ 사이에 2μ‹œκ°„λ§ˆλ‹€ μ‹€ν–‰
20
0 0 8-20/2 * * *
21
22
# λ§€μ›” λ§ˆμ§€λ§‰ κΈˆμš”μΌ 11:00:00PM에 μ‹€ν–‰
23
0 0 23 * * 5L
24
25
# 1μ΄ˆλ§ˆλ‹€ μ‹€ν–‰
26
* * * * * *
27
28
# 30μ΄ˆλ§ˆλ‹€ μ‹€ν–‰
29
*/30 * * * * *

3. NestJS Schedule μ„ μ–Έν˜•

1
import { Injectable, Logger } from '@nestjs/common'
2
import { Cron } from '@nestjs/schedule'
3
4
@Injectable()
5
export class TaskService {
6
private readonly logger = new Logger(TaskService.name)
7
8
@Cron('45 * * * * *')
9
handleCron() {
10
this.logger.debug('Called when the current second is 45')
11
}
12
}

4. NestJS Schedule μ˜΅μ…˜

1
import { Injectable } from '@nestjs/common'
2
import { Cron, CronExpression } from '@nestjs/schedule'
3
4
@Injectable()
5
export class NotificationService {
6
@Cron('* * 0 * * *', {
7
name: 'notifications',
8
timeZone: 'Europe/Paris',
9
})
10
triggerNotification() {}
11
}

5. SchedulerRegistry ν•¨μˆ˜

1
addCronJob(name: string, seconds: string) {
2
const job = new CronJob(`${seconds} * * * * *`, () => {
3
this.logger.warn(`time (${seconds}) for job ${name} to run!`)
4
})
5
6
this.schedulerRegistry.addCronJob(name, job)
7
job.start()
8
9
this.logger.warn(
10
`job ${name} added for each minute at ${seconds} seconds`,
11
)
12
}
13
  • stop() : μ˜ˆμ •λœ μž‘μ—…μ„ μ€‘μ§€ν•œλ‹€.
  • start() : stop()이 μ‹€ν–‰λœ μž‘μ—…μ„ μž¬μ‹€ν–‰ν•œλ‹€.
  • setTime(time: CronTime) : μž‘μ—…μ„ μ€‘μ§€ν•˜κ³  μƒˆλ‘œμš΄ μ£ΌκΈ°λ₯Ό μ§€μ •ν•˜κ³  μ‹œμž‘ν•œλ‹€.
  • lastDate() : λ§ˆμ§€λ§‰μœΌλ‘œ μž‘μ—…μ΄ μ‹€ν–‰λœ λ‚ μ§œλ₯Ό λ°˜ν™˜ν•œλ‹€.
  • nextDate() : λ‹€μŒμœΌλ‘œ μž‘μ—…μ΄ 싀행될 λ‚ μ§œλ₯Ό λ°˜ν™˜ν•œλ‹€.
  • nextDates(count: number) : λ‹€μŒμœΌλ‘œ μž‘μ—…μ΄ 싀행될 λ‚ μ§œλ“€μ„ n개 λ°˜ν™˜ν•œλ‹€

6. Versioning

  • URL Versioning : URI에 버전이 μ „λ‹¬λœλ‹€ /v1/movie
  • Header Versioning Header에 버전이 μ „λ‹¬λœλ‹€ version: 1
  • Media Type Versioning : Header의 Accept 킀에 버전이 μ „λ‹¬λœλ‹€. Accept: application/json;v=2