238 lines
8.2 KiB
Bash
238 lines
8.2 KiB
Bash
#!/bin/bash
|
||
|
||
# QAUP 一键升级脚本
|
||
|
||
set -e
|
||
|
||
# 颜色输出
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
BLUE='\033[0;34m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m'
|
||
|
||
print_message() {
|
||
echo -e "${1}${2}${NC}"
|
||
}
|
||
|
||
print_message $BLUE "=== QAUP 一键升级 ==="
|
||
|
||
# 检查必要文件
|
||
REQUIRED_FILES=("app.jar" "docker-compose.yml" "config.yml")
|
||
for file in "${REQUIRED_FILES[@]}"; do
|
||
if [ ! -f "$file" ]; then
|
||
print_message $RED "❌ 缺失必要文件: $file"
|
||
print_message $BLUE "请确保在正确的部署目录中运行此脚本"
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
# 1. 环境检查和准备
|
||
print_message $BLUE "1. 环境检查..."
|
||
|
||
# 检查Docker服务状态
|
||
if ! docker compose ps > /dev/null 2>&1; then
|
||
print_message $RED "❌ 无法连接到Docker服务"
|
||
print_message $BLUE "请确保Docker服务正在运行: sudo systemctl status docker"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查应用服务状态
|
||
APP_STATUS=$(docker compose ps qaup-app --format json 2>/dev/null | jq -r '.[0].State' 2>/dev/null || echo "exited")
|
||
if [ "$APP_STATUS" != "running" ]; then
|
||
print_message $YELLOW "⚠️ 应用服务当前状态: $APP_STATUS"
|
||
print_message $BLUE "正在启动应用服务..."
|
||
docker compose up -d qaup-app
|
||
sleep 30
|
||
fi
|
||
|
||
# 获取当前应用版本信息
|
||
print_message $BLUE "2. 检查应用版本..."
|
||
if [ -f "new-app.jar" ]; then
|
||
NEW_JAR_SIZE=$(stat -f%z new-app.jar 2>/dev/null || stat -c%s new-app.jar 2>/dev/null || echo "unknown")
|
||
CURRENT_JAR_SIZE=$(stat -f%z app.jar 2>/dev/null || stat -c%s app.jar 2>/dev/null || echo "unknown")
|
||
print_message $BLUE " 当前版本大小: $CURRENT_JAR_SIZE bytes"
|
||
print_message $BLUE " 新版本大小: $NEW_JAR_SIZE bytes"
|
||
|
||
if [ "$NEW_JAR_SIZE" = "$CURRENT_JAR_SIZE" ]; then
|
||
print_message $YELLOW "⚠️ 新旧版本大小相同,请确认版本是否正确"
|
||
read -p "是否继续升级?(y/N): " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||
print_message $BLUE "升级已取消"
|
||
exit 0
|
||
fi
|
||
fi
|
||
else
|
||
print_message $RED "❌ 未找到新版本文件: new-app.jar"
|
||
print_message $BLUE "请先将新版本文件重命名为 new-app.jar"
|
||
print_message $BLUE " 例如: cp qaup-admin-1.0.2.jar new-app.jar"
|
||
exit 1
|
||
fi
|
||
|
||
# 3. 数据库备份
|
||
print_message $BLUE "3. 备份数据库..."
|
||
BACKUP_DIR="backup"
|
||
mkdir -p "$BACKUP_DIR"
|
||
|
||
BACKUP_TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||
BACKUP_FILE="$BACKUP_DIR/qaup_db_backup_$BACKUP_TIMESTAMP.sql"
|
||
|
||
if docker exec qaup-postgres pg_dump -U qaup qaup > "$BACKUP_FILE" 2>/dev/null; then
|
||
BACKUP_SIZE=$(stat -f%z "$BACKUP_FILE" 2>/dev/null || stat -c%s "$BACKUP_FILE" 2>/dev/null || echo "unknown")
|
||
print_message $GREEN "✓ 数据库备份成功: $BACKUP_FILE ($BACKUP_SIZE bytes)"
|
||
else
|
||
print_message $RED "❌ 数据库备份失败"
|
||
print_message $BLUE "升级已取消,请检查数据库连接"
|
||
exit 1
|
||
fi
|
||
|
||
# 4. 备份当前应用
|
||
print_message $BLUE "4. 备份当前应用..."
|
||
BACKUP_JAR="$BACKUP_DIR/app.jar.backup.$BACKUP_TIMESTAMP"
|
||
cp app.jar "$BACKUP_JAR"
|
||
print_message $GREEN "✓ 应用备份成功: $BACKUP_JAR"
|
||
|
||
# 5. 获取升级前数据库迁移状态
|
||
print_message $BLUE "5. 记录升级前迁移状态..."
|
||
BEFORE_MIGRATION=$(docker exec qaup-postgres psql -U qaup -d qaup -t -c "SELECT version,description FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 5;" 2>/dev/null || echo "无法获取迁移状态")
|
||
print_message $BLUE "升级前迁移状态已记录"
|
||
|
||
# 6. 停止应用服务
|
||
print_message $BLUE "6. 停止应用服务..."
|
||
docker compose stop qaup-app
|
||
sleep 10
|
||
print_message $GREEN "✓ 应用服务已停止"
|
||
|
||
# 7. 替换应用文件
|
||
print_message $BLUE "7. 更新应用文件..."
|
||
if cp new-app.jar app.jar; then
|
||
print_message $GREEN "✓ 应用文件更新成功"
|
||
else
|
||
print_message $RED "❌ 应用文件更新失败"
|
||
print_message $BLUE "正在恢复备份..."
|
||
cp "$BACKUP_JAR" app.jar
|
||
docker compose start qaup-app
|
||
exit 1
|
||
fi
|
||
|
||
# 8. 启动应用服务
|
||
print_message $BLUE "8. 启动应用服务..."
|
||
docker compose up -d qaup-app
|
||
sleep 15
|
||
|
||
# 9. 监控应用启动和数据库迁移
|
||
print_message $BLUE "9. 监控应用启动和数据库迁移..."
|
||
print_message $BLUE " 这可能需要2-3分钟,请耐心等待..."
|
||
|
||
WAIT_TIME=0
|
||
HEALTH_URL="http://localhost:8080/actuator/health"
|
||
|
||
while [ $WAIT_TIME -lt 180 ]; do
|
||
sleep 10
|
||
WAIT_TIME=$((WAIT_TIME + 10))
|
||
|
||
# 检查应用健康状态
|
||
if curl -f -s "$HEALTH_URL" > /dev/null 2>&1; then
|
||
print_message $GREEN "✓ 应用启动成功!"
|
||
break
|
||
fi
|
||
|
||
# 显示等待进度
|
||
if [ $((WAIT_TIME % 30)) -eq 0 ]; then
|
||
print_message $BLUE " 已等待 ${WAIT_TIME} 秒..."
|
||
|
||
# 检查应用日志中的迁移信息
|
||
MIGRATION_LOGS=$(docker compose logs qaup-app --tail=10 2>/dev/null | grep -E "(Flyway|migration|Migration)" | tail -2)
|
||
if [ -n "$MIGRATION_LOGS" ]; then
|
||
print_message $BLUE " 迁移进度:"
|
||
echo "$MIGRATION_LOGS" | while read line; do
|
||
print_message $BLUE " $line"
|
||
done
|
||
fi
|
||
|
||
# 检查是否有错误
|
||
ERROR_LOGS=$(docker compose logs qaup-app --tail=5 2>/dev/null | grep -i -E "(error|exception|fail)" || true)
|
||
if [ -n "$ERROR_LOGS" ]; then
|
||
print_message $YELLOW " 检测到可能的错误:"
|
||
echo "$ERROR_LOGS" | while read line; do
|
||
print_message $YELLOW " $line"
|
||
done
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# 10. 验证升级结果
|
||
print_message $BLUE "10. 验证升级结果..."
|
||
|
||
if curl -f -s "$HEALTH_URL" > /dev/null 2>&1; then
|
||
# 获取升级后数据库迁移状态
|
||
print_message $BLUE " 检查数据库迁移状态..."
|
||
AFTER_MIGRATION=$(docker exec qaup-postgres psql -U qaup -d qaup -t -c "SELECT version,description FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 3;" 2>/dev/null || echo "无法获取迁移状态")
|
||
|
||
print_message $GREEN "🎉 升级成功完成!"
|
||
echo ""
|
||
print_message $GREEN "📊 升级信息:"
|
||
print_message $BLUE " 应用状态: 运行中"
|
||
print_message $BLUE " 健康检查: 通过"
|
||
echo ""
|
||
print_message $BLUE "💾 备份信息:"
|
||
print_message $BLUE " 应用备份: $BACKUP_JAR"
|
||
print_message $BLUE " 数据库备份: $BACKUP_FILE"
|
||
echo ""
|
||
print_message $BLUE "📋 升级前迁移状态:"
|
||
echo "$BEFORE_MIGRATION" | while read line; do
|
||
print_message $BLUE " $line"
|
||
done
|
||
echo ""
|
||
print_message $BLUE "📋 升级后迁移状态:"
|
||
echo "$AFTER_MIGRATION" | while read line; do
|
||
print_message $BLUE " $line"
|
||
done
|
||
echo ""
|
||
print_message $BLUE "🔍 验证命令:"
|
||
print_message $BLUE " 查看应用日志: docker compose logs -f qaup-app"
|
||
print_message $BLUE " 检查数据库连接: docker exec qaup-postgres psql -U qaup -d qaup -c 'SELECT version();'"
|
||
print_message $BLUE " 回滚命令: ./rollback.sh $BACKUP_TIMESTAMP"
|
||
|
||
# 创建回滚脚本
|
||
cat > rollback_$BACKUP_TIMESTAMP.sh << EOF
|
||
#!/bin/bash
|
||
echo "正在回滚到版本 $BACKUP_TIMESTAMP..."
|
||
docker compose stop qaup-app
|
||
cp backup/app.jar.backup.$BACKUP_TIMESTAMP app.jar
|
||
docker compose start qaup-app
|
||
echo "回滚完成,请检查应用状态"
|
||
EOF
|
||
chmod +x rollback_$BACKUP_TIMESTAMP.sh
|
||
print_message $BLUE " 自动回滚脚本: rollback_$BACKUP_TIMESTAMP.sh"
|
||
|
||
else
|
||
print_message $RED "❌ 升级失败"
|
||
print_message $BLUE "正在执行自动回滚..."
|
||
|
||
# 自动回滚
|
||
docker compose stop qaup-app
|
||
cp "$BACKUP_JAR" app.jar
|
||
docker compose start qaup-app
|
||
|
||
sleep 30
|
||
|
||
# 验证回滚
|
||
if curl -f -s "$HEALTH_URL" > /dev/null 2>&1; then
|
||
print_message $GREEN "✓ 自动回滚成功"
|
||
print_message $BLUE " 应用已恢复到升级前版本"
|
||
print_message $BLUE " 请检查应用日志: docker compose logs qaup-app"
|
||
else
|
||
print_message $RED "❌ 回滚失败"
|
||
print_message $BLUE " 请手动检查并恢复服务"
|
||
fi
|
||
|
||
echo ""
|
||
print_message $BLUE "📋 详细信息:"
|
||
print_message $BLUE " 应用备份: $BACKUP_JAR"
|
||
print_message $BLUE " 数据库备份: $BACKUP_FILE"
|
||
print_message $BLUE " 升级前状态: $APP_STATUS"
|
||
|
||
exit 1
|
||
fi |