QDAirPortBackend0122/deploy/qaup-service.sh
2026-01-22 13:19:47 +08:00

441 lines
13 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# QAUP 统一服务管理脚本
# 支持管理QAUP核心服务、数据库、缓存和ADXP适配器
set -e
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 配置变量
COMPOSE_FILE="docker-compose.yml"
ADXP_COMPOSE_FILE="docker-compose.adxp.yml"
APP_SERVICE="qaup-app"
DB_SERVICE="qaup-postgres"
REDIS_SERVICE="qaup-redis"
ADXP_SERVICE="adxp-adapter"
print_message() {
echo -e "${1}${2}${NC}"
}
print_header() {
echo ""
print_message $BLUE "=== QAUP 统一服务管理 ==="
print_message $BLUE "当前目录: $(pwd)"
print_message $BLUE "时间: $(date)"
echo ""
}
# 检查必要文件
check_files() {
if [ ! -f "$COMPOSE_FILE" ]; then
print_message $RED "❌ 找不到 $COMPOSE_FILE 文件"
exit 1
fi
if [ ! -f "config.yml" ]; then
print_message $RED "❌ 找不到 config.yml 文件"
exit 1
fi
}
# 启动所有服务
start_all() {
print_message $BLUE "启动所有QAUP服务..."
# 启动基础设施服务
print_message $BLUE "1. 启动数据库服务..."
docker compose up -d $DB_SERVICE
print_message $BLUE "2. 启动缓存服务..."
docker compose up -d $REDIS_SERVICE
# 等待基础设施就绪
print_message $BLUE "等待基础设施服务就绪..."
sleep 30
# 检查数据库状态
if ! docker exec $DB_SERVICE pg_isready -U qaup > /dev/null 2>&1; then
print_message $RED "❌ 数据库启动失败"
return 1
fi
# 检查Redis状态
if ! docker exec $REDIS_SERVICE redis-cli ping > /dev/null 2>&1; then
print_message $RED "❌ Redis启动失败"
return 1
fi
print_message $GREEN "✓ 基础设施服务就绪"
# 启动应用服务
print_message $BLUE "3. 启动应用服务..."
docker compose up -d $APP_SERVICE
# 启动ADXP适配器如果配置文件存在
if [ -f "$ADXP_COMPOSE_FILE" ]; then
print_message $BLUE "4. 启动ADXP适配器..."
docker compose -f $COMPOSE_FILE -f $ADXP_COMPOSE_FILE up -d $ADXP_SERVICE
fi
print_message $GREEN "🎉 所有服务启动完成!"
show_status
}
# 停止所有服务
stop_all() {
print_message $BLUE "停止所有QAUP服务..."
# 停止ADXP适配器
if [ -f "$ADXP_COMPOSE_FILE" ]; then
docker compose -f $COMPOSE_FILE -f $ADXP_COMPOSE_FILE down $ADXP_SERVICE 2>/dev/null || true
fi
# 停止应用服务
docker compose stop $APP_SERVICE 2>/dev/null || true
# 停止缓存服务
docker compose stop $REDIS_SERVICE 2>/dev/null || true
# 停止数据库服务
docker compose stop $DB_SERVICE 2>/dev/null || true
print_message $GREEN "✓ 所有服务已停止"
}
# 重启所有服务
restart_all() {
print_message $BLUE "重启所有QAUP服务..."
stop_all
sleep 5
start_all
}
# 查看服务状态
show_status() {
print_message $BLUE "服务状态:"
echo ""
# 显示服务状态表格
printf "%-20s %-15s %-15s %-10s\n" "服务名" "状态" "端口" "健康检查"
printf "%-20s %-15s %-15s %-10s\n" "--------------------" "---------------" "---------------" "----------"
# 检查各个服务状态
services=(
"$APP_SERVICE:8080:qaup-app"
"$DB_SERVICE:5432:qaup-postgres"
"$REDIS_SERVICE:6379:qaup-redis"
)
for service_info in "${services[@]}"; do
service=$(echo $service_info | cut -d: -f1)
port=$(echo $service_info | cut -d: -f2)
container=$(echo $service_info | cut -d: -f3)
status=$(docker compose ps $service --format json 2>/dev/null | jq -r '.[0].State' 2>/dev/null || echo "unknown")
# 健康检查
if [ "$status" = "running" ]; then
if [ "$service" = "$APP_SERVICE" ]; then
health=$(curl -f -s http://localhost:8080/actuator/health > /dev/null 2>&1 && echo "正常" || echo "异常")
elif [ "$service" = "$DB_SERVICE" ]; then
health=$(docker exec $DB_SERVICE pg_isready -U qaup > /dev/null 2>&1 && echo "正常" || echo "异常")
elif [ "$service" = "$REDIS_SERVICE" ]; then
health=$(docker exec $REDIS_SERVICE redis-cli ping > /dev/null 2>&1 && echo "正常" || echo "异常")
fi
else
health="未运行"
fi
printf "%-20s %-15s %-15s %-10s\n" "$service" "$status" "$port" "$health"
done
# 检查ADXP适配器状态
if [ -f "$ADXP_COMPOSE_FILE" ]; then
adxp_status=$(docker compose -f $COMPOSE_FILE -f $ADXP_COMPOSE_FILE ps $ADXP_SERVICE --format json 2>/dev/null | jq -r '.[0].State' 2>/dev/null || echo "unknown")
adxp_health=$(curl -f -s http://localhost:8086/health > /dev/null 2>&1 && echo "正常" || echo "异常")
printf "%-20s %-15s %-15s %-10s\n" "$ADXP_SERVICE" "$adxp_status" "8086" "$adxp_health"
fi
echo ""
}
# 查看日志
show_logs() {
local service=${1:-""}
local lines=${2:-50}
if [ -n "$service" ]; then
print_message $BLUE "查看 $service 服务日志 (最后 $lines 行):"
docker compose logs --tail=$lines -f $service
else
print_message $BLUE "查看所有服务日志 (最后 $lines 行):"
docker compose logs --tail=$lines -f
fi
}
# 健康检查
health_check() {
print_message $BLUE "执行健康检查..."
local errors=0
# 检查Docker服务
if ! docker info > /dev/null 2>&1; then
print_message $RED "❌ Docker服务不可用"
((errors++))
else
print_message $GREEN "✓ Docker服务正常"
fi
# 检查应用健康状态
if curl -f -s http://localhost:8080/actuator/health > /dev/null 2>&1; then
print_message $GREEN "✓ 应用服务健康检查通过"
else
print_message $RED "❌ 应用服务健康检查失败"
((errors++))
fi
# 检查数据库连接
if docker exec $DB_SERVICE pg_isready -U qaup > /dev/null 2>&1; then
print_message $GREEN "✓ 数据库连接正常"
else
print_message $RED "❌ 数据库连接失败"
((errors++))
fi
# 检查Redis连接
if docker exec $REDIS_SERVICE redis-cli ping > /dev/null 2>&1; then
print_message $GREEN "✓ Redis连接正常"
else
print_message $RED "❌ Redis连接失败"
((errors++))
fi
# 检查磁盘空间
available_space=$(df . | tail -1 | awk '{print $4}')
if [ "$available_space" -gt $((1024*1024)) ]; then # 1GB
print_message $GREEN "✓ 磁盘空间充足"
else
print_message $RED "❌ 磁盘空间不足"
((errors++))
fi
# 检查端口占用
ports=(8080 5432 6379 8086)
for port in "${ports[@]}"; do
if netstat -tuln 2>/dev/null | grep -q ":$port " || ss -tuln 2>/dev/null | grep -q ":$port "; then
print_message $GREEN "✓ 端口 $port 占用正常"
else
print_message $YELLOW "⚠️ 端口 $port 未占用"
fi
done
if [ $errors -eq 0 ]; then
print_message $GREEN "🎉 所有健康检查通过!"
return 0
else
print_message $RED "❌ 发现 $errors 个问题"
return 1
fi
}
# 数据备份
backup_data() {
local backup_dir="backup"
local timestamp=$(date +%Y%m%d_%H%M%S)
print_message $BLUE "开始数据备份..."
mkdir -p "$backup_dir"
# 备份数据库
local db_backup="$backup_dir/qaup_db_backup_$timestamp.sql"
print_message $BLUE "1. 备份数据库..."
if docker exec $DB_SERVICE pg_dump -U qaup qaup > "$db_backup" 2>/dev/null; then
print_message $GREEN "✓ 数据库备份成功: $db_backup"
else
print_message $RED "❌ 数据库备份失败"
return 1
fi
# 备份Redis数据
local redis_backup="$backup_dir/redis_backup_$timestamp.rdb"
print_message $BLUE "2. 备份Redis数据..."
if docker exec $REDIS_SERVICE redis-cli BGSAVE > /dev/null 2>&1; then
sleep 5
docker cp $REDIS_SERVICE:/data/dump.rdb "$redis_backup" 2>/dev/null
if [ -f "$redis_backup" ]; then
print_message $GREEN "✓ Redis备份成功: $redis_backup"
else
print_message $RED "❌ Redis备份失败"
fi
else
print_message $YELLOW "⚠️ Redis备份跳过"
fi
# 备份应用配置
local config_backup="$backup_dir/config_backup_$timestamp.yml"
print_message $BLUE "3. 备份应用配置..."
if cp config.yml "$config_backup"; then
print_message $GREEN "✓ 配置备份成功: $config_backup"
else
print_message $RED "❌ 配置备份失败"
fi
print_message $GREEN "🎉 数据备份完成!"
ls -la "$backup_dir"/*_$timestamp.*
}
# 清理数据
clean_data() {
print_message $YELLOW "⚠️ 这将删除所有数据目录,确认继续吗?(y/N): "
read -r confirmation
if [[ ! $confirmation =~ ^[Yy]$ ]]; then
print_message $BLUE "操作已取消"
return
fi
print_message $BLUE "清理数据目录..."
# 停止所有服务
stop_all
# 删除数据目录
rm -rf data/ logs/ backup/
print_message $GREEN "✓ 数据目录已清理"
print_message $BLUE "请运行 './qaup-service.sh start' 重新初始化数据"
}
# 更新应用
update_app() {
if [ ! -f "new-app.jar" ]; then
print_message $RED "❌ 未找到新版本文件: new-app.jar"
print_message $BLUE "请先将新版本文件重命名为 new-app.jar"
exit 1
fi
print_message $BLUE "开始应用更新..."
# 备份当前应用
local backup_dir="backup"
local timestamp=$(date +%Y%m%d_%H%M%S)
mkdir -p "$backup_dir"
if [ -f "app.jar" ]; then
cp app.jar "$backup_dir/app.jar.backup.$timestamp"
print_message $BLUE "✓ 当前应用已备份"
fi
# 停止应用服务
docker compose stop $APP_SERVICE
# 替换应用文件
if cp new-app.jar app.jar; then
print_message $GREEN "✓ 应用文件更新成功"
else
print_message $RED "❌ 应用文件更新失败"
exit 1
fi
# 启动应用服务
docker compose up -d $APP_SERVICE
# 等待应用启动
print_message $BLUE "等待应用启动..."
sleep 30
# 验证更新结果
if curl -f -s http://localhost:8080/actuator/health > /dev/null 2>&1; then
print_message $GREEN "🎉 应用更新成功!"
else
print_message $RED "❌ 应用更新失败,正在回滚..."
# 回滚应用
if [ -f "$backup_dir/app.jar.backup.$timestamp" ]; then
docker compose stop $APP_SERVICE
cp "$backup_dir/app.jar.backup.$timestamp" app.jar
docker compose up -d $APP_SERVICE
print_message $BLUE "✓ 应用已回滚"
fi
exit 1
fi
}
# 显示帮助信息
show_help() {
print_message $BLUE "QAUP 统一服务管理脚本"
echo ""
print_message $BLUE "使用方法:"
print_message $BLUE " ./qaup-service.sh <command> [options]"
echo ""
print_message $BLUE "可用命令:"
print_message $BLUE " start 启动所有服务"
print_message $BLUE " stop 停止所有服务"
print_message $BLUE " restart 重启所有服务"
print_message $BLUE " status 查看服务状态"
print_message $BLUE " logs [service] 查看日志 (可指定服务名)"
print_message $BLUE " health 执行健康检查"
print_message $BLUE " backup 备份数据"
print_message $BLUE " clean 清理所有数据"
print_message $BLUE " update 更新应用"
print_message $BLUE " help 显示此帮助信息"
echo ""
print_message $BLUE "示例:"
print_message $BLUE " ./qaup-service.sh start"
print_message $BLUE " ./qaup-service.sh logs qaup-app"
print_message $BLUE " ./qaup-service.sh health"
print_message $BLUE " ./qaup-service.sh backup"
}
# 主函数
main() {
check_files
case "${1:-help}" in
start)
start_all
;;
stop)
stop_all
;;
restart)
restart_all
;;
status)
show_status
;;
logs)
show_logs "$2" "${3:-50}"
;;
health)
health_check
;;
backup)
backup_data
;;
clean)
clean_data
;;
update)
update_app
;;
help|--help|-h)
show_help
;;
*)
print_message $RED "❌ 未知命令: $1"
show_help
exit 1
;;
esac
}
# 执行主函数
main "$@"