Skip to content

[Queue WAS] 큐 스케줄링#57

Merged
viixix merged 7 commits intodevfrom
queue-backend-25
Jan 19, 2026
Merged

[Queue WAS] 큐 스케줄링#57
viixix merged 7 commits intodevfrom
queue-backend-25

Conversation

@viixix
Copy link
Copy Markdown
Collaborator

@viixix viixix commented Jan 15, 2026

🧭 Summary

  • 대기열의 유저를 활성 큐로 이동시키기 위한 스케줄링 시스템(Trigger, Worker)을 구축했습니다. 원자적 처리를 위해 redis lua 스크립트를 도입하였습니다.
  • Cron(1분) + Pub/Sub(작업 완료 이벤트)로 트리거하여 자동 입장(큐 스케줄링)이 동작하도록 구성했습니다.
  • 이동 로직은 활성 큐 최대 수용량(MAX_CAPACITY)을 기준으로 원자적으로 처리되며, 이동된 유저는 활성 상태(5분)를 redis에 함께 기록합니다.

🔗 Linked Issue

🛠 개발 기능(작업 내용)

  • Redis Lua 스크립트 (transferUser) 도입: 대기열 조회, 인원 계산, 이관 작업을 하나의 원자적 단위로 묶었습니다. (동시성 문제 해결, 네트워크 왕복 감소)
    • 활성 큐 인원수(ZCARD) 기준으로 입장 가능 수(available) 계산
    • 대기 큐에서 오래 기다린 순서대로(ZPOPMIN) 가능한 만큼 pop 후 활성 큐로 이동(ZADD)
    • 유저별 활성 상태를 status:active:{userId}로 TTL 300초(5분) 저장
    • 이동된 유저 ID 리스트 반환
  • QueueWorker 구현: Lua 스크립트를 호출하여 실질적인 유저 이관 작업을 수행하는 Task 로직을 작성했습니다.
  • QueueTrigger 구현: 워커의 실행 주기(Interval)를 관리하며, 시스템 설정에 따라 스케줄링을 제어하는 트리거 메커니즘을 구축했습니다.
  • MAX_CAPACITY로 동적으로 활성 큐 사이즈를 조절할 수 있게 하였고, 실행 주기를 포함하여 추후 환경 변수와 연동하거나 redis 자체에 저장하는 방식도 고려중입니다.
  • 단위 테스트 (spec.ts): 모킹을 통해 트리거의 호출 주기와 워커의 커스텀 명령어 실행 여부를 검증하는 테스트 코드를 추가했습니다.

🧩 주요 고민과 해결 방법

  • 동시성 제어 및 레이스 컨디션: 여러 서버 인스턴스에서 동시에 워커가 돌아갈 때나 여러 명령어 실행을 할 때에 도중에 다른 클라이언트의 명령어가 끼어들면 생기는 문제를 고민했습니다.
    • 해결: zcard, zpopmin, zadd 로직을 별도의 애플리케이션 단계가 아닌 Redis 내부 Lua 스크립트에서 실행하게 하여 원자성을 확보했습니다.
  • 트리거와 워커의 역할 분리: "언제 실행하는가"와 "무엇을 실행하는가"가 섞일 경우 유지보수가 어려워질 수 있다고 판단했습니다.
    • 해결: QueueTrigger는 스케줄링 정책에만 집중하고, QueueWorker는 Redis 작업에만 집중하도록 구조를 명확히 분리했습니다.

🔍 리뷰 포인트

redis.commands.ts의 Lua 스크립트 로직을 봐주세요 (이해를 돕기 위한 주석을 달았습니다)

queue.trigger.ts(언제 실행하는가)와 queue.worker.ts(무엇을 실행하는가)를 중점으로 봐주세요.

- Redis Lua 스크립트로 대기열에서 활성 큐로 유저 이동 로직 구현
- 사용자 이동을 처리하는 TRANSFER_USER 명령어 정의 및 설정
- Redis 모듈에서 해당 명령어를 정의하여 사용 가능하도록 설정
- MAX_CAPACITY 기반으로 활성 큐 최대 인원 조절 가능하도록 구현
- `QueueWorker`: 대기 유저를 활성 큐로 이동시키는 구체적인 작업(Task) 로직 구현
- `QueueTrigge`: 워커의 실행 시점 및 스케줄링 주기(Interval) 관리 로직 구현
- 단위 테스트 추가: 스케줄링 주기 준수 여부 및 워커의 작업 수행 결과에 대한 spec.ts 작성
@viixix viixix self-assigned this Jan 15, 2026
@viixix viixix marked this pull request as ready for review January 15, 2026 00:55
Copy link
Copy Markdown
Collaborator

@shininghyunho shininghyunho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lua 스크립트 처음봤는데 저렇게 생겼군요. 트리거 - 워커 로직 잘봤습니다.
수고하셨습니다.

});
}

@Cron(CronExpression.EVERY_SECOND)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에는 환경변수 파일로 뺄수도 있을거같네요!

Copy link
Copy Markdown
Collaborator

@ParkTjgus ParkTjgus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다! 수고하셨습니다

viixix and others added 3 commits January 19, 2026 18:15
- `QueueTrigger`: 메시지 수신 시 활성 유저 제거 및 오류 로깅 기능 추가
- `QueueWorker`: 활성 큐 처리 스로틀링 로직 및 활성 유저 제거 메서드 구현
- `QueueTrigger`: 크론 표현식을 매 분으로 수정하여 큐 전송 처리 주기 조정
@viixix viixix merged commit f86a46a into dev Jan 19, 2026
1 check passed
@viixix viixix changed the title [BE] 대기열 WAS: 큐 스케줄링 [Queue WAS] 큐 스케줄링 Jan 21, 2026
@viixix viixix deleted the queue-backend-25 branch January 22, 2026 05:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants