fix: reduce mysql connection pressure
This commit is contained in:
@@ -20,9 +20,11 @@ _MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "")
|
||||
_MYSQL_DATABASE = os.getenv("MYSQL_DATABASE", "ai_cs")
|
||||
|
||||
# ========== MySQL 连接池 ==========
|
||||
_POOL_SIZE = int(os.getenv("MYSQL_POOL_SIZE", "50"))
|
||||
_POOL_SIZE = int(os.getenv("MYSQL_POOL_SIZE", "10"))
|
||||
_POOL_WAIT_TIMEOUT = float(os.getenv("MYSQL_POOL_WAIT_TIMEOUT", "10"))
|
||||
_mysql_pool: Optional[Queue] = None
|
||||
_pool_lock = threading.Lock()
|
||||
_mysql_conn_count = 0
|
||||
|
||||
|
||||
def _create_mysql_conn():
|
||||
@@ -44,58 +46,65 @@ def _create_mysql_conn():
|
||||
|
||||
|
||||
def _init_mysql_pool():
|
||||
"""初始化 MySQL 连接池"""
|
||||
"""初始化 MySQL 连接池(懒创建,不在启动时预建满)"""
|
||||
global _mysql_pool
|
||||
with _pool_lock:
|
||||
if _mysql_pool is None:
|
||||
_mysql_pool = Queue(maxsize=_POOL_SIZE)
|
||||
for _ in range(_POOL_SIZE):
|
||||
try:
|
||||
conn = _create_mysql_conn()
|
||||
_mysql_pool.put(conn)
|
||||
except Exception:
|
||||
pass # 启动时连接失败不阻塞,后续会重建
|
||||
|
||||
|
||||
def _discard_conn(conn):
|
||||
"""丢弃失效连接并维护计数"""
|
||||
global _mysql_conn_count
|
||||
try:
|
||||
conn.close()
|
||||
except Exception:
|
||||
pass
|
||||
with _pool_lock:
|
||||
if _mysql_conn_count > 0:
|
||||
_mysql_conn_count -= 1
|
||||
|
||||
|
||||
def _get_pooled_conn(timeout: float = 5.0):
|
||||
"""从连接池获取连接"""
|
||||
global _mysql_pool
|
||||
"""从连接池获取连接,达到上限后阻塞等待,不再额外扩容。"""
|
||||
global _mysql_pool, _mysql_conn_count
|
||||
if _mysql_pool is None:
|
||||
_init_mysql_pool()
|
||||
|
||||
|
||||
with _pool_lock:
|
||||
if _mysql_conn_count < _POOL_SIZE:
|
||||
conn = _create_mysql_conn()
|
||||
_mysql_conn_count += 1
|
||||
return conn
|
||||
|
||||
try:
|
||||
conn = _mysql_pool.get(timeout=timeout)
|
||||
# 检查连接是否有效
|
||||
try:
|
||||
conn.ping(reconnect=True)
|
||||
except Exception:
|
||||
# 连接失效,创建新连接
|
||||
try:
|
||||
conn.close()
|
||||
except Exception:
|
||||
pass
|
||||
conn = _create_mysql_conn()
|
||||
_discard_conn(conn)
|
||||
with _pool_lock:
|
||||
if _mysql_conn_count < _POOL_SIZE:
|
||||
conn = _create_mysql_conn()
|
||||
_mysql_conn_count += 1
|
||||
return conn
|
||||
conn = _mysql_pool.get(timeout=timeout)
|
||||
conn.ping(reconnect=True)
|
||||
return conn
|
||||
except Empty:
|
||||
# 池空了,创建新连接(不放回池)
|
||||
return _create_mysql_conn()
|
||||
raise TimeoutError(f"MySQL连接池已耗尽(pool_size={_POOL_SIZE}, wait_timeout={timeout}s)")
|
||||
|
||||
|
||||
def _return_conn(conn):
|
||||
"""归还连接到池"""
|
||||
"""归还连接到池,失效连接直接丢弃。"""
|
||||
global _mysql_pool
|
||||
if _mysql_pool is None:
|
||||
return
|
||||
try:
|
||||
if _mysql_pool.qsize() < _POOL_SIZE:
|
||||
_mysql_pool.put_nowait(conn)
|
||||
else:
|
||||
conn.close()
|
||||
conn.ping(reconnect=False)
|
||||
_mysql_pool.put_nowait(conn)
|
||||
except Exception:
|
||||
try:
|
||||
conn.close()
|
||||
except Exception:
|
||||
pass
|
||||
_discard_conn(conn)
|
||||
|
||||
|
||||
class _CompatResult:
|
||||
@@ -164,7 +173,7 @@ def _get_conn(max_retries: int = 3, retry_delay: float = 0.5) -> sqlite3.Connect
|
||||
last_error = None
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
conn = _get_pooled_conn(timeout=5.0)
|
||||
conn = _get_pooled_conn(timeout=_POOL_WAIT_TIMEOUT)
|
||||
return _PyMySQLCompatConn(conn, use_pool=True)
|
||||
except Exception as e:
|
||||
last_error = e
|
||||
|
||||
Reference in New Issue
Block a user