SWM14-Architect / moview-core-service

모뷰의 백엔드 API 서버
5 stars 0 forks source link

MongoHandler 커넥션 낭비하는지 확인 요청 #53

Open dasd412 opened 1 year ago

dasd412 commented 1 year ago

다음 코드에서 핸들러가 생성될 때마다 MongoClient에서 db 커넥션을 맺고 있습니다. 이는 불필요한 리소스 낭비일 수 있습니다. 특히 로거 만들때마다 커넥션 맺으면 굉장한 낭비가 될 수 있습니다. 해당 핸들러를 싱글톤으로 만들 수 있는지 확인바랍니다.

class MongoHandler(logging.Handler):
    def __init__(self, level=logging.NOTSET,
                 database_name='default', collection_name='collections',
                 capped=True, size=100 * 1024 * 1024, is_collection_drop=False):

        # 부모 생성자 호출
        logging.Handler.__init__(self, level)

        # MongoClient를 만들고, database를 가져 온다.
        self.conn = pymongo.MongoClient(host=EnvironmentLoader.get_param(DB_HOST_PARAM),
                                        port=int(EnvironmentLoader.get_param(DB_PORT_PARAM)),
                                        username=EnvironmentLoader.get_param(DB_USERNAME_PARAM),
                                        password=EnvironmentLoader.get_param(DB_PASSWORD_PARAM))

        self.db = self.conn.get_database(database_name)
ssfic3380 commented 1 year ago

커넥션을 클래스에서 관리하고, logger를 호출할 때마다 그 logger의 이름을 이용해서 커넥션의 collection_name과 db_name을 매번 설정해 주는 식으로 해결할 수도 있을 것 같습니다.

한 명의 User의 호출에 대해서 3개의 커넥션을 만드는 것은 너무 큰 낭비가 맞으니 위처럼 해결하고, 여러 사람이 여러 커넥션을 사용하는 것은 MongoDB의 풀링 기능을 이용하면 될 것 같습니다.

자세한 내용은 좀 더 리서치를 해봐야 할 것 같습니다.

ssfic3380 commented 1 year ago

flask_pymongoflask-mongoengine은 모두 Flask와 MongoDB를 통합하는 확장 패키지지만, 목적과 사용 방식에는 몇 가지 차이점이 있습니다.

flask_pymongo

  1. 저수준 인터페이스: flask_pymongo는 PyMongo 라이브러리를 기반으로 하며, MongoDB에 대한 직접적인 파이썬 API를 제공합니다.
  2. 간단한 통합: Flask 애플리케이션의 설정 파일로 MongoDB 연결을 관리하고, Flask 애플리케이션과 함께 작동하도록 설정합니다.
  3. 직접 쿼리 작성: MongoDB와 작업하기 위해 직접 MongoDB 쿼리 문법을 사용해야 합니다.
  4. 객체 매핑 없음: 데이터베이스 문서를 파이썬 객체로 자동 변환하지 않으므로, 개발자가 직접 처리해야 합니다.

flask-mongoengine

  1. 고수준 인터페이스: flask-mongoengine는 MongoEngine ODM(Object-Document Mapper)을 기반으로 하며, 객체 지향적인 방식으로 MongoDB와 작업할 수 있게 해줍니다.
  2. 객체 지향 프로그래밍 지원: MongoDB 문서를 파이썬 클래스로 표현하고, 클래스 메소드를 사용하여 쿼리를 작성할 수 있습니다.
  3. WTForms 통합: 웹 폼과 MongoDB 문서 간의 쉬운 통합을 지원하며, 유효성 검사도 수행합니다.
  4. 다중 연결 지원: 여러 MongoDB 데이터베이스와 연결할 수 있는 기능을 제공합니다.
  5. 학습 곡선: 객체 지향적인 접근 방식과 ODM의 사용이 익숙하지 않은 경우 학습 곡선이 있을 수 있습니다.

결론

두 확장 패키지 중 어떤 것을 선택할지는 프로젝트의 요구 사항과 개발자의 선호에 따라 결정됩니다.

ssfic3380 commented 1 year ago

flask_pymongo를 사용하여 MongoClient를 관리하면 Flask 애플리케이션과의 통합이 간단해지고, 직접 MongoClient를 관리하는 것보다 여러 가지 편리한 기능을 제공받을 수 있습니다. 아래에 주요 차이점을 정리하겠습니다.

flask_pymongo 사용

  1. 간편한 설정: flask_pymongo는 Flask 애플리케이션의 설정 파일을 통해 MongoDB 연결을 쉽게 구성할 수 있게 해줍니다. 이로써, 별도의 연결 관리 없이 Flask와 함께 원활하게 작동합니다.
  2. 자동 커넥션 풀링: flask_pymongo는 내부적으로 MongoClient 인스턴스를 생성하고 관리하며, 커넥션 풀을 자동으로 처리해줍니다.
  3. Flask 생명주기와 통합: Flask의 요청 및 응답 생명주기와 자동으로 통합되어, 리소스 관리가 단순화됩니다.
  4. 추가적인 유틸리티: 몇몇 추가적인 유틸리티 함수와 헬퍼를 제공하여, 개발 작업을 더 쉽게 만들어 줍니다.

직접 MongoClient 관리

  1. 커스텀 커넥션 관리: 직접 MongoClient를 관리하면 연결, 풀링, 리소스 해제 등을 수동으로 처리해야 합니다. 이로 인해 더 세밀한 제어가 가능하지만, 복잡도가 증가합니다.
  2. 프레임워크 독립적: 직접 관리하는 경우 Flask와 독립적이므로 다른 프레임워크나 애플리케이션으로 이전하기 쉽습니다.
  3. 필요한 기능만 구현: 프로젝트의 특별한 요구 사항을 충족하기 위해 필요한 기능만을 구현할 수 있으므로, 컨트롤이 더욱 유연합니다.

결론

ssfic3380 commented 1 year ago

https://velog.io/@d3fau1t/Flask%EC%97%90%EC%84%9C-MongoDB%EB%A5%BC-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%A9%B4-%EC%A2%8B%EC%9D%84%EC%A7%80-%EA%B3%A0%EB%AF%BC%ED%95%B4%EB%B3%B4%EC%95%98%EC%8A%B5%EB%8B%88%EB%8B%A4#flask-mongoengine

flask_pymongo, flask_mongoengine에 대한 예시가 있는데 flask_mongoengine은 스프링에서 ORM처럼 ODM(Object-Document Mapper)을 기반으로 해서 @Entity처럼 document modeling을 위한 클래스를 추가해야 하는 것으로 보입니다.

ssfic3380 commented 1 year ago

아래 예시를 보면 좀 더 이해가 쉬울 것 같습니다.

flask_pymongo 사용 예시

from flask import Flask
from flask_pymongo import PyMongo

app = Flask(__name__)
app.config['MONGO_URI'] = 'mongodb://localhost:27017/myDatabase'
mongo = PyMongo(app)

@app.route('/add_user')
def add_user():
    users = mongo.db.users
    users.insert_one({'name': 'John', 'age': 30})
    return 'User added.'

@app.route('/get_user')
def get_user():
    users = mongo.db.users
    user = users.find_one({'name': 'John'})
    return f"User: {user['name']} Age: {user['age']}"

flask_mongoengine 사용 예시

from flask import Flask
from flask_mongoengine import MongoEngine

app = Flask(__name__)
app.config['MONGODB_SETTINGS'] = {
    'db': 'myDatabase',
    'host': 'localhost',
    'port': 27017
}
db = MongoEngine(app)

class User(db.Document):
    name = db.StringField()
    age = db.IntField()

@app.route('/add_user')
def add_user():
    user = User(name='John', age=30)
    user.save()
    return 'User added.'

@app.route('/get_user')
def get_user():
    user = User.objects(name='John').first()
    return f"User: {user.name} Age: {user.age}"
ssfic3380 commented 1 year ago

커넥션 풀링 기능이나 MongoClient 관리는 직접 구현하기보다 이미 구현된 기능을 활용하는 것이 훨씬 좋을 것으로 판단해서 flask_pymongo나 flask_mongoengine을 이용해서 MongoClient를 만들어서(flask_pymongo의 mongo = PyMongo(app), flask_mongoengine의 db = MongoEngine(app)) MongoHandler에서도 가져다 쓰고, 그 외에도 DB에 데이터를 저장하는 것과 같이 활용하면 될 것 같습니다.

dasd412 commented 1 year ago

79

에서 언급된 내용 업데이트.

스크린샷 2023-09-05 오전 11 10 13