提交 93ff7706 authored 作者: 陈泽健's avatar 陈泽健

Merge remote-tracking branch 'origin/develop' into develop

#!/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" "ubains_nacos_config" "ubains_sso")
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
# 宿主机上的脚本:检查 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() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
check_nacos() {
# 确保 127.0.0.1:8848 可访问(Nacos 端口已映射到宿主机)
if curl -sf http://127.0.0.1:8848/nacos/v1/console/health/readiness >/dev/null; then
return 0
else
return 1
fi
}
restart_in_container() {
log "Nacos NOT READY. Restarting services in container 'ujava2'..."
# 检查容器是否正在运行(精确匹配名称)
if ! docker ps --format '{{.Names}}' | grep -Fxq "ujava2"; then
log "ERROR: Container 'ujava2' is not running!"
return 1
fi
# 在容器内执行 start.sh
if docker exec ujava2 /var/www/java/start.sh; then
log "SUCCESS: Services restarted in ujava2."
else
log "ERROR: Failed to run start.sh in ujava2."
fi
}
# 主逻辑
log "开始检查 Nacos 服务状态..."
if check_nacos; then
log "Nacos is healthy."
else
log "Nacos is not responding."
restart_in_container
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" "ubains_nacos_config" "ubains_sso")
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
#!/bin/bash
#####################################
#用于数据库定时备份 2022-12-12
#####################################
sudo chmod +x /usr/local/docker/UbainsmysqlBakUp.sh
/usr/local/docker/UbainsmysqlBakUp.sh
userset="root"
sleep 5
# 每天下午一点执行脚本
if cat /var/spool/cron/$userset |grep "UbainsmysqlBakUp.sh">/dev/null
then
echo -e "\033[32m
*********************
*已配置数据库定时备份
*
*********************
\033[0m"
sudo service crond restart
else
#每天13点备份
sudo cat >> /var/spool/cron/$userset<<EOF
0 13 * * * bash /usr/local/docker/UbainsmysqlBakUp.sh
EOF
sleep 3
sudo service crond restart
fi
#!/bin/bash
#####################################
#用于数据库备份 23-01-13
#####################################
#预定数据库备份
function ubainsbak()
{
echo -e "\033[33m 检查mysql...... \033[0m"
sudo docker images |grep mysql
sudo docker ps |grep umysql
if [ $? -eq 0 ]; then
sudo docker exec -i umysql bash <<'EOF'
find /home/mysql/ubains/* -mtime +30 -exec rm -rf {} \;
mkdir -p /home/mysql/ubains/$(date +%Y%m%d)
# 备份指定数据库
mysqldump -uroot -p"dNrprU&2S" ubains > /home/mysql/ubains/$(date +%Y%m%d)/ubains_$(date +%Y%m%d_%H%M%S).sql
#删除30天之前的备份
log3=$(date -d "30 day ago" +%Y%m%d)
rm /home/mysql/ubains/$log3* -rf
exit
EOF
sudo mkdir -p /opt/mysql/ubains/$(date +%Y%m%d)
sudo docker cp umysql:/home/mysql/ubains/$(date +%Y%m%d) /opt/mysql/ubains
#删除30天之前的备份
log3=$(date -d "30 day ago" +%Y%m%d)
sudo rm /opt/mysql/ubains/$log3* -rf
else
echo -e "\033[33m 请正确安装数据库...... \033[0m"
fi
}
#运维数据库备份
function devopsbak()
{
echo -e "\033[33m 检查mysql...... \033[0m"
sudo docker images |grep mysql
sudo docker ps |grep umysql
if [ $? -eq 0 ]; then
sudo docker exec -i umysql bash <<'EOF'
find /home/mysql/devops/* -mtime +30 -exec rm -rf {} \;
mkdir -p /home/mysql/devops/$(date +%Y%m%d)
# 备份指定数据库
mysqldump -uroot -p"dNrprU&2S" devops > /home/mysql/devops/$(date +%Y%m%d)/devops_$(date +%Y%m%d_%H%M%S).sql
#删除30天之前的备份
log3=$(date -d "30 day ago" +%Y%m%d)
rm /home/mysql/devops/$log3* -rf
exit
EOF
sudo mkdir -p /opt/mysql/devops/$(date +%Y%m%d)
sudo docker cp umysql:/home/mysql/devops/$(date +%Y%m%d) /opt/mysql/devops
#删除30天之前的备份
log3=$(date -d "30 day ago" +%Y%m%d)
sudo rm /opt/mysql/devops/$log3* -rf
else
echo -e "\033[33m 请正确安装数据库...... \033[0m"
fi
}
#############################################################脚本配置项##################################################################################################
#################预定系统 数据库本地备份###############################
ubainsbak
#################运维系统 数据库本地备份###############################
#devopsbak
...@@ -557,32 +557,6 @@ do ...@@ -557,32 +557,6 @@ do
done done
log "INFO" "数据库密码修改成功!" log "INFO" "数据库密码修改成功!"
log "INFO" "准备处理数据库备份脚本"
$sudoset cp -rf $PWD/UbainsmysqlBakUp.sh /usr/local/docker/
#定时备份数据库
sudo chmod +x /usr/local/docker/UbainsmysqlBakUp.sh
/usr/local/docker/UbainsmysqlBakUp.sh
userset="root"
sleep 5
# 每天下午一点执行脚本
log "INFO" "用cat检测是否有定时任务,没有则准备创建"
if cat /var/spool/cron/$userset |grep "UbainsmysqlBakUp.sh">/dev/null
then
log "INFO" "已配置数据库定时备份,准备重启定时任务"
sudo service crond restart
else
#每天13点备份
log "INFO" "配置数据库定时备份"
sudo tee -a /var/spool/cron/$userset <<EOF
0 13 * * * bash /usr/local/docker/UbainsmysqlBakUp.sh
EOF
sleep 3
#该命令通用centos7、uos
log "INFO" "配置数据库定时备份成功"
sudo service crond restart
log "INFO" "重启定时任务成功"
fi
} }
#x86架构安装mqtt(预定2.0) #x86架构安装mqtt(预定2.0)
...@@ -684,7 +658,7 @@ fi ...@@ -684,7 +658,7 @@ fi
function ntp_uos() { function ntp_uos() {
# 判断如果是centos7就退出安装 # 判断如果是centos7就退出安装
if [ -f /etc/redhat-release ]; then if [ -f /etc/redhat-release ]; then
log "ERROR" "当前系统已经安装NTP服务,无需安装chrony服务" log "ERROR" "当前系统已经安装NTP服务"
return 1 return 1
fi fi
...@@ -908,6 +882,7 @@ function getLatestVersion() { ...@@ -908,6 +882,7 @@ function getLatestVersion() {
#------------------------------服务安装-end------------------------------------------------------------------------------------------------------------------------ #------------------------------服务安装-end------------------------------------------------------------------------------------------------------------------------
#------------------------------文件上传&更改ip-start------------------------------------------------------------------------------------------------------------------------ #------------------------------文件上传&更改ip-start------------------------------------------------------------------------------------------------------------------------
#todo:针对更新对外包,如果存在,需要判断是否更新 #todo:针对更新对外包,如果存在,需要判断是否更新
#-----------------------------------预定系统-------------------------------------------- #-----------------------------------预定系统--------------------------------------------
...@@ -1050,6 +1025,74 @@ sleep 3 ...@@ -1050,6 +1025,74 @@ sleep 3
#------------------------------文件上传&更改ip-end-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #------------------------------文件上传&更改ip-end--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function check_crontab() {
log "INFO" "开始配置数据库备份、删除进程检测、对外服务检测的定时任务.."
$sudoset mkdir -p /opt/scripts/
# 从定时脚本目录复制脚本到 /opt/scripts/
$sudoset cp -rf $auto_java/scripts/* /opt/scripts/
$sudoset chmod 755 /opt/scripts/*.sh
# 添加定时脚本目录中的脚本定时任务
# 监控 Redis 服务 - 每5分钟检查一次
if ! crontab -l 2>/dev/null | grep -q "monitor_redis_service.sh"; then
log "INFO" "创建监控Redis服务的定时任务..."
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/scripts/monitor_redis_service.sh >> /var/log/monitor_redis_service.log 2>&1") | crontab -
else
log "INFO" "监控Redis服务的定时任务已存在"
fi
# 监控 EMQX 服务 - 每5分钟检查一次
if ! crontab -l 2>/dev/null | grep -q "monitor_emqx_service.sh"; then
log "INFO" "创建监控EMQX服务的定时任务..."
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/scripts/monitor_emqx_service.sh >> /var/log/monitor_emqx_service.log 2>&1") | crontab -
else
log "INFO" "监控EMQX服务的定时任务已存在"
fi
# 监控 MySQL 服务 - 每5分钟检查一次
if ! crontab -l 2>/dev/null | grep -q "monitor_mysql_service.sh"; then
log "INFO" "创建监控MySQL服务的定时任务..."
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/scripts/monitor_mysql_service.sh >> /var/log/monitor_mysql_service.log 2>&1") | crontab -
else
log "INFO" "监控MySQL服务的定时任务已存在"
fi
# 监控外部API服务 - 每5分钟检查一次
if ! crontab -l 2>/dev/null | grep -q "monitor_external_api_services.sh"; then
log "INFO" "创建监控外部API服务的定时任务..."
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/scripts/monitor_external_api_services.sh >> /var/log/monitor_external_api_services.log 2>&1") | crontab -
else
log "INFO" "监控外部API服务的定时任务已存在"
fi
# 数据库备份 - 每天凌晨2点执行
if ! crontab -l 2>/dev/null | grep -q "backup_mysql_databases.sh"; then
log "INFO" "创建数据库备份定时任务..."
(crontab -l 2>/dev/null; echo "0 2 * * * /opt/scripts/backup_mysql_databases.sh >> /var/log/backup_mysql_databases.log 2>&1") | crontab -
else
log "INFO" "数据库备份定时任务已存在"
fi
# 清理已删除文件 - 每天凌晨1点执行
if ! crontab -l 2>/dev/null | grep -q "cleanup_deleted_files.sh"; then
log "INFO" "创建清理已删除文件定时任务..."
(crontab -l 2>/dev/null; echo "0 1 * * * /opt/scripts/cleanup_deleted_files.sh >> /var/log/cleanup_deleted_files.log 2>&1") | crontab -
else
log "INFO" "清理已删除文件定时任务已存在"
fi
# 重启cron服务
sleep 3
if command -v systemctl >/dev/null 2>&1; then
sudo systemctl restart cron 2>/dev/null || sudo systemctl restart crond 2>/dev/null
else
sudo service cron restart 2>/dev/null || sudo service crond restart 2>/dev/null
fi
log "INFO" "定时任务配置成功"
}
#------------------------------全局配置-start-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #------------------------------全局配置-start--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
###服务器检测配置项 ###服务器检测配置项
#mem-check #mem-check
......
#!/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" "ubains_nacos_config" "ubains_sso")
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论