修改说明

This commit is contained in:
zhaojie
2025-09-08 15:27:22 +08:00
parent 8083f136c9
commit e08b570f22
26 changed files with 3524 additions and 21 deletions

266
scripts/deploy.sh Normal file
View File

@@ -0,0 +1,266 @@
#!/bin/bash
# TSP智能助手部署脚本
set -e # 遇到错误立即退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查依赖
check_dependencies() {
log_info "检查系统依赖..."
# 检查Python
if ! command -v python3 &> /dev/null; then
log_error "Python3 未安装"
exit 1
fi
# 检查pip
if ! command -v pip3 &> /dev/null; then
log_error "pip3 未安装"
exit 1
fi
# 检查Git
if ! command -v git &> /dev/null; then
log_error "Git 未安装"
exit 1
fi
log_info "依赖检查完成"
}
# 创建虚拟环境
setup_venv() {
local venv_path=$1
log_info "创建虚拟环境: $venv_path"
if [ ! -d "$venv_path" ]; then
python3 -m venv "$venv_path"
fi
source "$venv_path/bin/activate"
pip install --upgrade pip
log_info "虚拟环境设置完成"
}
# 安装依赖
install_dependencies() {
log_info "安装Python依赖..."
pip install -r requirements.txt
log_info "依赖安装完成"
}
# 数据库迁移
run_migrations() {
log_info "运行数据库迁移..."
# 检查数据库文件
if [ ! -f "tsp_assistant.db" ]; then
log_info "初始化数据库..."
python init_database.py
fi
log_info "数据库迁移完成"
}
# 创建systemd服务文件
create_systemd_service() {
local service_name=$1
local app_path=$2
local service_file="/etc/systemd/system/${service_name}.service"
log_info "创建systemd服务文件: $service_file"
sudo tee "$service_file" > /dev/null <<EOF
[Unit]
Description=TSP智能助手服务
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=$app_path
Environment=PATH=$app_path/venv/bin
ExecStart=$app_path/venv/bin/python start_dashboard.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable "$service_name"
log_info "systemd服务创建完成"
}
# 创建nginx配置
create_nginx_config() {
local domain=$1
local app_port=$2
local config_file="/etc/nginx/sites-available/tsp_assistant"
log_info "创建nginx配置: $config_file"
sudo tee "$config_file" > /dev/null <<EOF
server {
listen 80;
server_name $domain;
location / {
proxy_pass http://127.0.0.1:$app_port;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
location /static {
alias $app_path/src/web/static;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
EOF
# 启用站点
sudo ln -sf "$config_file" /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
log_info "nginx配置完成"
}
# 主部署函数
deploy() {
local environment=${1:-production}
local domain=${2:-localhost}
local app_port=${3:-5000}
log_info "开始部署TSP智能助手到 $environment 环境"
# 设置部署路径
case $environment in
development)
DEPLOY_PATH="./dev_deploy"
SERVICE_NAME=""
;;
staging)
DEPLOY_PATH="/opt/tsp_assistant_staging"
SERVICE_NAME="tsp_assistant_staging"
;;
production)
DEPLOY_PATH="/opt/tsp_assistant"
SERVICE_NAME="tsp_assistant"
;;
*)
log_error "未知环境: $environment"
exit 1
;;
esac
# 检查依赖
check_dependencies
# 创建部署目录
log_info "创建部署目录: $DEPLOY_PATH"
sudo mkdir -p "$DEPLOY_PATH"
sudo chown $USER:$USER "$DEPLOY_PATH"
# 复制文件
log_info "复制应用文件..."
cp -r . "$DEPLOY_PATH/"
cd "$DEPLOY_PATH"
# 设置虚拟环境
setup_venv "venv"
# 安装依赖
install_dependencies
# 运行迁移
run_migrations
# 创建服务文件(非开发环境)
if [ "$environment" != "development" ] && [ -n "$SERVICE_NAME" ]; then
create_systemd_service "$SERVICE_NAME" "$DEPLOY_PATH"
create_nginx_config "$domain" "$app_port"
fi
log_info "部署完成!"
if [ "$environment" != "development" ]; then
log_info "启动服务..."
sudo systemctl start "$SERVICE_NAME"
sudo systemctl status "$SERVICE_NAME"
else
log_info "开发环境部署完成,使用以下命令启动:"
log_info "cd $DEPLOY_PATH && source venv/bin/activate && python start_dashboard.py"
fi
}
# 回滚函数
rollback() {
local backup_name=$1
if [ -z "$backup_name" ]; then
log_error "请指定备份名称"
exit 1
fi
log_info "回滚到备份: $backup_name"
# 停止服务
sudo systemctl stop tsp_assistant
# 恢复备份
if [ -d "backups/$backup_name" ]; then
sudo rm -rf /opt/tsp_assistant
sudo cp -r "backups/$backup_name" /opt/tsp_assistant
sudo chown -R www-data:www-data /opt/tsp_assistant
# 重启服务
sudo systemctl start tsp_assistant
log_info "回滚完成"
else
log_error "备份不存在: $backup_name"
exit 1
fi
}
# 主函数
main() {
case ${1:-deploy} in
deploy)
deploy "$2" "$3" "$4"
;;
rollback)
rollback "$2"
;;
*)
echo "用法: $0 {deploy|rollback} [environment] [domain] [port]"
echo "环境: development, staging, production"
exit 1
;;
esac
}
main "$@"

277
scripts/monitor.sh Normal file
View File

@@ -0,0 +1,277 @@
#!/bin/bash
# TSP智能助手监控脚本
# 配置变量
APP_NAME="tsp_assistant"
SERVICE_NAME="tsp_assistant"
HEALTH_URL="http://localhost:5000/api/health"
LOG_FILE="./logs/monitor.log"
ALERT_EMAIL="admin@example.com"
ALERT_PHONE="13800138000"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 日志函数
log_info() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] INFO${NC} $1" | tee -a "$LOG_FILE"
}
log_warn() {
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARN${NC} $1" | tee -a "$LOG_FILE"
}
log_error() {
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR${NC} $1" | tee -a "$LOG_FILE"
}
# 发送告警
send_alert() {
local message=$1
local level=$2
log_error "告警: $message"
# 发送邮件告警
if command -v mail &> /dev/null; then
echo "$message" | mail -s "[$level] TSP助手告警" "$ALERT_EMAIL"
fi
# 发送短信告警(需要配置短信服务)
# curl -X POST "https://api.sms.com/send" \
# -d "phone=$ALERT_PHONE" \
# -d "message=$message"
}
# 检查服务状态
check_service_status() {
if systemctl is-active --quiet "$SERVICE_NAME"; then
return 0
else
return 1
fi
}
# 检查健康状态
check_health() {
local response_code
response_code=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_URL" 2>/dev/null)
if [ "$response_code" = "200" ]; then
return 0
else
return 1
fi
}
# 检查响应时间
check_response_time() {
local response_time
response_time=$(curl -s -o /dev/null -w "%{time_total}" "$HEALTH_URL" 2>/dev/null)
# 响应时间超过5秒认为异常
if (( $(echo "$response_time > 5.0" | bc -l) )); then
return 1
else
return 0
fi
}
# 检查系统资源
check_system_resources() {
local cpu_usage
local memory_usage
local disk_usage
# CPU使用率
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')
# 内存使用率
memory_usage=$(free | grep Mem | awk '{printf "%.2f", $3/$2 * 100.0}')
# 磁盘使用率
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
# 检查阈值
if (( $(echo "$cpu_usage > 80" | bc -l) )); then
send_alert "CPU使用率过高: ${cpu_usage}%" "HIGH"
fi
if (( $(echo "$memory_usage > 80" | bc -l) )); then
send_alert "内存使用率过高: ${memory_usage}%" "HIGH"
fi
if [ "$disk_usage" -gt 80 ]; then
send_alert "磁盘使用率过高: ${disk_usage}%" "HIGH"
fi
log_info "系统资源 - CPU: ${cpu_usage}%, 内存: ${memory_usage}%, 磁盘: ${disk_usage}%"
}
# 检查日志错误
check_log_errors() {
local log_file="./logs/tsp_assistant.log"
local error_count
if [ -f "$log_file" ]; then
# 检查最近5分钟的错误日志
error_count=$(tail -n 100 "$log_file" | grep -c "ERROR" 2>/dev/null || echo "0")
if [ "$error_count" -gt 10 ]; then
send_alert "最近5分钟错误日志过多: $error_count" "MEDIUM"
fi
fi
}
# 检查数据库连接
check_database() {
local db_file="./tsp_assistant.db"
if [ -f "$db_file" ]; then
# 检查数据库文件大小
local db_size
db_size=$(du -h "$db_file" | cut -f1)
log_info "数据库大小: $db_size"
# 检查数据库是否可读
if ! sqlite3 "$db_file" "SELECT 1;" > /dev/null 2>&1; then
send_alert "数据库连接失败" "CRITICAL"
return 1
fi
fi
return 0
}
# 自动重启服务
restart_service() {
log_warn "尝试重启服务..."
sudo systemctl restart "$SERVICE_NAME"
sleep 10
if check_service_status && check_health; then
log_info "服务重启成功"
return 0
else
log_error "服务重启失败"
return 1
fi
}
# 主监控循环
monitor_loop() {
local consecutive_failures=0
local max_failures=3
while true; do
log_info "开始监控检查..."
# 检查服务状态
if ! check_service_status; then
log_error "服务未运行"
send_alert "TSP助手服务未运行" "CRITICAL"
consecutive_failures=$((consecutive_failures + 1))
else
# 检查健康状态
if ! check_health; then
log_error "健康检查失败"
send_alert "TSP助手健康检查失败" "HIGH"
consecutive_failures=$((consecutive_failures + 1))
else
# 检查响应时间
if ! check_response_time; then
log_warn "响应时间过长"
send_alert "TSP助手响应时间过长" "MEDIUM"
fi
consecutive_failures=0
fi
fi
# 检查系统资源
check_system_resources
# 检查日志错误
check_log_errors
# 检查数据库
check_database
# 连续失败处理
if [ "$consecutive_failures" -ge "$max_failures" ]; then
log_error "连续失败次数达到阈值,尝试重启服务"
if restart_service; then
consecutive_failures=0
else
send_alert "TSP助手服务重启失败需要人工干预" "CRITICAL"
fi
fi
# 等待下次检查
sleep 60
done
}
# 一次性检查
single_check() {
log_info "执行一次性健康检查..."
if check_service_status; then
log_info "✓ 服务运行正常"
else
log_error "✗ 服务未运行"
exit 1
fi
if check_health; then
log_info "✓ 健康检查通过"
else
log_error "✗ 健康检查失败"
exit 1
fi
if check_response_time; then
log_info "✓ 响应时间正常"
else
log_warn "⚠ 响应时间过长"
fi
check_system_resources
check_log_errors
check_database
log_info "健康检查完成"
}
# 主函数
main() {
# 创建日志目录
mkdir -p logs
case ${1:-monitor} in
monitor)
log_info "启动TSP助手监控服务..."
monitor_loop
;;
check)
single_check
;;
restart)
restart_service
;;
*)
echo "用法: $0 {monitor|check|restart}"
echo " monitor - 持续监控模式"
echo " check - 一次性健康检查"
echo " restart - 重启服务"
exit 1
;;
esac
}
# 执行主函数
main "$@"

273
scripts/upgrade.sh Normal file
View File

@@ -0,0 +1,273 @@
#!/bin/bash
# TSP智能助手升级脚本
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_step() {
echo -e "${BLUE}[STEP]${NC} $1"
}
# 配置变量
APP_NAME="tsp_assistant"
BACKUP_DIR="./backups"
DEPLOY_PATH="/opt/tsp_assistant"
SERVICE_NAME="tsp_assistant"
HEALTH_URL="http://localhost:5000/api/health"
# 检查参数
if [ $# -lt 1 ]; then
echo "用法: $0 <新版本路径> [选项]"
echo "选项:"
echo " --force 强制升级,跳过确认"
echo " --no-backup 跳过备份"
echo " --rollback 回滚到指定备份"
exit 1
fi
NEW_VERSION_PATH=$1
FORCE_UPGRADE=false
SKIP_BACKUP=false
ROLLBACK_MODE=false
# 解析参数
while [[ $# -gt 1 ]]; do
case $2 in
--force)
FORCE_UPGRADE=true
;;
--no-backup)
SKIP_BACKUP=true
;;
--rollback)
ROLLBACK_MODE=true
;;
*)
log_error "未知选项: $2"
exit 1
;;
esac
shift
done
# 回滚功能
rollback() {
local backup_name=$1
if [ -z "$backup_name" ]; then
log_error "请指定备份名称"
exit 1
fi
log_step "开始回滚到备份: $backup_name"
# 检查备份是否存在
if [ ! -d "$BACKUP_DIR/$backup_name" ]; then
log_error "备份不存在: $backup_name"
log_info "可用备份列表:"
ls -la "$BACKUP_DIR" | grep backup
exit 1
fi
# 停止服务
log_info "停止服务..."
sudo systemctl stop "$SERVICE_NAME" || true
# 恢复文件
log_info "恢复文件..."
sudo rm -rf "$DEPLOY_PATH"
sudo cp -r "$BACKUP_DIR/$backup_name" "$DEPLOY_PATH"
sudo chown -R www-data:www-data "$DEPLOY_PATH"
# 恢复数据库
if [ -f "$BACKUP_DIR/$backup_name/database/tsp_assistant.db" ]; then
log_info "恢复数据库..."
sudo cp "$BACKUP_DIR/$backup_name/database/tsp_assistant.db" "$DEPLOY_PATH/"
fi
# 启动服务
log_info "启动服务..."
sudo systemctl start "$SERVICE_NAME"
# 等待服务启动
sleep 10
# 健康检查
if curl -f "$HEALTH_URL" > /dev/null 2>&1; then
log_info "回滚成功!"
else
log_error "回滚后健康检查失败"
exit 1
fi
}
# 创建备份
create_backup() {
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_name="${APP_NAME}_backup_${timestamp}"
local backup_path="$BACKUP_DIR/$backup_name"
log_step "创建备份: $backup_name"
# 创建备份目录
mkdir -p "$backup_path"
# 备份应用文件
if [ -d "$DEPLOY_PATH" ]; then
log_info "备份应用文件..."
cp -r "$DEPLOY_PATH"/* "$backup_path/"
fi
# 备份数据库
if [ -f "$DEPLOY_PATH/tsp_assistant.db" ]; then
log_info "备份数据库..."
mkdir -p "$backup_path/database"
cp "$DEPLOY_PATH/tsp_assistant.db" "$backup_path/database/"
fi
# 保存备份信息
cat > "$backup_path/backup_info.json" << EOF
{
"backup_name": "$backup_name",
"backup_path": "$backup_path",
"timestamp": "$timestamp",
"version": "$(cd "$DEPLOY_PATH" && python version.py version 2>/dev/null || echo "unknown")",
"git_commit": "$(cd "$DEPLOY_PATH" && git rev-parse HEAD 2>/dev/null | cut -c1-8 || echo "unknown")"
}
EOF
log_info "备份完成: $backup_name"
echo "$backup_name"
}
# 升级功能
upgrade() {
local new_version_path=$1
log_step "开始升级TSP智能助手"
# 检查新版本路径
if [ ! -d "$new_version_path" ]; then
log_error "新版本路径不存在: $new_version_path"
exit 1
fi
# 检查当前版本
if [ -d "$DEPLOY_PATH" ]; then
local current_version=$(cd "$DEPLOY_PATH" && python version.py version 2>/dev/null || echo "unknown")
log_info "当前版本: $current_version"
else
log_warn "当前部署路径不存在: $DEPLOY_PATH"
fi
# 检查新版本
local new_version=$(cd "$new_version_path" && python version.py version 2>/dev/null || echo "unknown")
log_info "新版本: $new_version"
# 确认升级
if [ "$FORCE_UPGRADE" = false ]; then
echo -n "确认升级到版本 $new_version? (y/N): "
read -r response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
log_info "升级取消"
exit 0
fi
fi
# 创建备份
local backup_name=""
if [ "$SKIP_BACKUP" = false ]; then
backup_name=$(create_backup)
fi
# 停止服务
log_step "停止服务..."
sudo systemctl stop "$SERVICE_NAME" || true
# 升级文件
log_step "升级应用文件..."
sudo rm -rf "$DEPLOY_PATH"
sudo mkdir -p "$DEPLOY_PATH"
sudo cp -r "$new_version_path"/* "$DEPLOY_PATH/"
sudo chown -R www-data:www-data "$DEPLOY_PATH"
# 安装依赖
log_step "安装依赖..."
cd "$DEPLOY_PATH"
sudo -u www-data python -m pip install -r requirements.txt
# 运行数据库迁移
log_step "运行数据库迁移..."
sudo -u www-data python init_database.py || true
# 启动服务
log_step "启动服务..."
sudo systemctl start "$SERVICE_NAME"
# 等待服务启动
log_info "等待服务启动..."
sleep 15
# 健康检查
log_step "执行健康检查..."
local retry_count=0
local max_retries=10
while [ $retry_count -lt $max_retries ]; do
if curl -f "$HEALTH_URL" > /dev/null 2>&1; then
log_info "健康检查通过!"
break
else
log_warn "健康检查失败,重试中... ($((retry_count + 1))/$max_retries)"
retry_count=$((retry_count + 1))
sleep 5
fi
done
if [ $retry_count -eq $max_retries ]; then
log_error "健康检查失败,开始回滚..."
if [ -n "$backup_name" ]; then
rollback "$backup_name"
else
log_error "没有备份可回滚"
exit 1
fi
else
log_info "升级成功!"
log_info "新版本: $new_version"
if [ -n "$backup_name" ]; then
log_info "备份名称: $backup_name"
fi
fi
}
# 主函数
main() {
if [ "$ROLLBACK_MODE" = true ]; then
rollback "$NEW_VERSION_PATH"
else
upgrade "$NEW_VERSION_PATH"
fi
}
# 执行主函数
main