티스토리 뷰

목차



    Docker & Python Logo

     

    이 글에서는 Python 데몬 프로그램을 만들어 매일 아침 6시에 MySQL 쿼리를 실행하고, 이 데몬이 예기치 않게 종료되더라도 자동으로 다시 실행되도록 구성하는 방법을 설명합니다. 이 방법은 Docker를 활용하여 서비스가 지속적으로 실행될 수 있도록 보장하는 방식입니다.

    요구 사항

    • 목표: 매일 아침 6시에 MySQL 데이터베이스에서 SELECT COUNT(1) FROM test 쿼리문을 실행하는 Python 데몬 프로그램을 만들고, Docker로 구성하여 예기치 않은 종료 시에도 자동으로 다시 시작되도록 설정합니다.
    • DB 서버 IP: 192.168.101.101
    • DB 사용자 정보: ID: mct, Password: passwd
    • DB 스키마: mydb

    1. Python 데몬 프로그램 작성

    먼저, Python을 이용해 MySQL에 연결하고, 매일 아침 6시에 지정된 쿼리를 실행하는 데몬을 작성합니다. 이를 위해 schedule 라이브러리를 사용하여 작업을 예약하고, MySQL 쿼리를 실행하는 코드를 작성합니다.

    count_rows.py 작성

    import mysql.connector
    import schedule
    import time
    from mysql.connector import Error
    
    # MySQL에 연결하기 위한 설정
    db_config = {
        'user': 'mct',
        'password': 'passwd',
        'host': '192.168.101.101',
        'database': 'mydb',
    }
    
    def log_message(message):
        """상태를 콘솔에 출력하는 함수."""
        print(f"[INFO] {time.strftime('%Y-%m-%d %H:%M:%S')} - {message}", flush=True)
    
    def count_rows():
        connection = None
        try:
            log_message("Attempting to connect to MySQL...")
            connection = mysql.connector.connect(**db_config)
            
            if connection.is_connected():
                log_message("Successfully connected to MySQL")
                cursor = connection.cursor()
    
                # 테이블의 row 수를 확인하는 SQL 쿼리 실행
                log_message("Executing query: SELECT COUNT(1) FROM test")
                cursor.execute("SELECT COUNT(1) FROM test")
                row_count = cursor.fetchone()[0]
    
                log_message(f"Row count: {row_count}")
            else:
                log_message("Failed to connect to MySQL")
    
        except Error as err:
            log_message(f"Error while connecting to MySQL: {err}")
            time.sleep(5)
            count_rows()
    
        finally:
            if connection and connection.is_connected():
                log_message("Closing MySQL connection")
                cursor.close()
                connection.close()
    
    # 매일 아침 6시에 쿼리를 실행하는 작업 예약
    schedule.every().day.at("06:00").do(count_rows)
    
    if __name__ == "__main__":
        log_message("Starting scheduled task")
        while True:
            try:
                schedule.run_pending()
            except Exception as e:
                log_message(f"An error occurred in the main loop: {e}")
            time.sleep(60)

    Python 코드 설명:

    • schedule 라이브러리를 사용하여 매일 아침 6시에 count_rows 함수를 실행하도록 예약합니다.
    • count_rows 함수는 MySQL 데이터베이스에 연결하여 SELECT COUNT(1) FROM test 쿼리를 실행하고, 결과를 출력합니다.
    • MySQL 연결이 실패할 경우 5초 후 재시도하도록 설정하였습니다.
    • 메인 루프에서 발생할 수 있는 예외를 처리하여 프로그램이 중단되지 않도록 합니다.

    2. Dockerfile 작성

    이 Python 데몬 프로그램을 Docker로 실행할 수 있도록 Dockerfile을 작성합니다.

    Dockerfile

    # Python 3.9 slim 베이스 이미지 사용
    FROM python:3.9-slim
    
    # 작업 디렉토리 설정
    WORKDIR /app
    
    # Python 프로그램 복사
    COPY count_rows.py .
    
    # MySQL 커넥터 및 스케줄러 라이브러리 설치
    RUN pip install mysql-connector-python schedule
    
    # Python 스크립트 실행
    CMD ["python", "count_rows.py"]

    Dockerfile 설명:

    • Python 3.9 slim 이미지를 기반으로 MySQL 커넥터와 스케줄 라이브러리를 설치합니다.
    • count_rows.py 파일을 컨테이너 내부로 복사하고, 컨테이너가 실행될 때 자동으로 Python 스크립트가 실행됩니다.

    3. Docker Compose 설정

    Docker Compose를 사용하여 Python 데몬 컨테이너를 관리하며, 컨테이너가 예기치 않게 종료되었을 때 자동으로 재시작되도록 설정합니다.

    docker-compose.yml

    version: '3.8'
    
    services:
      python-daemon:
        build: .
        restart: always  # 컨테이너가 종료되더라도 항상 재시작
        networks:
          - python-network
    
    networks:
      python-network:
        driver: bridge

    Docker Compose 설정 설명:

    • restart: always: 컨테이너가 정상적으로 종료되거나 오류로 인해 종료되더라도 자동으로 재시작되도록 설정합니다.
    • 네트워크 설정: bridge 네트워크를 사용하여 컨테이너 간 통신을 보장합니다.

    4. Docker 이미지 빌드 및 실행

    이제 Docker 이미지를 빌드하고, 컨테이너를 실행합니다.

    1. Docker 이미지 빌드
    docker-compose build

    이 명령어는 Dockerfile을 기반으로 Docker 이미지를 빌드합니다.

    1. Docker 컨테이너 실행
    docker-compose up -d

    이 명령어는 백그라운드 모드에서 Python 데몬을 실행하며, 계속해서 실행됩니다.


    5. 컨테이너 상태 및 로그 확인

    1. 컨테이너 상태 확인
    docker-compose ps

    컨테이너가 제대로 실행 중인지 확인할 수 있습니다.

    1. 컨테이너 로그 확인
    docker-compose logs -f python-daemon

    실시간 로그를 통해 Python 데몬이 MySQL 쿼리를 정상적으로 실행하고 있는지 확인할 수 있습니다.


    6. 컨테이너 재시작 정책 확인

    컨테이너가 예기치 않게 종료되었을 때 자동으로 재시작되는지 확인하기 위해 다음 명령어를 사용할 수 있습니다.

    docker inspect --format="{{.HostConfig.RestartPolicy.Name}}" <컨테이너 이름>

    always가 출력되면 재시작 정책이 올바르게 설정된 것입니다.


    7. 컨테이너 중지 및 재시작

    1. 컨테이너 중지
    docker-compose down
    1. 컨테이너 재시작
    docker-compose up -d

    이 명령어로 컨테이너를 중지하거나 다시 실행할 수 있습니다.


    최종 요약

    • Python 프로그램을 작성하여 매일 아침 6시에 MySQL 쿼리를 실행하도록 설정하였습니다.
    • Dockerfile을 작성하여 Python 프로그램을 Docker 컨테이너로 실행할 수 있도록 구성하였습니다.
    • Docker Compose 파일을 통해 컨테이너가 예기치 않게 종료되더라도 자동으로 재시작되도록 설정하였습니다.
    • Docker 이미지를 빌드하고, 연속적인 서비스를 보장하도록 구성하였습니다.

    이 구성을 통해 Python 데몬 프로그램이 항상 실행되며, 예기치 않은 종료 시에도 자동으로 재실행되도록 보장할 수 있습니다.