修复重复初始化问题 - 统一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 19:57:35 +01:00
parent 228e9b838f
commit 4b4bd683d9
11 changed files with 318 additions and 169 deletions

View File

@@ -10,11 +10,11 @@ from typing import Dict, List, Optional, Any, Tuple
from datetime import datetime, timedelta from datetime import datetime, timedelta
from dataclasses import dataclass from dataclasses import dataclass
from collections import defaultdict from collections import defaultdict
import redis
import time import time
from ..core.database import db_manager from ..core.database import db_manager
from ..core.models import Alert from ..core.models import Alert
from ..core.redis_manager import redis_manager
from ..config.config import Config from ..config.config import Config
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -38,8 +38,7 @@ class AISuccessMonitor:
"""AI调用成功率监控器""" """AI调用成功率监控器"""
def __init__(self): def __init__(self):
self.redis_client = None # 使用统一的Redis管理器
self._init_redis()
# 监控阈值 # 监控阈值
self.thresholds = { self.thresholds = {
@@ -58,23 +57,9 @@ class AISuccessMonitor:
"poor": {"success_rate": 0.85, "response_time": 12.0} "poor": {"success_rate": 0.85, "response_time": 12.0}
} }
def _init_redis(self): def _get_redis_client(self):
"""初始化Redis连接""" """获取Redis客户端"""
try: return redis_manager.get_connection()
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( def record_api_call(
self, self,

View File

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

View File

@@ -22,21 +22,32 @@ class CacheManager:
self.default_ttl = 60 # 默认1分钟过期提高响应速度 self.default_ttl = 60 # 默认1分钟过期提高响应速度
self.max_memory_size = 2000 # 增加内存缓存条目数 self.max_memory_size = 2000 # 增加内存缓存条目数
# Redis支持可选 # Redis支持可选- 延迟连接
self.redis_client = None self.redis_client = None
if redis_url: self.redis_url = redis_url
self.redis_connected = False
def _ensure_redis_connection(self):
"""确保Redis连接延迟连接"""
if self.redis_url and not self.redis_connected:
try: try:
import redis import redis
self.redis_client = redis.from_url(redis_url) self.redis_client = redis.from_url(self.redis_url, socket_connect_timeout=2, socket_timeout=2)
self.redis_client.ping() # 测试连接
self.redis_connected = True
logger.info("Redis缓存已启用") logger.info("Redis缓存已启用")
except ImportError: except ImportError:
logger.warning("Redis未安装使用内存缓存") logger.debug("Redis未安装使用内存缓存")
except Exception as e: except Exception as e:
logger.warning(f"Redis连接失败: {e},使用内存缓存") logger.debug(f"Redis连接失败: {e},使用内存缓存")
self.redis_client = None
def get(self, key: str) -> Optional[Any]: def get(self, key: str) -> Optional[Any]:
"""获取缓存值""" """获取缓存值"""
try: try:
# 确保Redis连接
self._ensure_redis_connection()
# 先尝试Redis # 先尝试Redis
if self.redis_client: if self.redis_client:
try: try:
@@ -66,6 +77,9 @@ class CacheManager:
ttl = ttl or self.default_ttl ttl = ttl or self.default_ttl
expires_at = time.time() + ttl expires_at = time.time() + ttl
# 确保Redis连接
self._ensure_redis_connection()
# 先尝试Redis # 先尝试Redis
if self.redis_client: if self.redis_client:
try: try:

81
src/core/redis_manager.py Normal file
View File

@@ -0,0 +1,81 @@
# -*- 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

@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
"""
启动优化配置
控制启动时的初始化行为,避免重复初始化和阻塞
"""
class StartupConfig:
"""启动配置类"""
# 启动优化设置
SKIP_SYSTEM_CHECK = True # 跳过系统检查
DELAY_REDIS_CONNECTION = True # 延迟Redis连接
DELAY_MONITORING_START = True # 延迟监控启动
DELAY_AGENT_INIT = True # 延迟Agent初始化
# 延迟时间(秒)
REDIS_CONNECTION_DELAY = 2 # Redis连接延迟
MONITORING_START_DELAY = 5 # 监控启动延迟
AGENT_INIT_DELAY = 3 # Agent初始化延迟
# 连接超时设置
REDIS_CONNECT_TIMEOUT = 2 # Redis连接超时
REDIS_SOCKET_TIMEOUT = 2 # Redis Socket超时
DATABASE_CONNECT_TIMEOUT = 5 # 数据库连接超时
# 日志级别控制
REDIS_LOG_LEVEL = "DEBUG" # Redis日志级别
STARTUP_LOG_LEVEL = "INFO" # 启动日志级别
@classmethod
def should_skip_system_check(cls):
"""是否跳过系统检查"""
return cls.SKIP_SYSTEM_CHECK
@classmethod
def should_delay_redis_connection(cls):
"""是否延迟Redis连接"""
return cls.DELAY_REDIS_CONNECTION
@classmethod
def should_delay_monitoring_start(cls):
"""是否延迟监控启动"""
return cls.DELAY_MONITORING_START
@classmethod
def should_delay_agent_init(cls):
"""是否延迟Agent初始化"""
return cls.DELAY_AGENT_INIT
@classmethod
def get_redis_timeout_config(cls):
"""获取Redis超时配置"""
return {
'socket_connect_timeout': cls.REDIS_CONNECT_TIMEOUT,
'socket_timeout': cls.REDIS_SOCKET_TIMEOUT
}
@classmethod
def get_delay_times(cls):
"""获取延迟时间配置"""
return {
'redis_connection': cls.REDIS_CONNECTION_DELAY,
'monitoring_start': cls.MONITORING_START_DELAY,
'agent_init': cls.AGENT_INIT_DELAY
}

View File

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

View File

@@ -8,11 +8,11 @@ import json
import logging import logging
from typing import Dict, List, Optional, Any, Tuple from typing import Dict, List, Optional, Any, Tuple
from datetime import datetime, timedelta from datetime import datetime, timedelta
import redis
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from ..core.database import db_manager from ..core.database import db_manager
from ..core.models import Conversation from ..core.models import Conversation
from ..core.redis_manager import redis_manager
from ..config.config import Config from ..config.config import Config
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -21,29 +21,12 @@ class ConversationHistoryManager:
"""对话历史管理器""" """对话历史管理器"""
def __init__(self): def __init__(self):
self.redis_client = None
self._init_redis()
self.max_history_length = 20 # 最大历史记录数 self.max_history_length = 20 # 最大历史记录数
self.cache_ttl = 3600 * 24 # 缓存24小时 self.cache_ttl = 3600 * 24 # 缓存24小时
def _init_redis(self): def _get_redis_client(self):
"""初始化Redis连接""" """获取Redis客户端"""
try: return redis_manager.get_connection()
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("Redis连接成功")
except Exception as e:
logger.error(f"Redis连接失败: {e}")
self.redis_client = None
def _get_cache_key(self, user_id: str, work_order_id: Optional[int] = None) -> str: def _get_cache_key(self, user_id: str, work_order_id: Optional[int] = None) -> str:
"""生成缓存键""" """生成缓存键"""
@@ -109,7 +92,8 @@ class ConversationHistoryManager:
response_time: Optional[float] = None response_time: Optional[float] = None
): ):
"""保存对话到Redis缓存""" """保存对话到Redis缓存"""
if not self.redis_client: redis_client = self._get_redis_client()
if not redis_client:
return return
try: try:
@@ -126,13 +110,13 @@ class ConversationHistoryManager:
} }
# 添加到Redis列表 # 添加到Redis列表
self.redis_client.lpush(cache_key, json.dumps(conversation_record, ensure_ascii=False)) redis_client.lpush(cache_key, json.dumps(conversation_record, ensure_ascii=False))
# 限制列表长度 # 限制列表长度
self.redis_client.ltrim(cache_key, 0, self.max_history_length - 1) redis_client.ltrim(cache_key, 0, self.max_history_length - 1)
# 设置过期时间 # 设置过期时间
self.redis_client.expire(cache_key, self.cache_ttl) redis_client.expire(cache_key, self.cache_ttl)
except Exception as e: except Exception as e:
logger.error(f"保存到Redis缓存失败: {e}") logger.error(f"保存到Redis缓存失败: {e}")
@@ -147,7 +131,8 @@ class ConversationHistoryManager:
"""获取对话历史优先从Redis获取""" """获取对话历史优先从Redis获取"""
try: try:
# 先尝试从Redis获取 # 先尝试从Redis获取
if self.redis_client: redis_client = self._get_redis_client()
if redis_client:
cached_history = self._get_from_cache(user_id, work_order_id, limit, offset) cached_history = self._get_from_cache(user_id, work_order_id, limit, offset)
if cached_history: if cached_history:
return cached_history return cached_history
@@ -167,7 +152,8 @@ class ConversationHistoryManager:
offset: int offset: int
) -> List[Dict[str, Any]]: ) -> List[Dict[str, Any]]:
"""从Redis缓存获取对话历史""" """从Redis缓存获取对话历史"""
if not self.redis_client: redis_client = self._get_redis_client()
if not redis_client:
return [] return []
try: try:
@@ -177,7 +163,7 @@ class ConversationHistoryManager:
start = offset start = offset
end = offset + limit - 1 end = offset + limit - 1
cached_data = self.redis_client.lrange(cache_key, start, end) cached_data = redis_client.lrange(cache_key, start, end)
history = [] history = []
for data in cached_data: for data in cached_data:

View File

@@ -23,11 +23,36 @@ class DialogueManager:
self.knowledge_manager = KnowledgeManager() self.knowledge_manager = KnowledgeManager()
self.vehicle_manager = VehicleDataManager() self.vehicle_manager = VehicleDataManager()
self.history_manager = ConversationHistoryManager() self.history_manager = ConversationHistoryManager()
self.token_monitor = TokenMonitor() # 延迟初始化监控器,避免重复创建
self.ai_success_monitor = AISuccessMonitor() self._token_monitor = None
self.system_optimizer = SystemOptimizer() self._ai_success_monitor = None
self._system_optimizer = None
self.conversation_history = {} # 存储对话历史 self.conversation_history = {} # 存储对话历史
@property
def token_monitor(self):
"""获取Token监控器懒加载"""
if self._token_monitor is None:
from ..analytics.token_monitor import TokenMonitor
self._token_monitor = TokenMonitor()
return self._token_monitor
@property
def ai_success_monitor(self):
"""获取AI成功监控器懒加载"""
if self._ai_success_monitor is None:
from ..analytics.ai_success_monitor import AISuccessMonitor
self._ai_success_monitor = AISuccessMonitor()
return self._ai_success_monitor
@property
def system_optimizer(self):
"""获取系统优化器(懒加载)"""
if self._system_optimizer is None:
from ..core.system_optimizer import SystemOptimizer
self._system_optimizer = SystemOptimizer()
return self._system_optimizer
def process_user_message( def process_user_message(
self, self,
user_message: str, user_message: str,

View File

@@ -16,13 +16,14 @@ from flask_cors import CORS
# 添加项目根目录到Python路径 # 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from src.main import TSPAssistant # 延迟导入,避免启动时重复初始化
from src.agent_assistant import TSPAgentAssistant # from src.main import TSPAssistant
from src.dialogue.realtime_chat import RealtimeChatManager # from src.agent_assistant import TSPAgentAssistant
from src.vehicle.vehicle_data_manager import VehicleDataManager # from src.dialogue.realtime_chat import RealtimeChatManager
# from src.vehicle.vehicle_data_manager import VehicleDataManager
from src.core.database import db_manager from src.core.database import db_manager
from src.core.models import Conversation, Alert, WorkOrder from src.core.models import Conversation, Alert, WorkOrder
from src.core.query_optimizer import query_optimizer # from src.core.query_optimizer import query_optimizer
# 导入蓝图 # 导入蓝图
from src.web.blueprints.alerts import alerts_bp from src.web.blueprints.alerts import alerts_bp
@@ -67,6 +68,7 @@ def get_assistant():
"""获取TSP助手实例懒加载""" """获取TSP助手实例懒加载"""
global assistant global assistant
if assistant is None: if assistant is None:
from src.main import TSPAssistant
assistant = TSPAssistant() assistant = TSPAssistant()
return assistant return assistant
@@ -74,6 +76,7 @@ def get_agent_assistant():
"""获取Agent助手实例懒加载""" """获取Agent助手实例懒加载"""
global agent_assistant global agent_assistant
if agent_assistant is None: if agent_assistant is None:
from src.agent_assistant import TSPAgentAssistant
agent_assistant = TSPAgentAssistant() agent_assistant = TSPAgentAssistant()
return agent_assistant return agent_assistant
@@ -81,6 +84,7 @@ def get_chat_manager():
"""获取聊天管理器实例(懒加载)""" """获取聊天管理器实例(懒加载)"""
global chat_manager global chat_manager
if chat_manager is None: if chat_manager is None:
from src.dialogue.realtime_chat import RealtimeChatManager
chat_manager = RealtimeChatManager() chat_manager = RealtimeChatManager()
return chat_manager return chat_manager
@@ -88,6 +92,7 @@ def get_vehicle_manager():
"""获取车辆数据管理器实例(懒加载)""" """获取车辆数据管理器实例(懒加载)"""
global vehicle_manager global vehicle_manager
if vehicle_manager is None: if vehicle_manager is None:
from src.vehicle.vehicle_data_manager import VehicleDataManager
vehicle_manager = VehicleDataManager() vehicle_manager = VehicleDataManager()
return vehicle_manager return vehicle_manager

View File

@@ -53,26 +53,8 @@ def main():
logger.info("正在启动TSP智能助手综合管理平台...") logger.info("正在启动TSP智能助手综合管理平台...")
# 快速系统检查(不创建完整实例 # 跳过系统检查,直接启动(避免重复初始化
try: logger.info("跳过系统检查,直接启动服务...")
from src.core.database import db_manager
from src.core.llm_client import QwenClient
# 快速测试数据库连接
db_ok = db_manager.test_connection()
# 快速测试LLM连接
llm_client = QwenClient()
llm_ok = llm_client.test_connection()
logger.info(f"系统检查结果: 数据库={db_ok}, LLM={llm_ok}")
if not (db_ok and llm_ok):
logger.warning("系统检查发现问题,但继续启动...")
except Exception as e:
logger.error(f"系统检查失败: {e}")
print(f"警告: 系统检查失败 - {e}")
# 导入并启动Flask应用 # 导入并启动Flask应用
from src.web.app import app from src.web.app import app

View File

@@ -0,0 +1,18 @@
@echo off
chcp 65001 >nul
echo ========================================
echo TSP智能助手 - 快速启动(优化版)
echo ========================================
echo.
echo 正在启动服务...
echo 优化内容:
echo - 跳过系统检查,快速启动
echo - 延迟Redis连接避免阻塞
echo - 延迟监控启动,减少初始化时间
echo - 懒加载组件,按需初始化
echo.
python start_dashboard.py
pause