[BACK-009][중급] 오래 걸리는 작업을 줄 세워 처리하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[BACK-009][중급] 오래 걸리는 작업을 줄 세워 처리하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 99회 작성일 26-09-04 02:32

본문

[이번 수업]

이미지 변환이나 보고서 생성처럼 오래 걸리는 일을 요청 안에서 끝내지 않고 메시지 큐에 넣어 별도 작업자가 처리하는 흐름을 배웁니다.

[선수지식]

BACK-001의 요청·응답, BACK-002의 HTTP 상태 코드, CS-010의 비동기 처리 개념과 Python 3 실행 방법을 알고 있으면 됩니다.

[학습목표]

1. 생산자·큐·소비자의 역할을 설명한다.
2. 확인 응답과 재시도 때문에 생기는 중복을 다룬다.
3. 비동기 작업의 상태와 실패를 관찰한다.

[핵심개념]

메시지 큐는 처리할 일을 순서대로 잠시 보관하는 완충 공간입니다. 생산자(publisher)는 작업 ID와 종류처럼 작은 메시지를 넣고, 소비자(consumer) 또는 워커(worker)는 메시지를 꺼내 실제 일을 합니다. API는 보통 작업 ID와 `202 Accepted`를 먼저 반환하고 사용자는 상태 조회 API로 진행 상황을 확인합니다. 큐는 순간 요청량을 흡수하지만 처리 능력을 저절로 늘리지는 않습니다.

소비자는 결과를 안전하게 기록한 뒤 확인 응답(acknowledgement, 처리 완료 신호)을 보냅니다. 확인 전에 연결이 끊기면 같은 메시지가 다시 올 수 있으므로 흔한 방식은 최소 한 번 전달입니다. 작업은 같은 ID로 여러 번 실행해도 결과가 한 번 실행한 것과 같도록 멱등성(idempotency)을 갖춰야 합니다. 작업 ID에 고유 제약을 두거나 처리 완료 기록을 먼저 확인하는 방법이 있습니다.

일시 오류는 간격을 늘리고 작은 무작위 지연을 더해 제한된 횟수만 재시도합니다. 계속 실패하는 메시지는 별도 실패 큐로 보내 조사합니다. 여러 소비자와 재전달이 있으면 완료 순서는 달라질 수 있습니다. 큐 길이뿐 아니라 가장 오래 기다린 시간, 처리 시간, 실패·재시도 수를 함께 관찰합니다.

[따라하기]

아래를 `queue_demo.py`로 저장합니다. Python 표준 라이브러리만 사용하며, 실제 메시지 브로커가 아니라 한 프로세스 안에서 구조를 연습하는 예제입니다.

```python
from queue import Queue
from threading import Thread
from time import sleep

jobs = Queue()

def worker():
    while True:
        job_id = jobs.get()
        try:
            print(f"처리 시작: {job_id}")
            sleep(0.2)
            print(f"처리 완료: {job_id}")
        finally:
            jobs.task_done()

for job_id in ("image-101", "report-102", "mail-103"):
    print(f"접수 완료: {job_id}")
    jobs.put(job_id)

Thread(target=worker, daemon=True).start()
jobs.join()
print("모든 작업 완료")
```

Windows PowerShell에서는 `py queue_demo.py`, macOS·Linux에서는 `python3 queue_demo.py`를 실행합니다. 접수 완료 세 줄 뒤에 각 작업의 시작과 완료가 입력 순서대로 나오고 마지막에 `모든 작업 완료`가 표시됩니다. `join()`은 모든 항목에 `task_done()`이 호출될 때까지 기다립니다.

[흔한 실수]

메시지 본문에 큰 파일을 넣지 말고 접근 권한이 있는 파일 위치와 작업 ID를 넣습니다. 자동 확인을 사용하면 처리 중 장애에서 일이 사라질 수 있습니다. 반대로 실패 메시지를 즉시 무한 재등록하면 장애를 키웁니다. 큐의 입력 순서가 항상 완료 순서라고 가정하지 않습니다. 데이터 저장과 메시지 발행을 함께 보장해야 할 때는 트랜잭션 아웃박스 같은 설계를 검토합니다.

[보안 주의]

예제는 본인 소유 로컬 환경에서만 실행합니다. 실제 브로커는 외부에 공개하지 말고 인증, TLS, 최소 권한 계정과 큐별 접근 제어를 적용합니다. 메시지에 비밀번호·토큰·개인정보를 직접 넣지 않으며 스키마, 크기, 작업 종류를 소비자에서도 검증합니다. 작업 ID를 로그에 남기되 민감한 본문은 기록하지 않습니다.

[직접 해볼 과제]

작업에 `attempt` 값을 추가하고 첫 실패에는 재등록하되 두 번째 실패에는 `실패 보관`을 출력하세요. 같은 작업 ID의 완료 기록이 있으면 건너뛰도록 집합을 사용해 중복 처리도 막아 봅니다.

[확인문제]

1. API가 오래 걸리는 일을 큐에 넣고 먼저 응답하면 어떤 장점이 있나요?
2. 확인 전 연결이 끊긴 작업에 멱등성이 필요한 이유는 무엇인가요?
3. 큐 길이 외에 관찰해야 할 지표 두 가지는 무엇인가요?

[다음 학습]

DB-009에서 메모리에 데이터를 두는 저장소와 캐시·만료 방식을 배웁니다.

[공식 참고 자료]

RabbitMQ Queues
https://www.rabbitmq.com/docs/queues

RabbitMQ Consumer Acknowledgements and Publisher Confirms
https://www.rabbitmq.com/docs/confirms

RabbitMQ Reliability Guide
https://www.rabbitmq.com/docs/reliability

Python queue 공식 문서
https://docs.python.org/3/library/queue.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
4,049
어제
6,862
최대
16,772
전체
770,000
Copyright © 소유하신 도메인. All rights reserved.