programing

flask_sqlalchemy 'pool_pre_ping'이 동작하는 경우가 있습니다.

bestcode 2022. 11. 6. 10:33
반응형

flask_sqlalchemy 'pool_pre_ping'이 동작하는 경우가 있습니다.

테스트를 위해 MYSQL(RDS) 파라미터를 다음과 같이 수정합니다.

wait_pairs = 40(기본값은 28800)

max_allowed_module = 1GB(최대 - 작은 패킷으로 인한 문제가 아님을 확인하기 위해)

net_read_module = 10

interactive_interactive 변경 없음

다음 앱을 했는데, 앱은퇴하다.pool_pre_ping 설정False)으로로 두고 I get ( False ) 。

Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: Traceback (most recent call last):
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:   File "/var/www/api_server/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:     context)
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:   File "/var/www/api_server/venv/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 507, in do_execute
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:     cursor.execute(statement, parameters)
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:   File "/var/www/api_server/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 206, in execute
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:     res = self._query(query)
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:   File "/var/www/api_server/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 312, in _query
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:     db.query(q)
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:   File "/var/www/api_server/venv/lib/python3.6/site-packages/MySQLdb/connections.py", line 224, in query
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]:     _mysql.connection.query(self, query)
Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: MySQLdb._exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')

가가 added the the 했습니다.pool_pre_ping (.4.1을 사용하여 사다리다(sqlalchamy 버전 2.4.1을 사용).

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy as _BaseSQLAlchemy


class SQLAlchemy(_BaseSQLAlchemy):
    def apply_pool_defaults(self, app, options):
        super(SQLAlchemy, self).apply_pool_defaults(app, options)
        options["pool_pre_ping"] = True
#        options["pool_recycle"] = 30
#        options["pool_timeout"] = 35

db = SQLAlchemy()


class DevConfig():
    SQLALCHEMY_ENGINE_OPTIONS = {'pool_recycle': 280, 'pool_timeout': 100, 'pool_pre_ping': True} # These configs doesn't get applied in engine configs :/
    DEBUG = True
    # SERVER_NAME = '127.0.0.1:5000'
    SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI_DEV')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

config = dict(
    dev=DevConfig,
)

app = Flask(__name__, instance_relative_config=True)
app.config.from_object(config['dev'])

# INIT DATABASE
db.init_app(app)
with app.app_context():
    db.create_all()

-----------run.py
app.run(host='127.0.0.1', port=5000)

이것으로 MySQL 서버가 이전 연결을 닫은 후에도 웹 앱은 새로운 연결을 얻을 수 있습니다.장시간 오류가 .그러나 접속을 오랫동안 비활성 상태로 유지하면(알 수 없지만 ~ 10~15분), 다시 같은 에러가 표시됩니다.
문서(특히 '절단 처리' 섹션)에 따르면pool_pre_ping옵션은 백그라운드 의례에서 이러한 시나리오를 처리해야 합니까?아니면 MySQL 서버에서 변경해야 할 다른 타임아웃 변수가 있나요?

다음의 설정을 실시합니다.

SQLALCHEMY_ENGINE_OPTIONS = {
    'pool_size': 10,
    'pool_recycle': 60,
    'pool_pre_ping': True
}

지난 몇 달 동안 하락이 멈췄어요

플라스크-SQ에서라케미 설정 문서:

데이터베이스 백엔드에 따라서는 다른 비활성 접속 타임아웃이 발생하여 Flask-SQ를 방해할 수 있습니다.LALchemy의 연결 풀링.

기본적으로는 MariaDB는 600초의 타임아웃을 갖도록 설정되어 있습니다.이것은 디버깅이 어려운 경우가 많습니다.실가동환경은 다음과 같은 예외만 있습니다.

2013: Lost connection to MySQL server during query.

타임아웃이 사전 는, 「」( 「」)를 설정하는 합니다.SQLALCHEMY_POOL_RECYCLE백엔드의 타임아웃보다 작은 값으로 설정합니다.

의 MySQL과 의 불일치를 .syslog-configs(syslog-conwait_timeout,net_read_timeout와 SQL (SQL Chemy) © SQL Chemy )pool_recycle,pool_timeout및 Flask-SQ 및및s-SQ la la la la타임아웃)SQLALCHEMY_POOL_RECYCLE,SQLALCHEMY_POOL_TIMEOUT를 참조해 주세요.

하려면 , 「」를 사용합니다.DevConfighelper-class: DB를 사용합니다.그러기 위해서는 스태틱아트리뷰트에 Configuration을 할당하고 타임아웃에 대한 기대가 경합하지 않도록 이들 Atribut을 참조합니다.을 사용하다

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy as _BaseSQLAlchemy

# Coordinate DevConfig with SQLAlchemy and Flask-SQLAlchemy (don't repeat yourself!)

class DevConfig():
    SQLALCHEMY_POOL_RECYCLE = 35  # value less than backend’s timeout
    SQLALCHEMY_POOL_TIMEOUT = 7  # value less than backend’s timeout
    SQLALCHEMY_PRE_PING = True
    SQLALCHEMY_ENGINE_OPTIONS = {'pool_recycle': SQLALCHEMY_POOL_RECYCLE, 'pool_timeout': SQLALCHEMY_POOL_TIMEOUT, 'pool_pre_ping': SQLALCHEMY_PRE_PING}
    DEBUG = True
    # SERVER_NAME = '127.0.0.1:5000'
    SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI_DEV')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class SQLAlchemy(_BaseSQLAlchemy):
    def apply_pool_defaults(self, app, options):
        super(SQLAlchemy, self).apply_pool_defaults(app, options)
        options["pool_pre_ping"] = DevConfig.SQLALCHEMY_PRE_PING
#        options["pool_recycle"] = 30
#        options["pool_timeout"] = 35

db = SQLAlchemy()

config = dict(
    dev=DevConfig,
)

app = Flask(__name__, instance_relative_config=True)
app.config.from_object(config['dev'])

# INIT DATABASE
db.init_app(app)
with app.app_context():
    db.create_all()

필요에 따라 변경 내용을 확인할 수 있습니다.diffchecker.com/Q1e85Hhc

언급URL : https://stackoverflow.com/questions/58866560/flask-sqlalchemy-pool-pre-ping-only-working-sometimes

반응형