修复重复初始化问题 - 统一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:
@@ -10,11 +10,11 @@ from typing import Dict, List, Optional, Any, Tuple
|
||||
from datetime import datetime, timedelta
|
||||
from dataclasses import dataclass
|
||||
from collections import defaultdict
|
||||
import redis
|
||||
import time
|
||||
|
||||
from ..core.database import db_manager
|
||||
from ..core.models import Alert
|
||||
from ..core.redis_manager import redis_manager
|
||||
from ..config.config import Config
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -38,7 +38,8 @@ class AISuccessMonitor:
|
||||
"""AI调用成功率监控器"""
|
||||
|
||||
def __init__(self):
|
||||
# 使用统一的Redis管理器
|
||||
self.redis_client = None
|
||||
self._init_redis()
|
||||
|
||||
# 监控阈值
|
||||
self.thresholds = {
|
||||
@@ -57,9 +58,23 @@ class AISuccessMonitor:
|
||||
"poor": {"success_rate": 0.85, "response_time": 12.0}
|
||||
}
|
||||
|
||||
def _get_redis_client(self):
|
||||
"""获取Redis客户端"""
|
||||
return redis_manager.get_connection()
|
||||
def _init_redis(self):
|
||||
"""初始化Redis连接"""
|
||||
try:
|
||||
self.redis_client = redis.Redis(
|
||||
host='43.134.68.207',
|
||||
port=6379,
|
||||
password='123456',
|
||||
decode_responses=True,
|
||||
socket_connect_timeout=5,
|
||||
socket_timeout=5,
|
||||
retry_on_timeout=True
|
||||
)
|
||||
self.redis_client.ping()
|
||||
logger.info("AI成功率监控Redis连接成功")
|
||||
except Exception as e:
|
||||
logger.error(f"AI成功率监控Redis连接失败: {e}")
|
||||
self.redis_client = None
|
||||
|
||||
def record_api_call(
|
||||
self,
|
||||
|
||||
@@ -10,9 +10,10 @@ from typing import Dict, List, Optional, Any, Tuple
|
||||
from datetime import datetime, timedelta
|
||||
from dataclasses import dataclass
|
||||
from collections import defaultdict
|
||||
import redis
|
||||
|
||||
from ..core.database import db_manager
|
||||
from ..core.models import Conversation
|
||||
from ..core.redis_manager import redis_manager
|
||||
from ..config.config import Config
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -36,7 +37,8 @@ class TokenMonitor:
|
||||
"""Token消耗监控器"""
|
||||
|
||||
def __init__(self):
|
||||
# 使用统一的Redis管理器
|
||||
self.redis_client = None
|
||||
self._init_redis()
|
||||
|
||||
# Token价格配置(每1000个token的价格,单位:元)
|
||||
self.token_prices = {
|
||||
@@ -62,9 +64,23 @@ class TokenMonitor:
|
||||
"error_rate_threshold": 0.1 # 错误率阈值
|
||||
}
|
||||
|
||||
def _get_redis_client(self):
|
||||
"""获取Redis客户端"""
|
||||
return redis_manager.get_connection()
|
||||
def _init_redis(self):
|
||||
"""初始化Redis连接"""
|
||||
try:
|
||||
self.redis_client = redis.Redis(
|
||||
host='43.134.68.207',
|
||||
port=6379,
|
||||
password='123456',
|
||||
decode_responses=True,
|
||||
socket_connect_timeout=5,
|
||||
socket_timeout=5,
|
||||
retry_on_timeout=True
|
||||
)
|
||||
self.redis_client.ping()
|
||||
logger.info("Token监控Redis连接成功")
|
||||
except Exception as e:
|
||||
logger.error(f"Token监控Redis连接失败: {e}")
|
||||
self.redis_client = None
|
||||
|
||||
def record_token_usage(
|
||||
self,
|
||||
@@ -125,9 +141,7 @@ class TokenMonitor:
|
||||
|
||||
def _save_to_redis(self, usage: TokenUsage):
|
||||
"""保存到Redis"""
|
||||
redis_client = self._get_redis_client()
|
||||
|
||||
if not redis_client:
|
||||
if not self.redis_client:
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -147,24 +161,24 @@ class TokenMonitor:
|
||||
}
|
||||
|
||||
# 保存到多个键
|
||||
redis_client.zadd(
|
||||
self.redis_client.zadd(
|
||||
"token_usage:daily",
|
||||
{json.dumps(usage_data, ensure_ascii=False): timestamp}
|
||||
)
|
||||
|
||||
redis_client.zadd(
|
||||
self.redis_client.zadd(
|
||||
f"token_usage:user:{usage.user_id}",
|
||||
{json.dumps(usage_data, ensure_ascii=False): timestamp}
|
||||
)
|
||||
|
||||
if usage.work_order_id:
|
||||
redis_client.zadd(
|
||||
self.redis_client.zadd(
|
||||
f"token_usage:work_order:{usage.work_order_id}",
|
||||
{json.dumps(usage_data, ensure_ascii=False): timestamp}
|
||||
)
|
||||
|
||||
# 设置过期时间(保留30天)
|
||||
redis_client.expire("token_usage:daily", 30 * 24 * 3600)
|
||||
self.redis_client.expire("token_usage:daily", 30 * 24 * 3600)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"保存Token使用到Redis失败: {e}")
|
||||
@@ -227,16 +241,14 @@ class TokenMonitor:
|
||||
def get_daily_cost(self, date: datetime.date) -> float:
|
||||
"""获取指定日期的成本"""
|
||||
try:
|
||||
redis_client = self._get_redis_client()
|
||||
|
||||
if not redis_client:
|
||||
if not self.redis_client:
|
||||
return 0.0
|
||||
|
||||
start_time = datetime.combine(date, datetime.min.time()).timestamp()
|
||||
end_time = datetime.combine(date, datetime.max.time()).timestamp()
|
||||
|
||||
# 从Redis获取当日数据
|
||||
usage_records = redis_client.zrangebyscore(
|
||||
usage_records = self.redis_client.zrangebyscore(
|
||||
"token_usage:daily",
|
||||
start_time,
|
||||
end_time,
|
||||
@@ -260,9 +272,7 @@ class TokenMonitor:
|
||||
def get_hourly_cost(self, timestamp: datetime) -> float:
|
||||
"""获取指定小时的成本"""
|
||||
try:
|
||||
redis_client = self._get_redis_client()
|
||||
|
||||
if not redis_client:
|
||||
if not self.redis_client:
|
||||
return 0.0
|
||||
|
||||
# 获取当前小时的数据
|
||||
@@ -272,7 +282,7 @@ class TokenMonitor:
|
||||
start_time = hour_start.timestamp()
|
||||
end_time = hour_end.timestamp()
|
||||
|
||||
usage_records = redis_client.zrangebyscore(
|
||||
usage_records = self.redis_client.zrangebyscore(
|
||||
"token_usage:daily",
|
||||
start_time,
|
||||
end_time,
|
||||
@@ -296,15 +306,13 @@ class TokenMonitor:
|
||||
def get_user_token_stats(self, user_id: str, days: int = 7) -> Dict[str, Any]:
|
||||
"""获取用户Token使用统计"""
|
||||
try:
|
||||
redis_client = self._get_redis_client()
|
||||
|
||||
if not redis_client:
|
||||
if not self.redis_client:
|
||||
return {}
|
||||
|
||||
end_time = datetime.now().timestamp()
|
||||
start_time = (datetime.now() - timedelta(days=days)).timestamp()
|
||||
|
||||
usage_records = redis_client.zrangebyscore(
|
||||
usage_records = self.redis_client.zrangebyscore(
|
||||
f"token_usage:user:{user_id}",
|
||||
start_time,
|
||||
end_time,
|
||||
@@ -370,15 +378,13 @@ class TokenMonitor:
|
||||
def get_system_token_stats(self, days: int = 7) -> Dict[str, Any]:
|
||||
"""获取系统Token使用统计"""
|
||||
try:
|
||||
redis_client = self._get_redis_client()
|
||||
|
||||
if not redis_client:
|
||||
if not self.redis_client:
|
||||
return {}
|
||||
|
||||
end_time = datetime.now().timestamp()
|
||||
start_time = (datetime.now() - timedelta(days=days)).timestamp()
|
||||
|
||||
usage_records = redis_client.zrangebyscore(
|
||||
usage_records = self.redis_client.zrangebyscore(
|
||||
"token_usage:daily",
|
||||
start_time,
|
||||
end_time,
|
||||
@@ -460,29 +466,27 @@ class TokenMonitor:
|
||||
def cleanup_old_data(self, days: int = 30) -> 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(
|
||||
"token_usage:daily",
|
||||
0,
|
||||
cutoff_time
|
||||
)
|
||||
|
||||
# 清理用户数据
|
||||
user_keys = redis_client.keys("token_usage:user:*")
|
||||
user_keys = self.redis_client.keys("token_usage:user:*")
|
||||
for key in user_keys:
|
||||
redis_client.zremrangebyscore(key, 0, cutoff_time)
|
||||
self.redis_client.zremrangebyscore(key, 0, cutoff_time)
|
||||
|
||||
# 清理工单数据
|
||||
work_order_keys = redis_client.keys("token_usage:work_order:*")
|
||||
work_order_keys = self.redis_client.keys("token_usage:work_order:*")
|
||||
for key in work_order_keys:
|
||||
redis_client.zremrangebyscore(key, 0, cutoff_time)
|
||||
self.redis_client.zremrangebyscore(key, 0, cutoff_time)
|
||||
|
||||
logger.info(f"清理Token监控数据成功: 数量={removed_count}")
|
||||
return removed_count
|
||||
|
||||
Reference in New Issue
Block a user