提交 7fce5681 authored 作者: PGY's avatar PGY

```feat(自动化部署脚本): 移除统一平台定时脚本位置,新增统一平台和运维定时脚本,

移除了以下自动化部署脚本:
- check_nacos_and_restart.sh: 检查 Nacos 并重启 ujava2 容器服务的脚本
- clear_deleted_files.sh: 定时清理被进程占用的已删除文件的脚本
- monitor_exapi_and_malan.sh: 监控 exapi 和 malan 服务的脚本
- mysql_backup.sh: MySQL 数据库备份脚本,包含自动清理30天前备份的功能
上级 63901ddc
......@@ -3,9 +3,8 @@
# ==================== 配置区 ====================
CONTAINER_NAME="umysql"
DB_USER="root"
PASSWORD_LIST=("dNrprU&2S" "Ubains@123") # 按顺序尝试
HOST_BACKUP_DIR="/opt/mysql" # 宿主机备份目录
LOG_FILE="/var/log/mysql_backup.log"
LOG_FILE="/var/log/backup_mysql_databases.log"
RETENTION_DAYS=30
TARGET_DBS=("devops" "devops_voice" "huazhao2" "nacos_mysql" "offline" "ubains" "wifi" "voice")
......@@ -18,6 +17,10 @@ log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
get_mysql_password() {
docker exec "$CONTAINER_NAME" printenv MYSQL_ROOT_PASSWORD 2>/dev/null
}
# ==================== 初始化 ====================
mkdir -p "$HOST_BACKUP_DIR/$DATE"
touch "$LOG_FILE"
......@@ -30,18 +33,18 @@ if [ $? -ne 0 ]; then
exit 1
fi
# ==================== 尝试连接并获取存在的数据库 ====================
DB_PASSWORD=""
for pwd in "${PASSWORD_LIST[@]}"; do
if docker exec "$CONTAINER_NAME" mysql -u"$DB_USER" -p"$pwd" -Nse "SELECT 1;" >/dev/null 2>&1; then
DB_PASSWORD="$pwd"
log "✅ 使用密码成功连接数据库"
break
fi
done
DB_PASSWORD=$(get_mysql_password)
if [ -z "$DB_PASSWORD" ]; then
log "❌ 所有密码尝试失败,无法连接数据库"
docker exec "$CONTAINER_NAME" rm -rf "$CONTAINER_TMP_DIR"
exit 1
fi
# 测试连接
if docker exec "$CONTAINER_NAME" mysql -u"$DB_USER" -p"$DB_PASSWORD" -Nse "SELECT 1;" >/dev/null 2>&1; then
log "✅ 使用密码成功连接数据库"
else
log "❌ 使用密码连接数据库失败"
docker exec "$CONTAINER_NAME" rm -rf "$CONTAINER_TMP_DIR"
exit 1
fi
......
#!/bin/bash
# clear_deleted_files.sh - 定时清理被进程占用的已删除文件
LOG_FILE="/var/log/clear_deleted.log"
LOG_FILE="/var/log/cleanup_deleted_files.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] 开始检查被占用的已删除文件..." >> "$LOG_FILE"
......
#!/bin/bash
# 宿主机上的脚本:检查 EMQX,如果容器未运行则重启 uemqx 容器
LOG_FILE="/var/log/monitor_emqx_service.log"
log() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
check_emqx() {
# 检查 uemqx 容器是否正在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uemqx"; then
# 通过 docker exec 检查 EMQX 进程是否在容器内运行
if docker exec uemqx pgrep -f "emqx" >/dev/null 2>&1; then
# 检查EMQX是否在运行状态(使用EMQX自带的命令)
if docker exec uemqx emqx_ctl status >/dev/null 2>&1; then
# 额外验证EMQX是否真正可用
status_output=$(docker exec uemqx emqx_ctl status 2>&1)
if echo "$status_output" | grep -q "is started"; then
log "EMQX 服务状态正常"
return 0
else
log "警告: emqx_ctl 命令执行成功,但返回意外状态"
return 1
fi
else
log "警告: 容器正在运行,EMQX 进程存在,但 emqx_ctl 命令执行失败"
return 1
fi
else
log "警告: 容器正在运行,但在容器内未找到 EMQX 进程"
return 1
fi
else
log "信息: uemqx 容器未运行"
return 1
fi
}
restart_emqx_container() {
log "EMQX 未运行。正在尝试重启容器 'uemqx'..."
# 检查容器是否存在(不仅仅是运行状态)
if docker ps -a --format '{{.Names}}' | grep -Fxq "uemqx"; then
# 停止可能挂起的容器
docker stop uemqx >/dev/null 2>&1 || true
# 容器存在但未运行,尝试启动
if docker start uemqx; then
log "成功: EMQX 容器已成功启动。"
# 等待几秒让服务启动
log "信息: 等待 30 秒让 EMQX 服务完全启动..."
for i in {1..30}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uemqx"; then
log "信息: EMQX 容器现在正在运行。"
# 再次检查EMQX进程是否已启动
if docker exec uemqx pgrep -f "emqx" >/dev/null 2>&1; then
log "信息: EMQX 进程在容器内正在运行。"
# 等待一段时间后再次检查服务状态
log "信息: 等待 10 秒后检查服务状态..."
sleep 10
if docker exec uemqx emqx_ctl status >/dev/null 2>&1; then
status_output=$(docker exec uemqx emqx_ctl status 2>&1)
if echo "$status_output" | grep -q "is started"; then
log "信息: EMQX 服务状态正常。"
return 0
else
log "错误: EMQX 进程运行中,但服务状态异常。"
return 1
fi
else
log "错误: EMQX 进程运行中,但服务状态检查失败。"
return 1
fi
else
log "错误: EMQX 进程在容器内未运行。"
return 1
fi
else
log "错误: EMQX 容器在启动后不久就停止了。"
return 1
fi
else
log "错误: 无法启动 EMQX 容器。"
return 1
fi
else
log "错误: 容器 'uemqx' 不存在!"
log "信息: 您可能需要手动重新创建 EMQX 容器。"
return 1
fi
}
# 主逻辑
log "开始检查 EMQX 服务状态..."
if check_emqx; then
log "EMQX 正在运行且状态正常。"
else
log "EMQX 无响应或容器未运行。"
restart_emqx_container
# 检查重启后是否正常工作
if check_emqx; then
log "EMQX 已成功重启,现在状态正常。"
else
log "错误: 重启尝试后 EMQX 仍无响应。"
log "信息: 请使用以下命令检查容器日志: docker logs uemqx"
fi
fi
\ No newline at end of file
#!/bin/bash
# 宿主机上的脚本:检查 MySQL,如果容器未运行则重启 umysql 容器
LOG_FILE="/var/log/monitor_mysql_service.log"
log() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
get_mysql_password() {
docker exec umysql printenv MYSQL_ROOT_PASSWORD 2>/dev/null
}
check_mysql() {
if docker ps --format '{{.Names}}' | grep -Fxq "umysql"; then
local mysql_password
mysql_password=$(get_mysql_password)
if [ -z "$mysql_password" ]; then
return 1
fi
# 尝试连接数据库
if docker exec umysql mysqladmin ping -h localhost -u root -p"$mysql_password" 2>/dev/null; then
# 尝试执行一个简单的SQL查询来确认数据库功能正常
if docker exec umysql mysql -u root -p"$mysql_password" -e "SELECT 1;" >/dev/null 2>&1; then
log "MySQL 服务连接正常,可以执行SQL查询"
return 0
else
log "警告: MySQL 服务可以ping通,但无法执行SQL查询"
return 1
fi
else
log "警告: 无法连接到 MySQL 服务"
return 1
fi
else
log "信息: umysql 容器未运行"
return 1
fi
}
restart_mysql_container() {
log "MySQL 未运行。正在尝试重启容器 'umysql'..."
# 检查容器是否存在(不仅仅是运行状态)
if docker ps -a --format '{{.Names}}' | grep -Fxq "umysql"; then
# 停止可能挂起的容器
docker stop umysql >/dev/null 2>&1 || true
# 容器存在但未运行,尝试启动
if docker start umysql; then
log "成功: MySQL 容器已成功启动。"
# 等待几秒让服务启动
log "信息: 等待 60 秒让 MySQL 服务完全启动..."
for i in {1..60}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "umysql"; then
log "信息: MySQL 容器现在正在运行。"
# 等待一段时间后检查服务状态
log "信息: 等待 20 秒后检查服务状态..."
sleep 60
local mysql_password
mysql_password=$(get_mysql_password)
if [ -z "$mysql_password" ]; then
return 1
fi
if docker exec umysql mysqladmin ping -h localhost -u root -p"$mysql_password" >/dev/null 2>&1; then
if docker exec umysql mysql -u root -p"$mysql_password" -e "SELECT 1;" >/dev/null 2>&1; then
log "信息: MySQL 服务状态正常。"
return 0
else
log "错误: MySQL 服务运行中,但无法执行SQL查询。"
return 1
fi
else
log "错误: MySQL 服务状态检查失败。"
return 1
fi
else
log "错误: MySQL 容器在启动后不久就停止了。"
return 1
fi
else
log "错误: 无法启动 MySQL 容器。"
return 1
fi
else
log "错误: 容器 'umysql' 不存在!"
log "信息: 您可能需要手动重新创建 MySQL 容器。"
return 1
fi
}
# 主逻辑
log "开始检查 MySQL 服务状态..."
if check_mysql; then
log "MySQL 正在运行且状态正常。"
else
log "MySQL 无响应或容器未运行。"
restart_mysql_container
# 检查重启后是否正常工作
if check_mysql; then
log "MySQL 已成功重启,现在状态正常。"
else
log "错误: 重启尝试后 MySQL 仍无响应。"
log "信息: 请使用以下命令检查容器日志: docker logs umysql"
fi
fi
\ No newline at end of file
#!/bin/bash
# 宿主机上的脚本:检查 Nacos,失败则重启 ujava2 容器中的服务
LOG_FILE="/var/log/monitor_nacos_service.log"
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
check_nacos() {
......@@ -33,8 +38,10 @@ restart_in_container() {
}
# 主逻辑
log "开始检查 Nacos 服务状态..."
if check_nacos; then
log "Nacos is healthy."
else
log "Nacos is not responding."
restart_in_container
fi
fi
\ No newline at end of file
#!/bin/bash
# ==================== 配置区域 ====================
# 可在此处配置要监控的容器名称,默认为ujava2
CONTAINER_NAME="${UJAVA_CONTAINER_NAME:-${1:-ujava2}}"
LOG_FILE="/var/log/monitor_${CONTAINER_NAME}_service.log"
# ==================== 日志函数 ====================
log() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
check_ujava() {
# 检查指定的 ujava 容器是否正在运行
if docker ps --format '{{.Names}}' | grep -Fxq "$CONTAINER_NAME"; then
# 获取运行中的Java进程列表
running_processes=$(docker exec "$CONTAINER_NAME" ps aux | grep -E "java.*\.jar|ubains" | grep -v grep)
if [ -n "$running_processes" ]; then
log "检测到容器中有Java进程在运行"
log "运行中的Java进程: $(echo "$running_processes" | wc -l) 个"
# 定义服务目录和JAR文件的对应关系
declare -A service_map
service_map["/var/www/java/auth-sso-auth"]="ubains-auth.jar"
service_map["/var/www/java/auth-sso-gatway"]="ubains-gateway.jar"
service_map["/var/www/java/auth-sso-system"]="ubains-modules-system.jar"
service_map["/var/www/java/api-java-meeting2.0"]="ubains-meeting-inner-api-1.0-SNAPSHOT"
service_map["/var/www/java/external-meeting-api"]="ubains-meeting-api-1.0-SNAPSHOT.jar"
service_map["/var/www/java/api-dubbo-meeting-control"]="ubains-dubbo-meeting-control"
service_map["/var/www/java/api-dubbo-smc-three"]="ubains-dubbo-smc-three-0.0.1"
missing_services=()
active_services=()
# 检查每个服务是否在运行
for dir in "${!service_map[@]}"; do
jar_file="${service_map[$dir]}"
if echo "$running_processes" | grep -q "$jar_file"; then
active_services+=("$jar_file")
else
missing_services+=("$dir:$jar_file")
fi
done
if [ ${#missing_services[@]} -eq 0 ]; then
log "所有预期的Java进程都在运行中 (共 ${#active_services[@]} 个)"
return 0
else
log "警告: 以下服务未运行: ${missing_services[*]}"
log "信息: 以下服务正在运行: ${active_services[*]}"
return 1
fi
else
log "警告: 容器运行中,但未检测到Java进程"
# 返回1表示服务不正常
return 1
fi
else
log "信息: 容器 $CONTAINER_NAME 未运行"
return 1
fi
}
restart_missing_services() {
log "检测到服务缺失,正在尝试启动缺失的服务..."
# 定义服务目录和JAR文件的对应关系
declare -A service_map
service_map["/var/www/java/auth-sso-auth"]="ubains-auth.jar"
service_map["/var/www/java/auth-sso-gatway"]="ubains-gateway.jar"
service_map["/var/www/java/auth-sso-system"]="ubains-modules-system.jar"
service_map["/var/www/java/api-java-meeting2.0"]="ubains-meeting-inner-api-1.0-SNAPSHOT"
service_map["/var/www/java/external-meeting-api"]="ubains-meeting-api-1.0-SNAPSHOT.jar"
service_map["/var/www/java/api-dubbo-meeting-control"]="ubains-dubbo-meeting-control"
service_map["/var/www/java/api-dubbo-smc-three"]="ubains-dubbo-smc-three-0.0.1"
# 统计启动了多少服务
started_count=0
# 遍历每个服务,检查是否运行,如果没有则启动
for dir in "${!service_map[@]}"; do
jar_file="${service_map[$dir]}"
# 检查服务是否已经运行
running_processes=$(docker exec "$CONTAINER_NAME" ps aux | grep -E "java.*\.jar|ubains" | grep -v grep)
if ! echo "$running_processes" | grep -q "$jar_file"; then
log "启动服务: $jar_file 在目录 $dir"
# 检查JAR文件是否存在
if docker exec -w "$dir" "$CONTAINER_NAME" test -f "$jar_file\.jar"; then
# 直接执行Java命令启动服务,而不是运行run.sh
docker exec -d -w "$dir" "$CONTAINER_NAME" sh -c "nohup java -Xms1024m -Xmx1024m -jar -DAPP_CONFIG=./config $jar_file\.jar > log.out 2>&1 &"
log "已尝试启动 $jar_file"
((started_count++))
elif docker exec -w "$dir" "$CONTAINER_NAME" test -f "$jar_file-0.0.1-SNAPSHOT\.jar"; then
# 对于带版本号的JAR文件
docker exec -d -w "$dir" "$CONTAINER_NAME" sh -c "nohup java -Xms1024m -Xmx1024m -jar -DAPP_CONFIG=./config $jar_file-0.0.1-SNAPSHOT\.jar > log.out 2>&1 &"
log "已尝试启动 $jar_file-0.0.1-SNAPSHOT.jar"
((started_count++))
elif docker exec -w "$dir" "$CONTAINER_NAME" test -f "run.sh"; then
# 如果JAR文件不存在但run.sh存在,安全地执行run.sh(传递参数以避免默认执行start)
docker exec -d -w "$dir" "$CONTAINER_NAME" sh -c "./run.sh start"
log "已尝试使用run.sh启动 $jar_file"
((started_count++))
else
log "错误: JAR文件和run.sh脚本在 $dir 目录中都不存在"
fi
else
log "服务 $jar_file 已经在运行"
fi
done
if [ $started_count -gt 0 ]; then
log "成功启动了 $started_count 个服务,等待服务启动..."
return 0
else
log "没有需要启动的服务"
return 0
fi
}
wait_for_services_to_start() {
log "开始监控服务启动状态,最多等待10分钟..."
# 循环检查服务是否启动成功,最多等待10次,每次等待1分钟
for i in {1..10}; do
log "等待第 $i 分钟,检查服务是否已启动..."
# 检查是否还有缺失的服务
running_processes=$(docker exec "$CONTAINER_NAME" ps aux | grep -E "java.*\.jar|ubains" | grep -v grep)
missing_services=()
# 定义服务目录和JAR文件的对应关系
declare -A service_map
service_map["/var/www/java/auth-sso-auth"]="ubains-auth.jar"
service_map["/var/www/java/auth-sso-gatway"]="ubains-gateway.jar"
service_map["/var/www/java/auth-sso-system"]="ubains-modules-system.jar"
service_map["/var/www/java/api-java-meeting2.0"]="ubains-meeting-inner-api-1.0-SNAPSHOT"
service_map["/var/www/java/external-meeting-api"]="ubains-meeting-api-1.0-SNAPSHOT.jar"
service_map["/var/www/java/api-dubbo-meeting-control"]="ubains-dubbo-meeting-control"
service_map["/var/www/java/api-dubbo-smc-three"]="ubains-dubbo-smc-three-0.0.1"
# 检查每个服务是否在运行
for dir in "${!service_map[@]}"; do
jar_file="${service_map[$dir]}"
if ! echo "$running_processes" | grep -q "$jar_file"; then
missing_services+=("$dir:$jar_file")
fi
done
if [ ${#missing_services[@]} -eq 0 ]; then
log "恭喜!所有服务都已成功启动。"
return 0
else
log "仍有 ${#missing_services[@]} 个服务未启动: ${missing_services[*]}"
fi
# 等待1分钟
sleep 60
done
log "已等待10分钟,仍有服务未能启动,将重启整个容器。"
return 1
}
restart_ujava_container() {
log "容器 $CONTAINER_NAME 服务不正常。正在尝试重启容器 '$CONTAINER_NAME'..."
# 检查容器是否存在(不仅仅是运行状态)
if docker ps -a --format '{{.Names}}' | grep -Fxq "$CONTAINER_NAME"; then
# 停止可能挂起的容器
docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
# 容器存在但未运行,尝试启动
if docker start "$CONTAINER_NAME"; then
log "成功: 容器 $CONTAINER_NAME 已成功启动。"
# 等待几分钟让Java服务启动
log "信息: 等待 90 秒让 Java 服务完全启动..."
for i in {1..90}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "$CONTAINER_NAME"; then
log "信息: 容器 $CONTAINER_NAME 现在正在运行。"
# 启动缺失的服务
restart_missing_services
# 检查Java进程是否已启动
log "信息: 检查服务状态..."
if check_ujava; then
log "信息: 容器 $CONTAINER_NAME 服务状态正常。"
return 0
else
log "错误: 容器 $CONTAINER_NAME 进程运行中,但服务状态异常。"
return 1
fi
else
log "错误: 容器 $CONTAINER_NAME 在启动后不久就停止了。"
return 1
fi
else
log "错误: 无法启动容器 $CONTAINER_NAME。"
return 1
fi
else
log "错误: 容器 '$CONTAINER_NAME' 不存在!"
log "信息: 您可能需要手动重新创建 $CONTAINER_NAME 容器。"
return 1
fi
}
# 主逻辑
log "开始检查容器 $CONTAINER_NAME 服务状态..."
if check_ujava; then
log "容器 $CONTAINER_NAME 正在运行且状态正常。"
else
log "容器 $CONTAINER_NAME 服务不完整或容器未运行。"
# 如果容器在运行但服务不完整,尝试启动缺失的服务
if docker ps --format '{{.Names}}' | grep -Fxq "$CONTAINER_NAME"; then
# 先获取当前运行的服务状态
running_processes=$(docker exec "$CONTAINER_NAME" ps aux | grep -E "java.*\.jar|ubains" | grep -v grep)
# 如果没有任何Java进程在运行,可能是所有服务都崩溃了,直接重启容器
if [ -z "$running_processes" ]; then
log "警告: 检测到没有任何Java进程在运行,尝试重启整个容器。"
restart_ujava_container
else
# 否则,尝试启动缺失的服务
restart_missing_services
# 检查重启后是否正常工作
if check_ujava; then
log "容器 $CONTAINER_NAME 服务已恢复,现在状态正常。"
else
log "容器 $CONTAINER_NAME 服务仍然不正常,尝试重启整个容器。"
restart_ujava_container
fi
fi
else
# 如果容器不在运行,直接重启容器
restart_ujava_container
fi
# 最终检查
if check_ujava; then
log "容器 $CONTAINER_NAME 已成功恢复,现在状态正常。"
else
log "错误: 尝试恢复后 $CONTAINER_NAME 仍无响应。"
log "信息: 请使用以下命令检查容器日志: docker logs $CONTAINER_NAME"
fi
fi
\ No newline at end of file
#!/bin/bash
# ==================== 配置区 ====================
CONTAINER_NAME="umysql"
DB_USER="root"
HOST_BACKUP_DIR="/opt/mysql" # 宿主机备份目录
LOG_FILE="/var/log/backup_mysql_databases.log"
RETENTION_DAYS=30
TARGET_DBS=("devops" "devops_voice" "huazhao2" "nacos_mysql" "offline" "ubains" "wifi" "voice")
DATE=$(date +"%Y%m%d")
CONTAINER_TMP_DIR="/tmp/mysql_backup_$$.sql.gz" # 容器内临时目录(带PID防冲突)
# ==================== 日志函数 ====================
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
get_mysql_password() {
docker exec "$CONTAINER_NAME" printenv MYSQL_ROOT_PASSWORD 2>/dev/null
}
# ==================== 初始化 ====================
mkdir -p "$HOST_BACKUP_DIR/$DATE"
touch "$LOG_FILE"
log "===== 开始备份任务 (容器: $CONTAINER_NAME) ====="
# 在容器内创建临时目录
docker exec "$CONTAINER_NAME" mkdir -p "$CONTAINER_TMP_DIR"
if [ $? -ne 0 ]; then
log "❌ 无法在容器内创建临时目录,请检查容器是否运行。"
exit 1
fi
DB_PASSWORD=$(get_mysql_password)
if [ -z "$DB_PASSWORD" ]; then
docker exec "$CONTAINER_NAME" rm -rf "$CONTAINER_TMP_DIR"
exit 1
fi
# 测试连接
if docker exec "$CONTAINER_NAME" mysql -u"$DB_USER" -p"$DB_PASSWORD" -Nse "SELECT 1;" >/dev/null 2>&1; then
log "✅ 使用密码成功连接数据库"
else
log "❌ 使用密码连接数据库失败"
docker exec "$CONTAINER_NAME" rm -rf "$CONTAINER_TMP_DIR"
exit 1
fi
# 获取容器中实际存在的数据库列表
EXISTING_DBS_RAW=$(docker exec "$CONTAINER_NAME" mysql -u"$DB_USER" -p"$DB_PASSWORD" -Nse "SHOW DATABASES;" 2>/dev/null)
mapfile -t EXISTING_DBS <<< "$EXISTING_DBS_RAW"
declare -A DB_EXISTS
for db in "${EXISTING_DBS[@]}"; do
DB_EXISTS["$db"]=1
done
# ==================== 备份每个目标数据库 ====================
SUCCESS_COUNT=0
for db in "${TARGET_DBS[@]}"; do
if [[ -n "${DB_EXISTS[$db]}" ]]; then
CONTAINER_DUMP_FILE="$CONTAINER_TMP_DIR/${db}.sql.gz"
HOST_DUMP_FILE="$HOST_BACKUP_DIR/$DATE/${db}.sql.gz"
log "开始备份数据库: $db"
# 在容器内执行 mysqldump + gzip
docker exec "$CONTAINER_NAME" \
sh -c "mysqldump -u'$DB_USER' -p'$DB_PASSWORD' --single-transaction --routines --triggers --events '$db' | gzip > '$CONTAINER_DUMP_FILE'"
if [ $? -eq 0 ] && docker exec "$CONTAINER_NAME" [ -s "$CONTAINER_DUMP_FILE" ]; then
# 从容器复制到宿主机
docker cp "$CONTAINER_NAME:$CONTAINER_DUMP_FILE" "$HOST_DUMP_FILE"
if [ $? -eq 0 ] && [ -s "$HOST_DUMP_FILE" ]; then
log "✅ 备份成功: $db -> $HOST_DUMP_FILE"
((SUCCESS_COUNT++))
else
log "❌ 复制到宿主机失败: $db"
[ -f "$HOST_DUMP_FILE" ] && rm -f "$HOST_DUMP_FILE"
fi
else
log "❌ 容器内备份失败: $db"
fi
# 立即删除容器内的临时文件(无论成功与否)
docker exec "$CONTAINER_NAME" rm -f "$CONTAINER_DUMP_FILE"
else
log "⚠️ 跳过: 数据库 $db 不存在"
fi
done
# 清理容器内临时目录
docker exec "$CONTAINER_NAME" rm -rf "$CONTAINER_TMP_DIR"
log "本次共成功备份 $SUCCESS_COUNT 个数据库"
# ==================== 清理超过30天的旧备份 ====================
log "开始清理超过 $RETENTION_DAYS 天的旧备份..."
find "$HOST_BACKUP_DIR" -maxdepth 1 -type d -name "????????" -mtime +$RETENTION_DAYS -exec rm -rf {} + 2>/dev/null
log "===== 备份任务结束 ====="
#!/bin/bash
# clear_deleted_files.sh - 定时清理被进程占用的已删除文件
LOG_FILE="/var/log/cleanup_deleted_files.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] 开始检查被占用的已删除文件..." >> "$LOG_FILE"
# 使用 lsof +L1 查找 link count 为 0(即已删除)但仍被打开的文件
DELETED_ENTRIES=$(lsof +L1 2>/dev/null | grep -v "COMMAND")
if [ -z "$DELETED_ENTRIES" ]; then
echo "[$DATE] 未发现被占用的已删除文件。" >> "$LOG_FILE"
exit 0
fi
echo "[$DATE] 发现以下被占用的已删除文件:" >> "$LOG_FILE"
echo "$DELETED_ENTRIES" >> "$LOG_FILE"
# 提取唯一 PID 列表
PIDS=$(echo "$DELETED_ENTRIES" | awk 'NR>1 {print $2}' | sort -u)
for PID in $PIDS; do
if ! kill -0 "$PID" 2>/dev/null; then
echo "[$DATE] PID $PID 已不存在,跳过。" >> "$LOG_FILE"
continue
fi
CMD=$(ps -p "$PID" -o comm= 2>/dev/null | tr -d ' ')
echo "[$DATE] 处理进程: PID=$PID, CMD=$CMD" >> "$LOG_FILE"
# 尝试发送 SIGHUP(适用于 Nginx、rsyslog 等支持 reload 的服务)
if kill -0 "$PID" 2>/dev/null; then
echo "[$DATE] 向 PID $PID 发送 SIGHUP 信号..." >> "$LOG_FILE"
kill -HUP "$PID" 2>/dev/null && continue
fi
# 若 SIGHUP 无效或不支持,记录警告(不强制 kill,避免服务中断)
echo "[$DATE] WARNING: 无法通过 SIGHUP 释放 PID $PID 的文件句柄。建议手动处理或配置 logrotate。" >> "$LOG_FILE"
done
echo "[$DATE] 检查完成。" >> "$LOG_FILE"
#!/bin/bash
# 宿主机上的脚本:检查 EMQX,如果容器未运行则重启 uemqx 容器
LOG_FILE="/var/log/monitor_emqx_service.log"
log() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
check_emqx() {
# 检查 uemqx 容器是否正在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uemqx"; then
# 通过 docker exec 检查 EMQX 进程是否在容器内运行
if docker exec uemqx pgrep -f "emqx" >/dev/null 2>&1; then
# 检查EMQX是否在运行状态(使用EMQX自带的命令)
if docker exec uemqx emqx_ctl status >/dev/null 2>&1; then
# 额外验证EMQX是否真正可用
status_output=$(docker exec uemqx emqx_ctl status 2>&1)
if echo "$status_output" | grep -q "is started"; then
log "EMQX 服务状态正常"
return 0
else
log "警告: emqx_ctl 命令执行成功,但返回意外状态"
return 1
fi
else
log "警告: 容器正在运行,EMQX 进程存在,但 emqx_ctl 命令执行失败"
return 1
fi
else
log "警告: 容器正在运行,但在容器内未找到 EMQX 进程"
return 1
fi
else
log "信息: uemqx 容器未运行"
return 1
fi
}
restart_emqx_container() {
log "EMQX 未运行。正在尝试重启容器 'uemqx'..."
# 检查容器是否存在(不仅仅是运行状态)
if docker ps -a --format '{{.Names}}' | grep -Fxq "uemqx"; then
# 停止可能挂起的容器
docker stop uemqx >/dev/null 2>&1 || true
# 容器存在但未运行,尝试启动
if docker start uemqx; then
log "成功: EMQX 容器已成功启动。"
# 等待几秒让服务启动
log "信息: 等待 30 秒让 EMQX 服务完全启动..."
for i in {1..30}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uemqx"; then
log "信息: EMQX 容器现在正在运行。"
# 再次检查EMQX进程是否已启动
if docker exec uemqx pgrep -f "emqx" >/dev/null 2>&1; then
log "信息: EMQX 进程在容器内正在运行。"
# 等待一段时间后再次检查服务状态
log "信息: 等待 10 秒后检查服务状态..."
sleep 10
if docker exec uemqx emqx_ctl status >/dev/null 2>&1; then
status_output=$(docker exec uemqx emqx_ctl status 2>&1)
if echo "$status_output" | grep -q "is started"; then
log "信息: EMQX 服务状态正常。"
return 0
else
log "错误: EMQX 进程运行中,但服务状态异常。"
return 1
fi
else
log "错误: EMQX 进程运行中,但服务状态检查失败。"
return 1
fi
else
log "错误: EMQX 进程在容器内未运行。"
return 1
fi
else
log "错误: EMQX 容器在启动后不久就停止了。"
return 1
fi
else
log "错误: 无法启动 EMQX 容器。"
return 1
fi
else
log "错误: 容器 'uemqx' 不存在!"
log "信息: 您可能需要手动重新创建 EMQX 容器。"
return 1
fi
}
# 主逻辑
log "开始检查 EMQX 服务状态..."
if check_emqx; then
log "EMQX 正在运行且状态正常。"
else
log "EMQX 无响应或容器未运行。"
restart_emqx_container
# 检查重启后是否正常工作
if check_emqx; then
log "EMQX 已成功重启,现在状态正常。"
else
log "错误: 重启尝试后 EMQX 仍无响应。"
log "信息: 请使用以下命令检查容器日志: docker logs uemqx"
fi
fi
\ No newline at end of file
......@@ -2,7 +2,7 @@
# --- 配置区域 ---
# 日志文件路径
LOG_FILE="/var/log/monitor_exapi_and_malan.log"
LOG_FILE="/var/log/monitor_external_api_services.log"
# 定义要监控的服务及其相关信息
# 格式: "进程名:目录路径:启动脚本路径"
......
#!/bin/bash
# 宿主机上的脚本:检查 MySQL,如果容器未运行则重启 umysql 容器
LOG_FILE="/var/log/monitor_mysql_service.log"
log() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
get_mysql_password() {
docker exec umysql printenv MYSQL_ROOT_PASSWORD 2>/dev/null
}
check_mysql() {
if docker ps --format '{{.Names}}' | grep -Fxq "umysql"; then
local mysql_password
mysql_password=$(get_mysql_password)
if [ -z "$mysql_password" ]; then
return 1
fi
# 尝试连接数据库
if docker exec umysql mysqladmin ping -h localhost -u root -p"$mysql_password" 2>/dev/null; then
# 尝试执行一个简单的SQL查询来确认数据库功能正常
if docker exec umysql mysql -u root -p"$mysql_password" -e "SELECT 1;" >/dev/null 2>&1; then
log "MySQL 服务连接正常,可以执行SQL查询"
return 0
else
log "警告: MySQL 服务可以ping通,但无法执行SQL查询"
return 1
fi
else
log "警告: 无法连接到 MySQL 服务"
return 1
fi
else
log "信息: umysql 容器未运行"
return 1
fi
}
restart_mysql_container() {
log "MySQL 未运行。正在尝试重启容器 'umysql'..."
# 检查容器是否存在(不仅仅是运行状态)
if docker ps -a --format '{{.Names}}' | grep -Fxq "umysql"; then
# 停止可能挂起的容器
docker stop umysql >/dev/null 2>&1 || true
# 容器存在但未运行,尝试启动
if docker start umysql; then
log "成功: MySQL 容器已成功启动。"
# 等待几秒让服务启动
log "信息: 等待 60 秒让 MySQL 服务完全启动..."
for i in {1..60}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "umysql"; then
log "信息: MySQL 容器现在正在运行。"
# 等待一段时间后检查服务状态
log "信息: 等待 20 秒后检查服务状态..."
sleep 20
local mysql_password
mysql_password=$(get_mysql_password)
if [ -z "$mysql_password" ]; then
return 1
fi
if docker exec umysql mysqladmin ping -h localhost -u root -p"$mysql_password" >/dev/null 2>&1; then
if docker exec umysql mysql -u root -p"$mysql_password" -e "SELECT 1;" >/dev/null 2>&1; then
log "信息: MySQL 服务状态正常。"
return 0
else
log "错误: MySQL 服务运行中,但无法执行SQL查询。"
return 1
fi
else
log "错误: MySQL 服务状态检查失败。"
return 1
fi
else
log "错误: MySQL 容器在启动后不久就停止了。"
return 1
fi
else
log "错误: 无法启动 MySQL 容器。"
return 1
fi
else
log "错误: 容器 'umysql' 不存在!"
log "信息: 您可能需要手动重新创建 MySQL 容器。"
return 1
fi
}
# 主逻辑
log "开始检查 MySQL 服务状态..."
if check_mysql; then
log "MySQL 正在运行且状态正常。"
else
log "MySQL 无响应或容器未运行。"
restart_mysql_container
# 检查重启后是否正常工作
if check_mysql; then
log "MySQL 已成功重启,现在状态正常。"
else
log "错误: 重启尝试后 MySQL 仍无响应。"
log "信息: 请使用以下命令检查容器日志: docker logs umysql"
fi
fi
\ No newline at end of file
#!/bin/bash
# ==================== 配置区 ====================
CONTAINER_NAME="umysql"
DB_USER="root"
HOST_BACKUP_DIR="/opt/mysql" # 宿主机备份目录
LOG_FILE="/var/log/backup_mysql_databases.log"
RETENTION_DAYS=30
TARGET_DBS=("devops" "devops_voice" "huazhao2" "nacos_mysql" "offline" "ubains" "wifi" "voice")
DATE=$(date +"%Y%m%d")
CONTAINER_TMP_DIR="/tmp/mysql_backup_$$.sql.gz" # 容器内临时目录(带PID防冲突)
# ==================== 日志函数 ====================
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
get_mysql_password() {
docker exec "$CONTAINER_NAME" printenv MYSQL_ROOT_PASSWORD 2>/dev/null
}
# ==================== 初始化 ====================
mkdir -p "$HOST_BACKUP_DIR/$DATE"
touch "$LOG_FILE"
log "===== 开始备份任务 (容器: $CONTAINER_NAME) ====="
# 在容器内创建临时目录
docker exec "$CONTAINER_NAME" mkdir -p "$CONTAINER_TMP_DIR"
if [ $? -ne 0 ]; then
log "❌ 无法在容器内创建临时目录,请检查容器是否运行。"
exit 1
fi
DB_PASSWORD=$(get_mysql_password)
if [ -z "$DB_PASSWORD" ]; then
docker exec "$CONTAINER_NAME" rm -rf "$CONTAINER_TMP_DIR"
exit 1
fi
# 测试连接
if docker exec "$CONTAINER_NAME" mysql -u"$DB_USER" -p"$DB_PASSWORD" -Nse "SELECT 1;" >/dev/null 2>&1; then
log "✅ 使用密码成功连接数据库"
else
log "❌ 使用密码连接数据库失败"
docker exec "$CONTAINER_NAME" rm -rf "$CONTAINER_TMP_DIR"
exit 1
fi
# 获取容器中实际存在的数据库列表
EXISTING_DBS_RAW=$(docker exec "$CONTAINER_NAME" mysql -u"$DB_USER" -p"$DB_PASSWORD" -Nse "SHOW DATABASES;" 2>/dev/null)
mapfile -t EXISTING_DBS <<< "$EXISTING_DBS_RAW"
declare -A DB_EXISTS
for db in "${EXISTING_DBS[@]}"; do
DB_EXISTS["$db"]=1
done
# ==================== 备份每个目标数据库 ====================
SUCCESS_COUNT=0
for db in "${TARGET_DBS[@]}"; do
if [[ -n "${DB_EXISTS[$db]}" ]]; then
CONTAINER_DUMP_FILE="$CONTAINER_TMP_DIR/${db}.sql.gz"
HOST_DUMP_FILE="$HOST_BACKUP_DIR/$DATE/${db}.sql.gz"
log "开始备份数据库: $db"
# 在容器内执行 mysqldump + gzip
docker exec "$CONTAINER_NAME" \
sh -c "mysqldump -u'$DB_USER' -p'$DB_PASSWORD' --single-transaction --routines --triggers --events '$db' | gzip > '$CONTAINER_DUMP_FILE'"
if [ $? -eq 0 ] && docker exec "$CONTAINER_NAME" [ -s "$CONTAINER_DUMP_FILE" ]; then
# 从容器复制到宿主机
docker cp "$CONTAINER_NAME:$CONTAINER_DUMP_FILE" "$HOST_DUMP_FILE"
if [ $? -eq 0 ] && [ -s "$HOST_DUMP_FILE" ]; then
log "✅ 备份成功: $db -> $HOST_DUMP_FILE"
((SUCCESS_COUNT++))
else
log "❌ 复制到宿主机失败: $db"
[ -f "$HOST_DUMP_FILE" ] && rm -f "$HOST_DUMP_FILE"
fi
else
log "❌ 容器内备份失败: $db"
fi
# 立即删除容器内的临时文件(无论成功与否)
docker exec "$CONTAINER_NAME" rm -f "$CONTAINER_DUMP_FILE"
else
log "⚠️ 跳过: 数据库 $db 不存在"
fi
done
# 清理容器内临时目录
docker exec "$CONTAINER_NAME" rm -rf "$CONTAINER_TMP_DIR"
log "本次共成功备份 $SUCCESS_COUNT 个数据库"
# ==================== 清理超过30天的旧备份 ====================
log "开始清理超过 $RETENTION_DAYS 天的旧备份..."
find "$HOST_BACKUP_DIR" -maxdepth 1 -type d -name "????????" -mtime +$RETENTION_DAYS -exec rm -rf {} + 2>/dev/null
log "===== 备份任务结束 ====="
#!/bin/bash
# clear_deleted_files.sh - 定时清理被进程占用的已删除文件
LOG_FILE="/var/log/cleanup_deleted_files.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] 开始检查被占用的已删除文件..." >> "$LOG_FILE"
# 使用 lsof +L1 查找 link count 为 0(即已删除)但仍被打开的文件
DELETED_ENTRIES=$(lsof +L1 2>/dev/null | grep -v "COMMAND")
if [ -z "$DELETED_ENTRIES" ]; then
echo "[$DATE] 未发现被占用的已删除文件。" >> "$LOG_FILE"
exit 0
fi
echo "[$DATE] 发现以下被占用的已删除文件:" >> "$LOG_FILE"
echo "$DELETED_ENTRIES" >> "$LOG_FILE"
# 提取唯一 PID 列表
PIDS=$(echo "$DELETED_ENTRIES" | awk 'NR>1 {print $2}' | sort -u)
for PID in $PIDS; do
if ! kill -0 "$PID" 2>/dev/null; then
echo "[$DATE] PID $PID 已不存在,跳过。" >> "$LOG_FILE"
continue
fi
CMD=$(ps -p "$PID" -o comm= 2>/dev/null | tr -d ' ')
echo "[$DATE] 处理进程: PID=$PID, CMD=$CMD" >> "$LOG_FILE"
# 尝试发送 SIGHUP(适用于 Nginx、rsyslog 等支持 reload 的服务)
if kill -0 "$PID" 2>/dev/null; then
echo "[$DATE] 向 PID $PID 发送 SIGHUP 信号..." >> "$LOG_FILE"
kill -HUP "$PID" 2>/dev/null && continue
fi
# 若 SIGHUP 无效或不支持,记录警告(不强制 kill,避免服务中断)
echo "[$DATE] WARNING: 无法通过 SIGHUP 释放 PID $PID 的文件句柄。建议手动处理或配置 logrotate。" >> "$LOG_FILE"
done
echo "[$DATE] 检查完成。" >> "$LOG_FILE"
#!/bin/bash
# 宿主机上的脚本:检查 EMQX,如果容器未运行则重启 uemqx 容器
LOG_FILE="/var/log/monitor_emqx_service.log"
log() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
check_emqx() {
# 检查 uemqx 容器是否正在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uemqx"; then
# 通过 docker exec 检查 EMQX 进程是否在容器内运行
if docker exec uemqx pgrep -f "emqx" >/dev/null 2>&1; then
# 检查EMQX是否在运行状态(使用EMQX自带的命令)
if docker exec uemqx emqx_ctl status >/dev/null 2>&1; then
# 额外验证EMQX是否真正可用
status_output=$(docker exec uemqx emqx_ctl status 2>&1)
if echo "$status_output" | grep -q "is started"; then
log "EMQX 服务状态正常"
return 0
else
log "警告: emqx_ctl 命令执行成功,但返回意外状态"
return 1
fi
else
log "警告: 容器正在运行,EMQX 进程存在,但 emqx_ctl 命令执行失败"
return 1
fi
else
log "警告: 容器正在运行,但在容器内未找到 EMQX 进程"
return 1
fi
else
log "信息: uemqx 容器未运行"
return 1
fi
}
restart_emqx_container() {
log "EMQX 未运行。正在尝试重启容器 'uemqx'..."
# 检查容器是否存在(不仅仅是运行状态)
if docker ps -a --format '{{.Names}}' | grep -Fxq "uemqx"; then
# 停止可能挂起的容器
docker stop uemqx >/dev/null 2>&1 || true
# 容器存在但未运行,尝试启动
if docker start uemqx; then
log "成功: EMQX 容器已成功启动。"
# 等待几秒让服务启动
log "信息: 等待 30 秒让 EMQX 服务完全启动..."
for i in {1..30}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uemqx"; then
log "信息: EMQX 容器现在正在运行。"
# 再次检查EMQX进程是否已启动
if docker exec uemqx pgrep -f "emqx" >/dev/null 2>&1; then
log "信息: EMQX 进程在容器内正在运行。"
# 等待一段时间后再次检查服务状态
log "信息: 等待 10 秒后检查服务状态..."
sleep 10
if docker exec uemqx emqx_ctl status >/dev/null 2>&1; then
status_output=$(docker exec uemqx emqx_ctl status 2>&1)
if echo "$status_output" | grep -q "is started"; then
log "信息: EMQX 服务状态正常。"
return 0
else
log "错误: EMQX 进程运行中,但服务状态异常。"
return 1
fi
else
log "错误: EMQX 进程运行中,但服务状态检查失败。"
return 1
fi
else
log "错误: EMQX 进程在容器内未运行。"
return 1
fi
else
log "错误: EMQX 容器在启动后不久就停止了。"
return 1
fi
else
log "错误: 无法启动 EMQX 容器。"
return 1
fi
else
log "错误: 容器 'uemqx' 不存在!"
log "信息: 您可能需要手动重新创建 EMQX 容器。"
return 1
fi
}
# 主逻辑
log "开始检查 EMQX 服务状态..."
if check_emqx; then
log "EMQX 正在运行且状态正常。"
else
log "EMQX 无响应或容器未运行。"
restart_emqx_container
# 检查重启后是否正常工作
if check_emqx; then
log "EMQX 已成功重启,现在状态正常。"
else
log "错误: 重启尝试后 EMQX 仍无响应。"
log "信息: 请使用以下命令检查容器日志: docker logs uemqx"
fi
fi
\ No newline at end of file
#!/bin/bash
# --- 配置区域 ---
# 日志文件路径
LOG_FILE="/var/log/monitor_external_api_services.log"
# 定义要监控的服务及其相关信息
# 格式: "进程名:目录路径:启动脚本路径"
SERVICES=(
"ubains-meeting-api-1.0-SNAPSHOT.jar:/var/www/java/external-meeting-api:/var/www/java/external-meeting-api/run.sh"
"malan:/var/www/malan:/var/www/malan/run.sh"
)
# --- 函数定义 ---
# 记录日志的函数
log_message() {
local message="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> "$LOG_FILE"
}
# 检查进程是否运行
is_process_running() {
local process_name="$1"
# 使用 pgrep -f 搜索命令行中包含该名称的进程
# 对于 .jar 文件,通常搜索的是 java -jar ...<jar_name>
# 对于其他程序,搜索其进程名
if [[ "$process_name" == *.jar ]]; then
# 如果是 JAR 文件,搜索 java 进程中包含该 jar 名称的
pgrep -f "java.*$process_name" > /dev/null
else
# 否则直接搜索进程名
pgrep -x "$process_name" > /dev/null
fi
if [ $? -eq 0 ]; then
return 0 # 进程运行中
else
return 1 # 进程未运行
fi
}
# 检查目录是否存在
is_directory_exists() {
local dir_path="$1"
[ -d "$dir_path" ]
}
# 检查启动脚本是否存在且可执行
is_script_executable() {
local script_path="$1"
[ -x "$script_path" ]
}
# 启动服务
start_service() {
local service_name="$1"
local dir_path="$2"
local script_path="$3"
log_message "尝试启动服务 '$service_name'..."
# 切换到服务目录并执行启动脚本
# 使用子shell (cd ...) 以确保不影响当前脚本的工作目录
(
cd "$dir_path" || { log_message "错误: 无法切换到目录 '$dir_path'"; return 1; }
# 检查启动脚本是否存在且可执行
if ! is_script_executable "$script_path"; then
log_message "错误: 启动脚本 '$script_path' 不存在或不可执行。"
return 1
fi
# 执行启动脚本
# 使用 nohup 将进程与终端脱离,使其在后台持续运行
# 输出重定向到 startup.log 或 /dev/null
nohup "./$(basename "$script_path")" > startup.log 2>&1 &
# 等待一小段时间,让进程有机会启动
sleep 3
# 再次检查进程是否启动成功
if is_process_running "$service_name"; then
log_message "服务 '$service_name' 启动成功。"
return 0
else
log_message "错误: 服务 '$service_name' 启动失败。"
return 1
fi
)
}
# --- 主逻辑 ---
# 初始化日志
log_message "=== 服务监控脚本开始执行 ==="
# 遍历所有服务
for service_info in "${SERVICES[@]}"; do
# 解析服务信息
IFS=':' read -r service_name dir_path script_path <<< "$service_info"
# 去除可能的前后空格
service_name=$(echo "$service_name" | xargs)
dir_path=$(echo "$dir_path" | xargs)
script_path=$(echo "$script_path" | xargs)
log_message "检查服务: $service_name (目录: $dir_path, 启动脚本: $script_path)"
# 检查目录是否存在
if ! is_directory_exists "$dir_path"; then
log_message "跳过服务 '$service_name': 目录 '$dir_path' 不存在。"
continue # 跳过当前循环,检查下一个服务
fi
# 检查进程是否运行
if is_process_running "$service_name"; then
log_message "服务 '$service_name' 正在运行。"
else
log_message "服务 '$service_name' 未运行。"
# 尝试启动服务
start_service "$service_name" "$dir_path" "$script_path"
fi
done
log_message "=== 服务监控脚本执行完毕 ==="
#!/bin/bash
# 宿主机上的脚本:检查 MySQL,如果容器未运行则重启 umysql 容器
LOG_FILE="/var/log/monitor_mysql_service.log"
log() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
get_mysql_password() {
docker exec umysql printenv MYSQL_ROOT_PASSWORD 2>/dev/null
}
check_mysql() {
if docker ps --format '{{.Names}}' | grep -Fxq "umysql"; then
local mysql_password
mysql_password=$(get_mysql_password)
if [ -z "$mysql_password" ]; then
return 1
fi
# 尝试连接数据库
if docker exec umysql mysqladmin ping -h localhost -u root -p"$mysql_password" 2>/dev/null; then
# 尝试执行一个简单的SQL查询来确认数据库功能正常
if docker exec umysql mysql -u root -p"$mysql_password" -e "SELECT 1;" >/dev/null 2>&1; then
log "MySQL 服务连接正常,可以执行SQL查询"
return 0
else
log "警告: MySQL 服务可以ping通,但无法执行SQL查询"
return 1
fi
else
log "警告: 无法连接到 MySQL 服务"
return 1
fi
else
log "信息: umysql 容器未运行"
return 1
fi
}
restart_mysql_container() {
log "MySQL 未运行。正在尝试重启容器 'umysql'..."
# 检查容器是否存在(不仅仅是运行状态)
if docker ps -a --format '{{.Names}}' | grep -Fxq "umysql"; then
# 停止可能挂起的容器
docker stop umysql >/dev/null 2>&1 || true
# 容器存在但未运行,尝试启动
if docker start umysql; then
log "成功: MySQL 容器已成功启动。"
# 等待几秒让服务启动
log "信息: 等待 60 秒让 MySQL 服务完全启动..."
for i in {1..60}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "umysql"; then
log "信息: MySQL 容器现在正在运行。"
# 等待一段时间后检查服务状态
log "信息: 等待 20 秒后检查服务状态..."
sleep 20
local mysql_password
mysql_password=$(get_mysql_password)
if [ -z "$mysql_password" ]; then
return 1
fi
if docker exec umysql mysqladmin ping -h localhost -u root -p"$mysql_password" >/dev/null 2>&1; then
if docker exec umysql mysql -u root -p"$mysql_password" -e "SELECT 1;" >/dev/null 2>&1; then
log "信息: MySQL 服务状态正常。"
return 0
else
log "错误: MySQL 服务运行中,但无法执行SQL查询。"
return 1
fi
else
log "错误: MySQL 服务状态检查失败。"
return 1
fi
else
log "错误: MySQL 容器在启动后不久就停止了。"
return 1
fi
else
log "错误: 无法启动 MySQL 容器。"
return 1
fi
else
log "错误: 容器 'umysql' 不存在!"
log "信息: 您可能需要手动重新创建 MySQL 容器。"
return 1
fi
}
# 主逻辑
log "开始检查 MySQL 服务状态..."
if check_mysql; then
log "MySQL 正在运行且状态正常。"
else
log "MySQL 无响应或容器未运行。"
restart_mysql_container
# 检查重启后是否正常工作
if check_mysql; then
log "MySQL 已成功重启,现在状态正常。"
else
log "错误: 重启尝试后 MySQL 仍无响应。"
log "信息: 请使用以下命令检查容器日志: docker logs umysql"
fi
fi
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论