Files
HAOVP/backend/deploy-ha.sh
T

334 lines
8.9 KiB
Bash

#!/bin/bash
# ============================================================
# 高可用集群部署脚本
# 用法: ./deploy-ha.sh <node-id> <action>
# node-id: 1, 2, 3
# action: init, start, stop, restart, status
# ============================================================
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
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"; }
log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
# 检查参数
if [ $# -lt 2 ]; then
echo "用法: $0 <node-id> <action>"
echo "node-id: 1, 2, 3"
echo "action: init, start, stop, restart, status, mysql-master, mysql-slave, redis-master, redis-slave"
exit 1
fi
NODE_ID=$1
ACTION=$2
ENV_FILE="config/.env.node-0${NODE_ID}"
# 检查环境文件
if [ ! -f "$ENV_FILE" ]; then
log_error "环境文件不存在: $ENV_FILE"
exit 1
fi
# 加载环境变量
log_info "加载环境变量: $ENV_FILE"
export $(grep -v '^#' $ENV_FILE | xargs)
log_info "=========================================="
log_info "节点ID: $NODE_ID"
log_info "主机IP: $HOST_IP"
log_info "操作: $ACTION"
log_info "=========================================="
# 初始化函数
init_node() {
log_step "初始化节点 $NODE_ID..."
# 创建必要目录
log_info "创建数据目录..."
mkdir -p data/mysql data/redis data/nacos data/rocketmq data/minio logs/nginx
# 复制配置文件
log_info "配置文件准备..."
# MySQL配置
if [ "$NODE_ID" == "1" ]; then
cp config/mysql/my-master.cnf config/mysql/my.cnf
log_info "MySQL配置: 主节点"
else
cp config/mysql/my-slave.cnf config/mysql/my.cnf
log_info "MySQL配置: 从节点"
fi
# Redis配置
if [ "$NODE_ID" == "1" ]; then
cp config/redis/redis-master.conf config/redis/redis.conf
log_info "Redis配置: 主节点"
else
cp config/redis/redis-slave.conf config/redis/redis.conf
fi
# RocketMQ Broker配置
if [ "$NODE_ID" == "2" ]; then
cp config/rocketmq/broker-a.conf config/rocketmq/broker.conf
log_info "RocketMQ配置: Broker-A"
elif [ "$NODE_ID" == "3" ]; then
cp config/rocketmq/broker-b.conf config/rocketmq/broker.conf
log_info "RocketMQ配置: Broker-B"
fi
# 设置Docker网络
log_info "创建Docker网络..."
docker network create ha-network 2>/dev/null || true
log_info "节点初始化完成!"
}
# 启动基础设施
start_infrastructure() {
log_step "启动基础设施..."
# 按顺序启动服务
log_info "启动MySQL..."
docker compose --env-file $ENV_FILE up -d mysql
sleep 30
log_info "等待MySQL就绪..."
until docker exec mysql mysqladmin ping -h localhost -uroot -p${MYSQL_ROOT_PASSWORD} --silent 2>/dev/null; do
log_warn "等待MySQL启动..."
sleep 5
done
log_info "MySQL已就绪"
# 初始化数据库 (仅主节点)
if [ "$NODE_ID" == "1" ]; then
log_info "初始化数据库..."
docker exec -i mysql mysql -uroot -p${MYSQL_ROOT_PASSWORD} < sql/init.sql 2>/dev/null || true
log_info "数据库初始化完成"
fi
log_info "启动Redis..."
docker compose --env-file $ENV_FILE up -d redis redis-sentinel
sleep 10
log_info "启动Nacos..."
docker compose --env-file $ENV_FILE up -d nacos
sleep 30
log_info "等待Nacos就绪..."
until curl -s http://localhost:8848/nacos/v1/console/health/liveness | grep -q "UP" 2>/dev/null; do
log_warn "等待Nacos启动..."
sleep 5
done
log_info "Nacos已就绪"
log_info "启动RocketMQ NameServer..."
docker compose --env-file $ENV_FILE up -d rmqnamesrv
sleep 10
# Broker仅Node-02和Node-03启动
if [ "$NODE_ID" != "1" ]; then
log_info "启动RocketMQ Broker..."
docker compose --env-file $ENV_FILE up -d rmqbroker
sleep 10
fi
log_info "启动MinIO..."
docker compose --env-file $ENV_FILE up -d minio
sleep 10
log_info "启动Sentinel..."
docker compose --env-file $ENV_FILE up -d sentinel
log_info "基础设施启动完成!"
}
# 启动微服务
start_microservices() {
log_step "启动微服务..."
log_info "启动网关服务..."
docker compose --env-file $ENV_FILE up -d video-gateway
sleep 15
log_info "启动认证服务..."
docker compose --env-file $ENV_FILE up -d video-auth
sleep 15
log_info "启动用户服务..."
docker compose --env-file $ENV_FILE up -d video-user
sleep 15
log_info "启动内容服务..."
docker compose --env-file $ENV_FILE up -d video-content
sleep 15
log_info "启动评论服务..."
docker compose --env-file $ENV_FILE up -d video-comment
sleep 15
log_info "启动推荐服务..."
docker compose --env-file $ENV_FILE up -d video-recommend
sleep 15
log_info "启动管理后台服务..."
docker compose --env-file $ENV_FILE up -d video-admin
log_info "微服务启动完成!"
}
# 启动Nginx
start_nginx() {
log_step "启动Nginx负载均衡..."
docker compose --env-file $ENV_FILE up -d nginx
log_info "Nginx启动完成!"
}
# 停止所有服务
stop_all() {
log_step "停止所有服务..."
docker compose --env-file $ENV_FILE down
log_info "所有服务已停止"
}
# 查看状态
check_status() {
log_step "服务状态检查..."
echo ""
docker compose --env-file $ENV_FILE ps
echo ""
log_info "检查服务健康状态..."
services=("video-gateway:9000" "video-auth:9001" "video-user:9002" "video-content:9003" "video-comment:9004" "video-recommend:9005" "video-admin:9006")
for service in "${services[@]}"; do
name=$(echo $service | cut -d':' -f1)
port=$(echo $service | cut -d':' -f2)
if curl -s "http://localhost:$port/actuator/health" | grep -q "UP" 2>/dev/null; then
log_info "$name: ${GREEN}健康${NC}"
else
log_warn "$name: ${YELLOW}未响应${NC}"
fi
done
}
# 配置MySQL主从复制
setup_mysql_replication() {
log_step "配置MySQL主从复制..."
if [ "$NODE_ID" == "1" ]; then
log_info "配置主节点..."
# 创建复制用户
docker exec mysql mysql -uroot -p${MYSQL_ROOT_PASSWORD} <<EOF
CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED BY 'repl_password_2024';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;
EOF
log_info "主节点配置完成"
else
log_info "配置从节点..."
log_warn "请在主节点获取MASTER_LOG_FILE和MASTER_LOG_POS后手动执行:"
echo ""
echo "CHANGE MASTER TO"
echo " MASTER_HOST='192.168.1.101',"
echo " MASTER_USER='repl',"
echo " MASTER_PASSWORD='repl_password_2024',"
echo " MASTER_LOG_FILE='<从主节点获取>',"
echo " MASTER_LOG_POS=<从主节点获取>;"
echo "START SLAVE;"
echo ""
fi
}
# 配置Redis主从复制
setup_redis_replication() {
log_step "配置Redis主从复制..."
if [ "$NODE_ID" != "1" ]; then
log_info "配置从节点连接主节点..."
docker exec redis redis-cli -a ${REDIS_PASSWORD} REPLICAOF 192.168.1.101 6379
log_info "Redis从节点配置完成"
else
log_info "当前为主节点,无需配置"
fi
}
# 初始化MinIO
init_minio() {
log_step "初始化MinIO..."
# 等待MinIO就绪
until curl -s http://localhost:9000/minio/health/live > /dev/null 2>&1; do
log_warn "等待MinIO启动..."
sleep 5
done
log_info "创建存储桶..."
docker run --rm --network ha-network minio/mc <<EOF
mc alias set myminio http://minio:9000 minioadmin minioadmin123
mc mb myminio/video-platform --ignore-existing
mc anonymous set download myminio/video-platform
mc ls myminio
EOF
log_info "MinIO初始化完成"
}
# 主流程
case $ACTION in
init)
init_node
;;
start)
start_infrastructure
init_minio
start_microservices
start_nginx
;;
stop)
stop_all
;;
restart)
stop_all
sleep 10
start_infrastructure
start_microservices
start_nginx
;;
status)
check_status
;;
mysql-master|mysql-slave)
setup_mysql_replication
;;
redis-master|redis-slave)
setup_redis_replication
;;
infra)
start_infrastructure
;;
services)
start_microservices
;;
*)
log_error "未知操作: $ACTION"
echo "可用操作: init, start, stop, restart, status, mysql-master, mysql-slave, redis-master, redis-slave, infra, services"
exit 1
;;
esac
log_info "=========================================="
log_info "操作完成: $ACTION"
log_info "=========================================="