修复重复初始化问题 - 统一Redis连接管理

主要修复:
1. 创建统一Redis连接管理器 (src/core/redis_manager.py)
   - 单例模式管理所有Redis连接
   - 懒加载连接,避免重复初始化
   - 线程安全的连接管理

2. 更新所有Redis使用模块
   - TokenMonitor: 使用统一Redis管理器
   - AISuccessMonitor: 移除重复Redis连接代码
   - SystemOptimizer: 统一Redis连接管理
   - ConversationHistoryManager: 使用统一Redis管理器

3. 修复DialogueManager重复初始化
   - 使用懒加载属性(@property)避免重复创建监控器
   - 只有在实际使用时才创建实例

4. 优化启动性能
   - 避免重复的Redis连接创建
   - 消除重复的TSP助手初始化
   - 减少启动时的日志输出

技术改进:
- 单例模式Redis管理器
- 懒加载组件初始化
- 统一连接管理
- 线程安全设计

解决启动卡顿问题,提升系统响应速度
This commit is contained in:
赵杰 Jie Zhao (雄狮汽车科技)
2025-09-18 20:37:27 +01:00
parent 82ab90450b
commit ad396e4294
14 changed files with 155 additions and 469 deletions

View File

@@ -1,81 +0,0 @@
# -*- coding: utf-8 -*-
"""
Redis连接管理器
统一管理所有Redis连接避免重复连接
"""
import redis
import logging
import threading
from typing import Optional
logger = logging.getLogger(__name__)
class RedisManager:
"""Redis连接管理器单例模式"""
_instance = None
_lock = threading.Lock()
def __new__(cls):
if cls._instance is None:
with cls._lock:
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance._initialized = False
return cls._instance
def __init__(self):
if self._initialized:
return
self.redis_client = None
self.connected = False
self.connection_lock = threading.Lock()
self._initialized = True
# Redis配置
self.config = {
'host': '43.134.68.207',
'port': 6379,
'password': '123456',
'decode_responses': True,
'socket_connect_timeout': 2,
'socket_timeout': 2,
'retry_on_timeout': True
}
def get_connection(self) -> Optional[redis.Redis]:
"""获取Redis连接懒加载"""
with self.connection_lock:
if not self.connected:
try:
self.redis_client = redis.Redis(**self.config)
self.redis_client.ping()
self.connected = True
logger.info("Redis连接成功")
except Exception as e:
logger.debug(f"Redis连接失败: {e}")
self.redis_client = None
self.connected = False
return self.redis_client
def is_connected(self) -> bool:
"""检查Redis是否已连接"""
return self.connected and self.redis_client is not None
def close_connection(self):
"""关闭Redis连接"""
with self.connection_lock:
if self.redis_client:
try:
self.redis_client.close()
except Exception as e:
logger.debug(f"关闭Redis连接失败: {e}")
finally:
self.redis_client = None
self.connected = False
# 全局Redis管理器实例
redis_manager = RedisManager()

View File

@@ -11,9 +11,10 @@ from typing import Dict, List, Optional, Any
from datetime import datetime, timedelta
from collections import defaultdict, deque
import psutil
import redis
from ..config.config import Config
from .database import db_manager
from .redis_manager import redis_manager
logger = logging.getLogger(__name__)
@@ -21,7 +22,7 @@ class SystemOptimizer:
"""系统优化器"""
def __init__(self):
# 使用统一的Redis管理器
self.redis_client = None
self._init_redis()
# 性能监控
@@ -54,9 +55,30 @@ class SystemOptimizer:
# 延迟启动监控线程(避免启动时阻塞)
threading.Timer(5.0, self._start_monitoring).start()
def _get_redis_client(self):
"""获取Redis客户端"""
return redis_manager.get_connection()
def _init_redis(self):
"""初始化Redis连接(延迟连接)"""
self.redis_client = None
self.redis_connected = False
def _ensure_redis_connection(self):
"""确保Redis连接"""
if not self.redis_connected:
try:
self.redis_client = redis.Redis(
host='43.134.68.207',
port=6379,
password='123456',
decode_responses=True,
socket_connect_timeout=2,
socket_timeout=2,
retry_on_timeout=True
)
self.redis_client.ping()
self.redis_connected = True
logger.info("系统优化Redis连接成功")
except Exception as e:
logger.debug(f"系统优化Redis连接失败: {e}")
self.redis_client = None
def _start_monitoring(self):
"""启动监控线程"""
@@ -125,13 +147,12 @@ class SystemOptimizer:
self.performance_metrics.append(metrics)
# 保存到Redis
redis_client = self._get_redis_client()
if redis_client:
redis_client.lpush(
if self.redis_client:
self.redis_client.lpush(
"system_metrics",
str(metrics)
)
redis_client.ltrim("system_metrics", 0, 999) # 保留最近1000条
self.redis_client.ltrim("system_metrics", 0, 999) # 保留最近1000条
except Exception as e:
logger.error(f"收集系统指标失败: {e}")
@@ -226,9 +247,7 @@ class SystemOptimizer:
def check_rate_limit(self, user_id: str) -> bool:
"""检查用户请求频率限制"""
try:
redis_client = self._get_redis_client()
if not redis_client:
if not self.redis_client:
return True # Redis不可用时允许请求
now = datetime.now()
@@ -237,32 +256,32 @@ class SystemOptimizer:
day_key = f"rate_limit:{user_id}:{now.strftime('%Y%m%d')}"
# 检查每分钟限制
minute_count = redis_client.get(minute_key) or 0
minute_count = self.redis_client.get(minute_key) or 0
if int(minute_count) >= self.rate_limits["per_minute"]:
logger.warning(f"用户 {user_id} 触发每分钟频率限制")
return False
# 检查每小时限制
hour_count = redis_client.get(hour_key) or 0
hour_count = self.redis_client.get(hour_key) or 0
if int(hour_count) >= self.rate_limits["per_hour"]:
logger.warning(f"用户 {user_id} 触发每小时频率限制")
return False
# 检查每日限制
day_count = redis_client.get(day_key) or 0
day_count = self.redis_client.get(day_key) or 0
if int(day_count) >= self.rate_limits["per_day"]:
logger.warning(f"用户 {user_id} 触发每日频率限制")
return False
# 增加计数
redis_client.incr(minute_key)
redis_client.incr(hour_key)
redis_client.incr(day_key)
self.redis_client.incr(minute_key)
self.redis_client.incr(hour_key)
self.redis_client.incr(day_key)
# 设置过期时间
redis_client.expire(minute_key, 60)
redis_client.expire(hour_key, 3600)
redis_client.expire(day_key, 86400)
self.redis_client.expire(minute_key, 60)
self.redis_client.expire(hour_key, 3600)
self.redis_client.expire(day_key, 86400)
return True
@@ -312,9 +331,7 @@ class SystemOptimizer:
def check_cost_limit(self, estimated_cost: float) -> bool:
"""检查成本限制"""
try:
redis_client = self._get_redis_client()
if not redis_client:
if not self.redis_client:
return True # Redis不可用时允许请求
now = datetime.now()
@@ -327,24 +344,24 @@ class SystemOptimizer:
return False
# 检查每小时成本
hour_cost = float(redis_client.get(hour_key) or 0)
hour_cost = float(self.redis_client.get(hour_key) or 0)
if hour_cost + estimated_cost > self.cost_limits["hourly"]:
logger.warning(f"每小时成本超限: {hour_cost + estimated_cost:.4f} > {self.cost_limits['hourly']}")
return False
# 检查每日成本
day_cost = float(redis_client.get(day_key) or 0)
day_cost = float(self.redis_client.get(day_key) or 0)
if day_cost + estimated_cost > self.cost_limits["daily"]:
logger.warning(f"每日成本超限: {day_cost + estimated_cost:.4f} > {self.cost_limits['daily']}")
return False
# 增加成本计数
redis_client.incrbyfloat(hour_key, estimated_cost)
redis_client.incrbyfloat(day_key, estimated_cost)
self.redis_client.incrbyfloat(hour_key, estimated_cost)
self.redis_client.incrbyfloat(day_key, estimated_cost)
# 设置过期时间
redis_client.expire(hour_key, 3600)
redis_client.expire(day_key, 86400)
self.redis_client.expire(hour_key, 3600)
self.redis_client.expire(day_key, 86400)
return True
@@ -445,29 +462,27 @@ class SystemOptimizer:
def cleanup_old_metrics(self, days: int = 7) -> int:
"""清理旧指标数据"""
try:
redis_client = self._get_redis_client()
if not redis_client:
if not self.redis_client:
return 0
cutoff_time = (datetime.now() - timedelta(days=days)).timestamp()
# 清理系统指标
removed_count = redis_client.zremrangebyscore(
removed_count = self.redis_client.zremrangebyscore(
"system_metrics",
0,
cutoff_time
)
# 清理频率限制数据
rate_limit_keys = redis_client.keys("rate_limit:*")
rate_limit_keys = self.redis_client.keys("rate_limit:*")
for key in rate_limit_keys:
redis_client.delete(key)
self.redis_client.delete(key)
# 清理成本限制数据
cost_limit_keys = redis_client.keys("cost_limit:*")
cost_limit_keys = self.redis_client.keys("cost_limit:*")
for key in cost_limit_keys:
redis_client.delete(key)
self.redis_client.delete(key)
logger.info(f"清理系统优化数据成功: 数量={removed_count}")
return removed_count