Docker, Flask, Docker Compose를 이용한 Flask 웹 앱 Docker화 후 발생하는 "Periodic 'Lost connection to MySQL server during query'" 문제 해결

2024-04-02

Docker, Flask, Docker Compose를 이용한 Flask 웹 앱 Docker화 후 발생하는 "Periodic 'Lost connection to MySQL server during query'" 문제 해결

문제 설명

해결 방법

MySQL 서버 설정 파일 /etc/mysql/my.cnf를 편집하여 다음 설정을 변경합니다.

  • wait_timeout: MySQL 서버가 클라이언트 연결 응답을 기다리는 시간을 설정합니다. 이 값을 늘려서 연결 끊김 문제를 해결할 수 있습니다.
  • max_allowed_packet: MySQL 서버가 허용하는 최대 패킷 크기를 설정합니다. 앱에서 사용하는 쿼리가 큰 경우 이 값을 늘려야 합니다.

docker-compose.yml 파일을 편집하여 다음 설정을 변경합니다.

  • depends_on: mysql 서비스가 web 서비스 시작 전에 시작되도록 설정합니다.
  • restart: web 서비스를 always 모드로 설정하여 연결 끊김 발생 시 자동으로 재시작되도록 합니다.

Python 코드 변경

app.py 파일을 편집하여 다음 코드를 추가합니다.

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine("mysql+pymysql://user:password@localhost:3306/database")
Session = sessionmaker(bind=engine)

def get_session():
    return Session()

@app.route("/")
def index():
    session = get_session()
    # ...

위 코드는 SQLAlchemy를 사용하여 MySQL 연결을 관리합니다. get_session() 함수를 사용하여 모든 요청에 대해 새 연결을 생성하고, 사용 후 닫습니다.

네트워크 설정 확인

Docker 컨테이너 간 네트워크 연결 문제로 인해 오류가 발생할 수 있습니다. 다음 사항을 확인합니다.

  • docker-compose.yml 파일에서 네트워크 설정이 올바른지 확인합니다.
  • 컨테이너 간 연결이 제대로 설정되었는지 확인합니다.

기타 해결 방법

  • MySQL 서버 버전을 업데이트합니다.
  • Python 라이브러리 버전을 업데이트합니다.
  • Docker 이미지 버전을 업데이트합니다.



예제 코드

app.py

from flask import Flask, render_template

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

app = Flask(__name__)

engine = create_engine("mysql+pymysql://user:password@localhost:3306/database")
Session = sessionmaker(bind=engine)

@app.route("/")
def index():
    session = Session()
    users = session.query(User).all()
    return render_template("index.html", users=users)

if __name__ == "__main__":
    app.run(debug=True)

index.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Flask Web App</title>
</head>
<body>
    <h1>사용자 목록</h1>
    <ul>
        {% for user in users %}
        <li>{{ user.name }}</li>
        {% endfor %}
    </ul>
</body>
</html>

docker-compose.yml

version: "3"

services:
  web:
    build: .
    volumes:
      - .:/app
    ports:
      - "5000:5000"
  mysql:
    image: "mysql:5.7"
    environment:
      MYSQL_ROOT_PASSWORD: "password"
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306"

volumes:
  db_data:

사용 방법

  1. docker-compose up -d 명령을 실행하여 컨테이너를 실행합니다.
  2. 웹 브라우저에서 http://localhost:5000 주소를 열면 사용자 목록 페이지가 표시됩니다.

참고

  • 이 예시는 기본적인 기능만 구현합니다. 실제 프로젝트에서는 보안, 에러 처리 등을 추가적으로 고려해야 합니다.
  • Docker, Flask, Docker Compose, MySQL에 대한 더 자세한 정보는 각 공식 문서를 참고하시기 바랍니다.



"Lost connection to MySQL server during query" 문제 해결을 위한 대체 방법

연결 풀은 데이터베이스 연결을 관리하는 데 도움이 되는 라이브러리입니다. 연결 풀을 사용하면 모든 요청에 대해 새 연결을 생성하는 대신 풀에서 사용 가능한 연결을 가져와 사용할 수 있습니다. 이렇게 하면 연결 오버헤드를 줄이고 성능을 향상시킬 수 있습니다.

비동기 쿼리 실행을 사용하면 쿼리가 실행되는 동안 다른 작업을 수행할 수 있습니다. 이렇게 하면 웹 앱 응답 속도를 향상시킬 수 있습니다.

데이터베이스 캐싱을 사용하면 자주 사용되는 데이터를 메모리에 저장하여 데이터베이스 쿼리 횟수를 줄일 수 있습니다. 이렇게 하면 웹 앱 성능을 향상시킬 수 있습니다.

데이터베이스 스키마를 최적화하면 쿼리 실행 속도를 향상시킬 수 있습니다. 적절한 색인을 사용하고 테이블 구조를 최적화하는 것이 중요합니다.

데이터베이스 서버 하드웨어를 업그레이드하거나 데이터베이스 설정을 조정하여 서버 성능을 향상시킬 수 있습니다.

로깅 및 모니터링

웹 앱과 데이터베이스 서버를 로깅하고 모니터링하여 문제를 빠르게 식별하고 해결할 수 있습니다.


docker flask docker-compose

docker flask compose