提交 62333acd authored 作者: 陈泽健's avatar 陈泽健

docs(PRD): 整理和补充PRD文档规范

- 移动规范获取部分到文档末尾,保持文档结构一致性
- 添加文档规范和测试规范的标准模板
- 统一各PRD文档中的规范引用格式
- 补充缺失的规范获取章节到所有相关文档
- 优化文档结构使内容更清晰易读
# 文档规范:
## 文档结构:
1. 文档结构:
- 标题层级清晰,使用Markdown语法中的#表示不同层级的标题。
- 每个章节应有明确的标题,便于阅读和导航。
## 功能实现状态:
2. 功能实现状态:
- 使用复选框表示功能的实现状态。
- [x] 已实现
- [ ] 未实现
- [ ] 进行中
- [ ] 待定
## 代码块:
3. 代码块:
- 使用Markdown的代码块语法(```)来表示代码段。
- 指定代码语言以启用语法高亮。
- 示例:
```python
def example_function():
print("This is an example.")
```
## 优化功能回填:
4. 优化功能回填:
- 在文档末尾添加“优化功能回填”部分。
- 列出需要优化或改进的功能点,便于后续跟踪和实施。
- 示例:
### 优化功能回填
- [ ] 优化用户界面响应速度
- [ ] 增加多语言支持
- [ ] 改进错误处理机制
# 测试规范:
## 代码实现后的简单自测:
1. 运行代码,查看结果是否与预期一致。
2. 检查代码是否有语法错误或运行时错误。
......@@ -4,13 +4,6 @@
注意:OpenSSL 支持的最大有效期有限,常见做法是设置为 100 年(`-days 36500`),接近“长期有效”。自签名 CA 仅在受信任的环境(内网/测试)使用。
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 先决条件
- 服务器需安装 `openssl`
- 若希望脚本自动写入并重载 nginx,需具备相应的文件访问/重载权限(或 root 权限)。
......@@ -181,4 +174,10 @@ sudo update-ca-certificates
- 运维系统
- 配置路径:`/var/www/html/nginx-conf/moblie8081.conf``/var/www/html/nginx-conf/rms8443.conf`
- 推荐命令:`docker exec -it upython /usr/local/nginx/sbin/nginx -s reload`
-
\ No newline at end of file
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
# 服务检测需求说明文档
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 📋 概述
本脚本主要用于在自动化运行期间的服务器监测,用于检测在自动化运行期间的服务器时间的服务信息。
......@@ -82,4 +75,11 @@
##### 7、对接钉钉发送:
需要能实现将当前的监测后输出的报告,调用钉钉发送给群消息。
参考代码:E:\GithubData\自动化\ubains-module-test\新统一平台\Base\base.py中的dingding_send_message函数来实现
\ No newline at end of file
参考代码:E:\GithubData\自动化\ubains-module-test\新统一平台\Base\base.py中的dingding_send_message函数来实现
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
# 服务自检需求说明文档
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 📋 概述
本脚本主要用于服务自检,用于检测服务器上的服务是否正常启动,并返回结果。
......@@ -21,8 +14,8 @@
## 🎯 功能实现总览
### 服务自检 (`check_server_health.ps1`和`check_server_health.sh`)
脚本路径:AuxiliaryTool\ScriptTool\ServiceSelfInspection\check_server_health.ps1
脚本路径:AuxiliaryTool\ScriptTool\ServiceSelfInspection\check_server_health.sh
powershell脚本路径:AuxiliaryTool\ScriptTool\ServiceSelfInspection\check_server_health.ps1
shell脚本路径:AuxiliaryTool\ScriptTool\ServiceSelfInspection\check_server_health.sh
#### 检测需求
......@@ -569,4 +562,11 @@
5)可读性要求:
- 报告结构清晰,分级标题明确(如:一级为大模块,二级为具体检测项)。
- 对终端用户(非开发人员)也能直观理解当前服务器健康状况以及需要关注的问题。
\ No newline at end of file
- 对终端用户(非开发人员)也能直观理解当前服务器健康状况以及需要关注的问题。
## 需求规范
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
......@@ -6,13 +6,6 @@
---
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 漏洞修复清单
### 问题一:OpenSSH 安全配置加固
......@@ -403,6 +396,13 @@
---
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 总结
该文档涵盖了系统安全的各个方面,包括:
......
# 根据PRD需求文档生成用例
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 1. 概述
需求文档生成用例,根据PRD需求文档快速生成测试用例,提升测试效率,确保测试覆盖率。
## 2. 需求文档读取
......@@ -16,4 +9,11 @@
读取开发的PRD文档,解析出各个功能模块及其对应的测试点,重点关注逻辑层面的测试需求。输出测试用例的初步结构。
## 4. 测试用例生成
根据解析出的测试点,再参考测试用例模板,对测试点进行测试用例的生成,生成对应的测试用例,涵盖功能测试、边界测试、异常测试等。生成的用例存放在:AuxiliaryTool/用例生成/用例文件。
生成的测试用例名称通过交互型输入名称后追加时间来命名。
\ No newline at end of file
生成的测试用例名称通过交互型输入名称后追加时间来命名。
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
# 容器升级需求说明文档
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 📋 概述
本脚本主要用于将主服务器上根据不同系统要求进行更新自动化部署包程序,压缩后上传至公司网盘:
......@@ -126,4 +119,11 @@
### 更新说明
- 已实现语音转录系统的前后端服务包和容器镜像包功能。
- 请验证相关功能是否符合需求。
\ No newline at end of file
- 请验证相关功能是否符合需求。
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
# 容器升级需求说明文档
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 📋 概述
本系统由三个核心 Shell 脚本组成,用于实现容器化服务的远程部署与升级管理:
......@@ -137,4 +130,11 @@
| 批量部署 | 一次升级多台服务器 | ❌ 待开发 |
| 版本管理 | 记录部署版本和时间 | ❌ 待开发 |
---
\ No newline at end of file
---
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
# 程序更新脚本需求文档
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 需求描述
### 一、需求描述:
能够通过脚本实现在window上远程更新任何系统的前后端包版本,以减少错误,提升效率。
......@@ -104,4 +97,12 @@
| 系统名称 | 前端路径及文件 | 后端路径及文件 | 数据库名称 |
|:会议预定系统: | :前台前端:/var/www/java/ubains-web-2.0 *.js static/ index.html 后台前端:/var/www/java/ubains-web-admin index.html static/: | :对内后端:/var/www/java/api-java-meeting2.0 *.jar 对外后端:/var/www/java/external-meeting-api *.jar: | :数据库:ubains: |
|:运维集控系统: | :前端:/var/www/html/web-vue-rms static/ index.html: | :后端:/var/www/html cmdb/ UbainsDevOps/: | :数据库:devops: |
|:讯飞转录系统: | :前端:/var/www/html/web-vue-voice static/ index.html: | :后端:/var/www/html UbainsDevOps/: | :数据库:devops: |
\ No newline at end of file
|:讯飞转录系统: | :前端:/var/www/html/web-vue-voice static/ index.html: | :后端:/var/www/html UbainsDevOps/: | :数据库:devops: |
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ No newline at end of file
# 常见问题处理说明文档
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
## 📋 概述
该脚本主要用于在Linux服务器上执行,解决常见的服务运行异常、权限不足、磁盘空间不足、版本更新、数据备份等问题。需要提供交互界面,允许用户选择不同的处理选项,如果涉及到输入参数,需要提示用户输入并验证输入的有效性。
......@@ -683,4 +676,11 @@ cd /data/services/api/java-meeting/java-meeting-extapi/
- 当通过服务自检脚本自动调用时,使用非交互模式:
1)调用示例:./issue_handler.sh --action redis_container_exception --non-interactive --yes
2)非交互模式下,如果未同时指定 --yes,脚本应出于安全考虑直接退出,不删除任何数据;
3)只有在同时传入 --non-interactive 和 --yes 时,才会自动执行删除 data 并重启 uredis 的操作。
\ No newline at end of file
3)只有在同时传入 --non-interactive 和 --yes 时,才会自动执行删除 data 并重启 uredis 的操作。
## 规范获取
代码规范:Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md
问题总结:Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md
方法总结:Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md
文档规范:Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md
测试规范:Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md
\ 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
# 宿主机上的脚本:检查 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
done
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)
......@@ -684,7 +658,7 @@ fi
function ntp_uos() {
# 判断如果是centos7就退出安装
if [ -f /etc/redhat-release ]; then
log "ERROR" "当前系统已经安装NTP服务,无需安装chrony服务"
log "ERROR" "当前系统已经安装NTP服务"
return 1
fi
......@@ -908,6 +882,7 @@ function getLatestVersion() {
#------------------------------服务安装-end------------------------------------------------------------------------------------------------------------------------
#------------------------------文件上传&更改ip-start------------------------------------------------------------------------------------------------------------------------
#todo:针对更新对外包,如果存在,需要判断是否更新
#-----------------------------------预定系统--------------------------------------------
......@@ -1050,6 +1025,74 @@ sleep 3
#------------------------------文件上传&更改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--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
###服务器检测配置项
#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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论