Docker를 사용하여 예약된 시간에 따라 상품의 재고 정보를 자동으로 확인하고 알림을 주는 툴을 구축하였습니다. Python 스크립트는 http_request_stock.py로 명명되며, redis와 APScheduler를 사용하여 예약 시작 10분 전과 예약 종료 시에 상품 재고 정보를 로그로 출력합니다.
Dockerfile 구성
Dockerfile은 Python 환경을 구축하고 필요한 의존성을 설치하는 데 사용됩니다. 또한, 작성한 Python 스크립트를 컨테이너 내부에 복사하고 실행합니다.
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "-u", "./http_request_stock.py"]
이 Dockerfile은 Python 3.9 slim 이미지를 기반으로 하며, 필요한 Python 패키지를 requirements.txt를 통해 설치합니다. 마지막으로, -u 옵션을 사용하여 http_request_stock.py 스크립트를 실행하여 stdout과 stderr를 플러시합니다.
Python 스크립트 (http_request_stock.py)
http_request_stock.py 스크립트는 redis, APScheduler, pytz 라이브러리를 사용하여 예약된 시간에 따라 상품의 재고 정보를 확인하고 로그로 출력합니다.
from datetime import datetime, timedelta
import pytz
from apscheduler.schedulers.background import BackgroundScheduler
import redis
import time
import logging
logging.basicConfig()
logging.getLogger('apscheduler').setLevel(logging.DEBUG)
# Redis 연결 설정
redis_client = redis.Redis(host='host.docker.internal', port=6379, db=0)
# Asia/Seoul 시간대 설정
seoul_timezone = pytz.timezone('Asia/Seoul')
# 전역 변수로 scheduler 선언, 시간대를 Asia/Seoul로 설정
scheduler = BackgroundScheduler(timezone=seoul_timezone)
def notify_stock(event_type, item_id):
# 현재 시간을 Asia/Seoul 기준으로 출력 (단지 로깅 목적)
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
stock_quantity = redis_client.hget(f"item:{item_id}", "stockQuantity").decode('utf-8')
print(f"[{current_time}] {event_type} - Item ID: {item_id}, Stock Quantity: {stock_quantity}")
def list_initial_stock():
print("Listing all items and their initial stock quantities:")
for key in redis_client.scan_iter("item:*"):
item_id = key.decode().split(":")[1]
stock_quantity = redis_client.hget(key, "stockQuantity").decode('utf-8')
print(f"Item ID: {item_id}, Initial Stock Quantity: {stock_quantity}")
def schedule_stock_checks():
global scheduler
scheduler.start()
for key in redis_client.scan_iter("item:*"):
item_id = key.decode().split(":")[1]
item_info = redis_client.hgetall(key)
if b'reservationStart' in item_info and b'reservationEnd' in item_info:
reservation_start_str = item_info[b'reservationStart'].decode()
reservation_end_str = item_info[b'reservationEnd'].decode()
# 문자열을 datetime 객체로 변환 (시간대 변환 없이 직접 사용)
reservation_start = datetime.strptime(reservation_start_str, '%Y-%m-%dT%H:%M:%S')
reservation_end = datetime.strptime(reservation_end_str, '%Y-%m-%dT%H:%M:%S')
# 예약 시작 10분 전 계산
start_check_time = reservation_start - timedelta(minutes=10)
# 예약 종료 시간에 대한 처리도 포함
end_check_time = reservation_end
# 스케줄러에 작업 추가 (시간대 변환 없이 직접 사용)
scheduler.add_job(notify_stock, 'date', run_date=start_check_time, args=["Reservation Start", item_id], misfire_grace_time=300) # 5분의 유예 시간
scheduler.add_job(notify_stock, 'date', run_date=end_check_time, args=["Reservation End", item_id], misfire_grace_time=300)
if __name__ == "__main__":
list_initial_stock()
schedule_stock_checks()
try:
while True:
time.sleep(1)
except (KeyboardInterrupt, SystemExit):
scheduler.shutdown()
이 스크립트는 Redis에서 상품 정보를 조회하고, 예약 시작 10분 전과 예약 종료 시에 상품 재고 정보를 출력합니다. BackgroundScheduler를 사용하여 예약된 작업을 비동기적으로 실행합니다.
requirements.txt
requirements.txt 파일에는 스크립트 실행에 필요한 Python 패키지 목록이 포함됩니다.
# requirements.txt
redis
APScheduler
pytz
실행 방법
1. Docker 이미지 빌드
docker build -t http_request_stock .
docker run http_request_stock
이 도구를 사용하여 예약된 시간에 상품의 재고 정보를 자동으로 확인할 수 있습니다. 예약 시간에 따라 상품의 판매 가능 여부를 관리하는 시스템에 유용하게 활용할 수 있습니다.
'프로젝트 (Java) > 예약마켓' 카테고리의 다른 글
[프로젝트] 54. 실시간 재고 관리를 위해 주문 로직 리팩토링 (0) | 2024.02.20 |
---|---|
[프로젝트] 53. Redis를 활용한 실시간 재고 관리 서비스 (0) | 2024.02.20 |
[프로젝트] 51. Docker 활용 주문 API 자동화 툴 구축 (1) | 2024.02.20 |
[프로젝트] 50. Redis를 사용하여 상품 재고 정보 저장 (0) | 2024.02.20 |
[프로젝트] 49. Docker 활용 자동화 테스트 툴 구축 (0) | 2024.02.13 |