提交 59635acc authored 作者: PGY's avatar PGY

feat(monitor): 监控脚本新增重启机制处理、日志轮转与并发控制机制。

  - 为监控脚本添加连续检测失败重启机制
  - 为监控脚本添加日志自动轮转机制(5MB轮转、保留30天)
  - 为监控脚本添加PID文件锁机制防止并发执行
  - 统一所有脚本头部说明格式,规范版本管理
上级 72625e39
......@@ -126,7 +126,12 @@
"Bash(grep:*)",
"Bash(mkdir:*)",
"Bash(cd \"E:/GithubData/ubains-module-test/AuxiliaryTool/DocumentAutoOptimizationCalibration\" && pip install translators -q)",
"Bash(ls -la \"E:\\\\GithubData\\\\ubains-module-test\\\\Docs\\\\PRD\" 2>&1 || dir \"E:\\\\GithubData\\\\ubains-module-test\\\\Docs\\\\PRD\" 2>&1)"
"Bash(ls -la \"E:\\\\GithubData\\\\ubains-module-test\\\\Docs\\\\PRD\" 2>&1 || dir \"E:\\\\GithubData\\\\ubains-module-test\\\\Docs\\\\PRD\" 2>&1)",
"Bash(sed -i 's/if \\\\[ \"\"$size_bytes\"\" -gt 0 \\\\] || \\\\[\\\\[ \"\"$target_file\"\" == \\\\*\"\"\\\\$TARGET_KEY\"\"\\\\* \\\\]\\\\]; then/if [ \"\"$size_bytes\"\" -gt 0 ]; then/' check_deleted_file_ubains.sh)",
"Bash(sed -i '/^[[:space:]]*TARGET_KEY=/d' check_deleted_file_ubains.sh)",
"Bash(check_deleted_file_ubains_header.tmp:*)",
"Bash(mv check_deleted_file_ubains_header.tmp check_deleted_file_ubains.sh)",
"Bash(chmod +x check_deleted_file_ubains.sh)"
]
}
}
# _PRD_预定系统EMQX服务监控需求文档.md
> 版本:V1.0
> 更新日期:2026-01-29
> 适用范围:预定系统EMQX消息队列服务监测与自愈
> 实现脚本:`自动化部署脚本\x86架构\预定系统\定时脚本\monitor_emqx_service.sh`
---
## 1. 背景与目标
### 1.1 背景
EMQX作为预定系统的核心消息队列服务,负责处理设备通信、消息路由等关键功能。服务中断会直接影响系统整体可用性,需要建立自动监控和恢复机制。
### 1.2 目标
实现EMQX服务的自动化定时监控功能,具备:
- 容器运行状态监测
- EMQX进程存在性验证
- 服务可用性状态检查
- 异常时的自动重启恢复
- 多层次的状态验证机制
- 完整的操作日志记录
---
## 2. 总体范围
### 2.1 纳入监控对象
- **容器名称**`uemqx`
- **监控维度**
- 容器运行状态(docker ps)
- EMQX进程存在性(pgrep -f "emqx")
- 服务可用性(emqx_ctl status命令)
- 服务状态详细信息
### 2.2 不在本期范围
- EMQX集群状态监控
- 消息队列性能指标监控
- 客户端连接数统计
- 消息流量监控
---
## 3. 术语说明
- **服务状态验证**:通过EMQX自带的emqx_ctl命令检查服务运行状态
- **渐进式恢复**:先检查再重启,重启后再次验证的恢复策略
- **多层次检测**:容器层→进程层→服务层的逐级验证机制
---
## 4. 功能需求
### 4.1 监控流程
#### 4.1.1 状态检查机制
按以下顺序进行状态验证:
1. **容器运行检查**
- 使用`docker ps`检查uemqx容器是否运行
- 容器未运行时直接进入重启流程
2. **进程存在检查**
- 在容器内执行`pgrep -f "emqx"`查找EMQX进程
- 进程不存在时标记为异常状态
3. **服务可用性检查**
- 执行`emqx_ctl status`命令检查服务状态
- 验证返回结果中包含"is started"标识
- 确认服务真正可用而非仅进程存在
#### 4.1.2 异常处理流程
当检测到异常时执行:
1. **容器重启**
- 停止可能挂起的容器实例
- 启动uemqx容器
- 等待30秒让服务完全启动
2. **状态验证循环**
- 检查容器是否成功运行
- 验证EMQX进程是否启动
- 等待10秒后再次检查服务状态
- 确认emqx_ctl status返回正常
3. **最终状态确认**
- 所有检查项都通过才算恢复成功
- 任一环节失败都记录为恢复失败
### 4.2 日志与审计
#### 4.2.1 日志文件
- 主日志:`/var/log/scripts/monitor_emqx_service.log`
#### 4.2.2 日志级别和格式
每行必须包含:
- 时间戳:`YYYY-MM-DD HH:MM:SS`
- 级别标识:信息/警告/错误/成功
- 具体操作和结果状态
示例:
```
2026-01-29 10:00:00 - 开始检查 EMQX 服务状态...
2026-01-29 10:00:01 - EMQX 服务状态正常
2026-01-29 10:05:00 - 警告: 容器正在运行,EMQX 进程存在,但 emqx_ctl 命令执行失败
2026-01-29 10:05:05 - EMQX 未运行。正在尝试重启容器 'uemqx'...
2026-01-29 10:05:35 - 信息: 等待 30 秒让 EMQX 服务完全启动..............................
2026-01-29 10:06:05 - 成功: EMQX 容器已成功启动。
```
### 4.3 错误处理
#### 4.3.1 容器状态异常
- 容器不存在:记录严重错误并建议手动创建
- 容器启动失败:记录错误详情和可能原因
- 容器启动后立即停止:记录错误并建议检查日志
#### 4.3.2 服务状态异常
- emqx_ctl命令不存在:记录警告并降级检查
- 命令执行失败:记录错误并尝试重启
- 状态返回异常:记录详细状态信息
#### 4.3.3 恢复过程异常
- 重启后容器仍不运行:记录失败并建议手动干预
- 进程启动但服务不可用:记录详细诊断信息
- 超时等待后仍未恢复:记录超时并建议深入排查
---
## 5. 配置参数
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| CONTAINER_NAME | uemqx | EMQX容器名称 |
| LOG_FILE | /var/log/scripts/monitor_emqx_service.log | 日志文件路径 |
| STARTUP_WAIT | 30秒 | 容器启动等待时间 |
| STATUS_CHECK_WAIT | 10秒 | 状态验证等待时间 |
---
## 6. 执行要求
### 6.1 执行时机
- 建议:每5分钟执行一次
- cron配置:`*/5 * * * * /opt/scripts/monitor_emqx_service.sh`
### 6.2 执行环境
- 需要docker命令权限
- uemqx容器必须存在
- 容器内需要有emqx_ctl命令
### 6.3 资源要求
- 内存:监控过程占用少量内存
- CPU:状态检查操作轻量级
- 网络:仅本地容器通信
---
## 7. 验收标准
1. **监控准确性**
- 能正确识别容器运行状态
- 准确检测EMQX进程存在性
- 正确验证服务可用性状态
2. **恢复有效性**
- 异常检测后能正确触发重启
- 重启操作能成功执行
- 恢复后服务状态确实正常
3. **日志完整性**
- 每次检查都有完整的开始和结束记录
- 异常情况有详细的诊断信息
- 恢复过程有清晰的步骤记录
4. **系统稳定性**
- 监控过程不影响EMQX正常运行
- 重启操作安全可靠
- 不会产生连锁故障
---
## 8. 故障排查
### 8.1 常见问题
1. **容器不存在**
```
错误: 容器 'uemqx' 不存在!
```
解决:重新创建uemqx容器
2. **命令执行失败**:
```
警告: 容器正在运行,EMQX 进程存在,但 emqx_ctl 命令执行失败
```
解决:检查容器内EMQX安装状态
3. **重启失败**:
```
错误: 无法启动 EMQX 容器。
```
解决:查看容器日志`docker logs uemqx`
### 8.2 诊断命令
```bash
# 检查容器状态
docker ps | grep uemqx
# 检查容器内进程
docker exec uemqx pgrep -f "emqx"
# 手动检查服务状态
docker exec uemqx emqx_ctl status
# 查看容器日志
docker logs uemqx --tail 50
# 手动重启测试
docker restart uemqx
```
### 8.3 日志分析
```bash
# 实时监控脚本执行
tail -f /var/log/scripts/monitor_emqx_service.log
# 统计异常发生频率
grep "警告\|错误" /var/log/scripts/monitor_emqx_service.log | wc -l
# 查看最近的恢复记录
grep "成功: EMQX 容器已成功启动" /var/log/scripts/monitor_emqx_service.log
```
---
## 需求规范
代码规范: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
# _PRD_预定系统Redis服务监控需求文档_计划执行.md
> 版本:V1.1
> 更新日期:2026-03-30
> 关联文档:_PRD_预定系统Redis服务监控需求文档.md (V1.1)
> 关联脚本:monitor_redis_service.sh (V1.0 → V1.1)
---
## 一、变更概述
### 1.1 变更背景
原脚本(V1.0)在检测到Redis服务异常时直接触发容器重启,导致单次网络波动或临时堵塞时就会重启服务,影响业务连续性。
### 1.2 变更目标
引入**连续失败阈值判断机制**,避免因单次临时故障触发不必要的服务重启:
- 单次检查失败时仅记录失败次数,不立即重启
- 连续失败达到阈值(默认3次)时才触发容器重启
- 检查成功后自动重置失败计数器
- 状态持久化保存,进程重启不丢失
---
## 二、当前脚本分析
### 2.1 现有逻辑流程(V1.0)
```
开始 → 检查Redis服务
检查成功 → 结束
检查失败 → 立即重启容器
重启失败 → 清理数据目录重试
验证重启结果 → 结束
```
### 2.2 存在的问题
1. **单次失败即重启**:临时网络波动也会触发重启
2. **无失败计数**:无法区分瞬时故障和持续故障
3. **无状态持久化**:脚本重启后丢失失败历史
4. **日志不完整**:缺少失败次数和阈值的日志信息
---
## 三、实现计划
### 3.1 新增配置参数
```bash
# 状态文件路径
STATE_FILE="/var/log/scripts/monitor_redis_service.state"
# 最大失败次数阈值
MAX_FAILURES=3
```
### 3.2 新增函数
#### 3.2.1 读取状态文件函数
```bash
read_state_file() {
if [ -f "$STATE_FILE" ]; then
source "$STATE_FILE"
echo "${FAILURE_COUNT:-0}"
else
echo "0"
fi
}
```
#### 3.2.2 写入状态文件函数
```bash
write_state_file() {
local count=$1
cat > "$STATE_FILE" << EOF
FAILURE_COUNT=$count
LAST_CHECK_TIME=$(date +%s)
EOF
}
```
### 3.3 主逻辑修改
#### 3.3.1 新的主流程
```
开始 → 读取失败计数器
检查Redis服务
┌───┴───┐
↓ ↓
检查成功 检查失败
↓ ↓
清零计数器 计数器+1
↓ ↓
结束 写入状态文件
判断是否达阈值?
┌──────┴──────┐
↓ ↓
未达阈值 达到阈值
↓ ↓
结束 清零计数器
重启容器
重启失败? → 清理数据重试
验证结果
结束
```
#### 3.3.2 主逻辑伪代码
```bash
# 主逻辑
log "开始检查 Redis 服务状态..."
# 读取当前失败次数
failure_count=$(read_state_file)
log "读取失败计数器: 当前失败次数 = $failure_count"
# 检查Redis服务
if check_redis; then
# 检查成功,清零计数器
if [ "$failure_count" -gt 0 ]; then
write_state_file 0
log "检查成功,重置失败计数器为 0"
fi
log "Redis 服务状态正常"
else
# 检查失败,累加计数器
failure_count=$((failure_count + 1))
write_state_file "$failure_count"
log "失败计数器更新: $((failure_count - 1)) -> $failure_count (阈值: $MAX_FAILURES)"
# 判断是否达到阈值
if [ "$failure_count" -ge "$MAX_FAILURES" ]; then
log "错误: 连续失败达到阈值($MAX_FAILURES次),触发容器重启"
write_state_file 0
# 执行重启流程
restart_redis_container
# 验证重启结果
if check_redis; then
log "Redis 服务已成功恢复"
else
log "错误: 重启后Redis服务仍不可用"
fi
else
log "警告: 未达到重启阈值,等待下次检查确认"
fi
fi
```
### 3.4 日志格式变更
```
2026-03-30 10:00:00 - 开始检查 Redis 服务状态...
2026-03-30 10:00:00 - 读取失败计数器: 当前失败次数 = 0
2026-03-30 10:00:01 - Redis 服务状态正常(已通过密码认证)
2026-03-30 10:00:01 - 检查成功,重置失败计数器为 0
2026-03-30 10:05:00 - 开始检查 Redis 服务状态...
2026-03-30 10:05:00 - 读取失败计数器: 当前失败次数 = 0
2026-03-30 10:05:01 - 警告: 无法连接到 Redis 服务
2026-03-30 10:05:01 - 失败计数器更新: 0 -> 1 (阈值: 3)
2026-03-30 10:05:01 - 警告: 未达到重启阈值,等待下次检查确认
2026-03-30 10:15:01 - 警告: 无法连接到 Redis 服务
2026-03-30 10:15:01 - 失败计数器更新: 2 -> 3 (阈值: 3)
2026-03-30 10:15:02 - 错误: 连续失败达到阈值(3次),触发容器重启
2026-03-30 10:15:02 - 重置失败计数器为 0
```
---
## 四、代码修改清单
### 4.1 配置变量区域(约第33行后添加)
```bash
# 状态文件配置
STATE_FILE="/var/log/scripts/monitor_redis_service.state"
MAX_FAILURES=3
```
### 4.2 函数区域(约第42行后添加)
```bash
# 读取状态文件
read_state_file() {
if [ -f "$STATE_FILE" ]; then
source "$STATE_FILE"
echo "${FAILURE_COUNT:-0}"
else
echo "0"
fi
}
# 写入状态文件
write_state_file() {
local count=$1
cat > "$STATE_FILE" << EOF
FAILURE_COUNT=$count
LAST_CHECK_TIME=$(date +%s)
EOF
}
```
### 4.3 主逻辑区域(约第250-265行,完全重写)
```bash
# 主逻辑(新版本)
log "开始检查 Redis 服务状态..."
# 读取当前失败次数
failure_count=$(read_state_file)
log "读取失败计数器: 当前失败次数 = $failure_count"
# 检查Redis服务
if check_redis; then
# 检查成功,清零计数器
if [ "$failure_count" -gt 0 ]; then
write_state_file 0
log "检查成功,重置失败计数器为 0"
fi
log "Redis 服务状态正常"
else
# 检查失败,累加计数器
failure_count=$((failure_count + 1))
write_state_file "$failure_count"
log "失败计数器更新: $((failure_count - 1)) -> $failure_count (阈值: $MAX_FAILURES)"
# 判断是否达到阈值
if [ "$failure_count" -ge "$MAX_FAILURES" ]; then
log "错误: 连续失败达到阈值($MAX_FAILURES次),触发容器重启"
write_state_file 0
# 执行重启流程
restart_redis_container
# 验证重启结果
if check_redis; then
log "Redis 服务已成功恢复"
else
log "错误: 重启后Redis服务仍不可用"
fi
else
log "警告: 未达到重启阈值,等待下次检查确认"
fi
fi
```
### 4.4 版本信息更新(约第6行)
```bash
# 版本:V1.1
```
---
## 五、测试计划
### 5.1 单元测试
| 测试项 | 测试方法 | 预期结果 |
|--------|----------|----------|
| 状态文件读取 | 删除状态文件后执行脚本 | 自动初始化为0 |
| 状态文件写入 | 执行后检查文件内容 | 正确写入FAILURE_COUNT |
| 计数器累加 | 模拟服务失败 | 计数器正确+1 |
| 计数器清零 | 模拟服务恢复 | 计数器归0 |
### 5.2 集成测试
| 测试场景 | 操作步骤 | 预期结果 |
|----------|----------|----------|
| 单次失败 | 1. 停止Redis<br>2. 执行脚本1次 | 计数器=1,不重启 |
| 连续失败 | 1. 停止Redis<br>2. 执行脚本3次 | 第3次触发重启 |
| 恢复清零 | 1. 重启成功<br>2. 启动Redis<br>3. 执行脚本 | 计数器归0 |
---
## 六、部署步骤
### 6.1 备份
```bash
cp /opt/scripts/monitor_redis_service.sh /opt/scripts/monitor_redis_service.sh.bak
```
### 6.2 部署
```bash
# 上传新脚本
scp monitor_redis_service.sh user@server:/opt/scripts/
# 设置执行权限
chmod +x /opt/scripts/monitor_redis_service.sh
# 创建状态文件
touch /var/log/scripts/monitor_redis_service.state
```
### 6.3 验证
```bash
# 手动执行测试
/opt/scripts/monitor_redis_service.sh
# 检查日志
tail -f /var/log/scripts/monitor_redis_service.log
# 检查状态文件
cat /var/log/scripts/monitor_redis_service.state
```
---
## 七、回滚方案
### 7.1 回滚步骤
```bash
# 停止定时任务
crontab -e # 注释掉相关行
# 恢复原脚本
cp /opt/scripts/monitor_redis_service.sh.bak /opt/scripts/monitor_redis_service.sh
# 删除状态文件
rm -f /var/log/scripts/monitor_redis_service.state
# 重启定时任务
crontab -e # 取消注释
```
---
## 需求规范
- 代码规范: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
#!/bin/bash
#===============================================================================
# 脚本名称:auto_clean_deleted_ubains_v3.sh
# 功能描述:已删除大文件自动清理与容器重启脚本
# 版本:V3.0
# 创建日期:2026-01-27
# 更新日期:2026-03-30
#
# 监测对象:
# 1. 进程占用的已删除大文件(>1GB)
# 2. 匹配关键字: ubains-INFO-AND-ERROR
# 3. 自动清理并重启关联容器
# 4. 日志文件自动轮转(5MB轮转、保留7天)
#
# 清理策略:
# 1. 扫描所有进程的fd目录,查找deleted标记文件
# 2. 文件大小超过1GB时执行自动处理
# 3. 强制杀死占用进程
# 4. 重启docker容器ujava2
# 5. 若进程属于特定应用,启动该应用
#
# 使用方法:
# chmod +x auto_clean_deleted_ubains_v3.sh
# ./auto_clean_deleted_ubains_v3.sh
#
# 定时任务示例:
# 0 4 * * * /opt/scripts/auto_clean_deleted_ubains_v3.sh
#===============================================================================
# ================= 配置区域 =================
TARGET_KEY="ubains-INFO-AND-ERROR"
MIN_SIZE=$((1024*1024*1024)) # 1GB (单位:字节)
......
......@@ -29,6 +29,8 @@ CONTAINER_NAME="umysql"
DB_USER="root"
HOST_BACKUP_DIR="/opt/mysql" # 宿主机备份目录
LOG_FILE="/var/log/scripts/backup_mysql_databases.log"
MAX_LOG_SIZE=$((5*1024*1024)) # 5MB 日志大小限制
LOG_RETENTION_DAYS=30 # 日志保留天数
RETENTION_DAYS=30
TARGET_DBS=("devops" "devops_voice" "huazhao2" "nacos_mysql" "offline" "ubains" "wifi" "voice" "ubains_nacos_config" "ubains_sso")
......@@ -38,7 +40,21 @@ CONTAINER_TMP_DIR="/tmp/mysql_backup_$$.sql.gz" # 容器内临时目录(带PI
# ==================== 日志函数 ====================
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# ==================== 日志轮转函数 ====================
rotate_logs() {
if [ -f "$LOG_FILE" ]; then
FILE_SIZE=$(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0)
if [ "$FILE_SIZE" -ge "$MAX_LOG_SIZE" ]; then
mv "$LOG_FILE" "$LOG_FILE.$(date '+%Y%m%d%H%M%S')"
touch "$LOG_FILE"
log "日志文件超过 5MB,已自动轮转。"
fi
fi
# 清理超过保留天数的旧日志文件
find "$(dirname "$LOG_FILE")" -name "backup_mysql_databases.log.*" -mtime +$LOG_RETENTION_DAYS -exec rm -f {} \; 2>/dev/null
}
get_mysql_password() {
......@@ -47,7 +63,12 @@ get_mysql_password() {
# ==================== 初始化 ====================
mkdir -p "$HOST_BACKUP_DIR/$DATE"
mkdir -p "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"
# 执行日志轮转
rotate_logs
log "===== 开始备份任务 (容器: $CONTAINER_NAME) ====="
# 在容器内创建临时目录
......
......@@ -3,8 +3,9 @@
#===============================================================================
# 脚本名称:backup_mysql_logs.sh
# 功能描述:MySQL日志文件定时备份与压缩脚本
# 版本:V1.0
# 版本:V1.1
# 创建日期:2026-01-27
# 更新日期:2026-03-30
# 基于文档:_PRD_预定系统_MySQL日志备份需求文档.md
#
# 备份对象:
......@@ -12,6 +13,7 @@
# 2. 自动压缩备份文件
# 3. 保留原始文件权限
# 4. 自动清理过期备份
# 5. 日志文件自动轮转(5MB轮转、保留30天)
#
# 日志文件类型:
# *.log, *.slow, error.log, slow.log, mysqld.log
......@@ -28,14 +30,30 @@
MYSQL_LOG_DIR="/opt/mysql/logs" # MySQL日志目录
BACKUP_DIR="/opt/mysql/logs/backup" # 备份目录
LOG_FILE="/var/log/scripts/backup_mysql_logs.log" # 日志文件路径
RETENTION_DAYS=30 # 保留天数
MAX_LOG_SIZE=$((5*1024*1024)) # 5MB 日志大小限制
LOG_RETENTION_DAYS=30 # 日志保留天数
RETENTION_DAYS=30 # 备份保留天数
DATE=$(date +"%Y%m%d") # 当前日期格式 YYYYMMDD
TODAY_DIR="$BACKUP_DIR/$DATE" # 今天的备份目录
# ==================== 日志函数 ====================
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# ==================== 日志轮转函数 ====================
rotate_logs() {
if [ -f "$LOG_FILE" ]; then
FILE_SIZE=$(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0)
if [ "$FILE_SIZE" -ge "$MAX_LOG_SIZE" ]; then
mv "$LOG_FILE" "$LOG_FILE.$(date '+%Y%m%d%H%M%S')"
touch "$LOG_FILE"
log "日志文件超过 5MB,已自动轮转。"
fi
fi
# 清理超过保留天数的旧日志文件
find "$(dirname "$LOG_FILE")" -name "backup_mysql_logs.log.*" -mtime +$LOG_RETENTION_DAYS -exec rm -f {} \; 2>/dev/null
}
# ==================== 权限保存和恢复函数 ====================
......@@ -59,9 +77,13 @@ restore_permissions() {
local perms owner group
read -r perms owner group < "$perm_file"
# 恢复权限和属主
# 恢复权限和属主(增加空值检查)
if [ -n "$owner" ] && [ -n "$group" ]; then
chown "$owner:$group" "$file" 2>/dev/null
fi
if [ -n "$perms" ]; then
chmod "$perms" "$file" 2>/dev/null
fi
# 删除临时权限文件
rm -f "$perm_file"
......@@ -69,11 +91,17 @@ restore_permissions() {
}
# ==================== 主要功能 ====================
# 创建日志目录并确保存在
mkdir -p "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"
# 执行日志轮转
rotate_logs
log "===== 开始备份MySQL日志 (日期: $DATE) ====="
# 创建备份目录
mkdir -p "$TODAY_DIR"
touch "$LOG_FILE"
# 检查MySQL日志目录是否存在
if [ ! -d "$MYSQL_LOG_DIR" ]; then
......
......@@ -3,8 +3,9 @@
#===============================================================================
# 脚本名称:backup_nginx_logs.sh
# 功能描述:Nginx日志文件定时备份与压缩脚本
# 版本:V1.0
# 版本:V1.1
# 创建日期:2026-01-27
# 更新日期:2026-03-30
# 基于文档:_PRD_预定系统_Nginx日志备份需求文档.md
#
# 备份对象:
......@@ -13,6 +14,7 @@
# 3. 自动压缩并清空原日志文件
# 4. 向Nginx发送reopen信号重新打开日志
# 5. 自动清理过期备份
# 6. 日志文件自动轮转(5MB轮转、保留30天)
#
# 使用方法:
# chmod +x backup_nginx_logs.sh
......@@ -26,14 +28,30 @@
NGINX_LOG_DIR="/var/www/java/nginx-conf.d/nginx_log" # Nginx日志目录
BACKUP_DIR="$NGINX_LOG_DIR/backup" # 备份目录
LOG_FILE="/var/log/scripts/backup_nginx_logs.log" # 日志文件路径
RETENTION_DAYS=30 # 保留天数
MAX_LOG_SIZE=$((5*1024*1024)) # 5MB 日志大小限制
LOG_RETENTION_DAYS=30 # 日志保留天数
RETENTION_DAYS=30 # 备份保留天数
DATE=$(date +"%Y%m%d") # 当前日期格式 YYYYMMDD
TODAY_DIR="$BACKUP_DIR/$DATE" # 今天的备份目录
# ==================== 日志函数 ====================
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# ==================== 日志轮转函数 ====================
rotate_logs() {
if [ -f "$LOG_FILE" ]; then
FILE_SIZE=$(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0)
if [ "$FILE_SIZE" -ge "$MAX_LOG_SIZE" ]; then
mv "$LOG_FILE" "$LOG_FILE.$(date '+%Y%m%d%H%M%S')"
touch "$LOG_FILE"
log "日志文件超过 5MB,已自动轮转。"
fi
fi
# 清理超过保留天数的旧日志文件
find "$(dirname "$LOG_FILE")" -name "backup_nginx_logs.log.*" -mtime +$LOG_RETENTION_DAYS -exec rm -f {} \; 2>/dev/null
}
# ==================== 权限保存和恢复函数 ====================
......@@ -57,9 +75,13 @@ restore_permissions() {
local perms owner group
read -r perms owner group < "$perm_file"
# 恢复权限和属主
# 恢复权限和属主(增加空值检查)
if [ -n "$owner" ] && [ -n "$group" ]; then
chown "$owner:$group" "$file" 2>/dev/null
fi
if [ -n "$perms" ]; then
chmod "$perms" "$file" 2>/dev/null
fi
# 删除临时权限文件
rm -f "$perm_file"
......@@ -67,11 +89,17 @@ restore_permissions() {
}
# ==================== 主要功能 ====================
# 创建日志目录并确保存在
mkdir -p "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"
# 执行日志轮转
rotate_logs
log "===== 开始备份Nginx日志 (日期: $DATE) ====="
# 创建备份目录
mkdir -p "$TODAY_DIR"
touch "$LOG_FILE"
# 检查Nginx日志目录是否存在
if [ ! -d "$NGINX_LOG_DIR" ]; then
......
#!/bin/bash
#===============================================================================
# 脚本名称:check_deleted_file_ubains.sh
# 功能描述:已删除但仍被占用文件排查工具(内核直读版)
# 版本:V1.1
# 创建日期:2026-02-28
# 更新日期:2026-03-30
#
# 监测对象:
# 1. 扫描所有进程的fd目录
# 2. 查找已删除但仍被占用的文件
# 3. 统计占用空间大小
# 4. 显示进程信息和文件路径
#
# 使用方法:
# chmod +x check_deleted_file_ubains.sh
# ./check_deleted_file_ubains.sh
#
# 注意事项:
# 本脚本为检查工具,仅显示信息不执行清理操作
# 清理操作请使用 auto_clean_deleted_ubains_v3.sh
#===============================================================================
echo "==============================================="
echo " Linux 已删除但仍被占用文件排查工具 (内核直读版)"
echo "==============================================="
......@@ -31,7 +54,7 @@ for fd_path in /proc/[0-9]*/fd/*; do
# 注意:对于已删除文件,直接 stat fd 路径是获取该文件大小最准确的方法
size_bytes=$(stat -L -c %s "$fd_path" 2>/dev/null || echo 0)
if [ "$size_bytes" -gt 0 ] || [[ "$target_file" == *"$TARGET_KEY"* ]]; then
if [ "$size_bytes" -gt 0 ]; then
found_count=$((found_count + 1))
total_size=$((total_size + size_bytes))
......
#!/bin/bash
#===============================================================================
# 脚本名称:monitor_external_api_services_v2.sh
# 功能描述:外部API服务监测与自愈脚本
# 版本:V1.1
# 创建日期:2026-01-27
# 更新日期:2026-03-30
# 基于文档:_PRD_预定系统外部API服务监控需求文档.md (V1.1)
#
# 监测对象:
# 1. ubains-meeting-api-1.0-SNAPSHOT.jar
# 2. malan服务
#
# 恢复策略:
# 1. 连续失败阈值判断(默认3次)
# 2. 每个服务独立维护失败计数器
# 3. 达到阈值时启动服务
#
# 使用方法:
# chmod +x monitor_external_api_services_v2.sh
# ./monitor_external_api_services_v2.sh
#
# 定时任务示例:
# */5 * * * * /opt/scripts/monitor_external_api_services_v2.sh
#===============================================================================
# --- 配置区域 ---
# 日志文件路径
LOG_FILE="/var/log/scripts/monitor_external_api_services.log"
MAX_LOG_SIZE=$((5*1024*1024)) # 5MB 日志大小限制
LOG_RETENTION_DAYS=30 # 日志保留天数
PID_FILE="/var/log/scripts/.external_api_monitor.pid"
# 状态文件配置
STATE_DIR="/var/log/scripts/external_api_state"
MAX_FAILURES=3
# 定义要监控的服务及其相关信息
# 格式: "服务名:目录路径:启动脚本路径"
......@@ -18,12 +50,96 @@ API_DATA='{
"password": "test"
}'
# --- 函数定义 ---
#===============================================================================
# 函数定义
#===============================================================================
# 获取锁函数(防止并发执行)
acquire_lock() {
# 检查 PID 文件是否存在
if [ -f "$PID_FILE" ]; then
local old_pid
old_pid=$(cat "$PID_FILE" 2>/dev/null)
# 检查该进程是否还在运行
if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - 警告: 上一次脚本执行仍在运行 (PID: $old_pid),本次跳过执行" | tee -a "$LOG_FILE"
exit 1
else
# 进程不存在,清理旧的 PID 文件
rm -f "$PID_FILE"
fi
fi
# 确保 PID 文件目录存在
local pid_dir
pid_dir=$(dirname "$PID_FILE")
if [ ! -d "$pid_dir" ]; then
mkdir -p "$pid_dir" 2>/dev/null || true
fi
# 写入当前进程 PID
echo $$ > "$PID_FILE"
# 设置退出时清理 PID 文件
trap 'rm -f "$PID_FILE"; exit' EXIT INT TERM HUP
}
# 日志轮转函数
rotate_logs() {
if [ -f "$LOG_FILE" ]; then
FILE_SIZE=$(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0)
if [ "$FILE_SIZE" -ge "$MAX_LOG_SIZE" ]; then
mv "$LOG_FILE" "$LOG_FILE.$(date '+%Y%m%d%H%M%S')"
touch "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') - 日志文件超过 5MB,已自动轮转。" | tee -a "$LOG_FILE"
fi
fi
# 清理超过保留天数的旧日志文件
find "$(dirname "$LOG_FILE")" -name "monitor_external_api_services.log.*" -mtime +$LOG_RETENTION_DAYS -exec rm -f {} \; 2>/dev/null
}
# 记录日志的函数
log_message() {
local message="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE"
}
# 获取服务状态文件路径
get_service_state_file() {
local service_name="$1"
# 服务名中的特殊字符替换为下划线
local safe_name=$(echo "$service_name" | tr -cd '[:alnum:]_-')
echo "${STATE_DIR}/${safe_name}.state"
}
# 读取服务状态文件
read_service_state() {
local service_name="$1"
local state_file
state_file=$(get_service_state_file "$service_name")
if [ -f "$state_file" ]; then
source "$state_file"
echo "${FAILURE_COUNT:-0}"
else
echo "0"
fi
}
# 写入服务状态文件
write_service_state() {
local service_name="$1"
local count="$2"
local state_file
state_file=$(get_service_state_file "$service_name")
# 确保状态目录存在
mkdir -p "$STATE_DIR"
cat > "$state_file" << EOF
FAILURE_COUNT=$count
LAST_CHECK_TIME=$(date +%s)
EOF
}
# 检查服务是否正常(通过 API 请求)
......@@ -98,7 +214,15 @@ start_service() {
)
}
# --- 主逻辑 ---
#===============================================================================
# 主逻辑
#===============================================================================
# 获取锁(防止并发执行)
acquire_lock
# 执行日志轮转
rotate_logs
# 初始化日志
log_message "=== 服务监控脚本开始执行 (API 检查模式) ==="
......@@ -114,6 +238,10 @@ for service_info in "${SERVICES[@]}"; do
log_message "检查服务: $service_name"
# 读取当前失败次数
failure_count=$(read_service_state "$service_name")
log_message "读取失败计数器: 当前失败次数 = $failure_count"
# 检查目录是否存在
if ! is_directory_exists "$dir_path"; then
log_message "跳过服务 '$service_name': 目录 '$dir_path' 不存在。"
......@@ -122,11 +250,28 @@ for service_info in "${SERVICES[@]}"; do
# 检查服务是否正常
if is_service_healthy "$service_name"; then
# 检查成功,清零计数器
if [ "$failure_count" -gt 0 ]; then
write_service_state "$service_name" 0
log_message "检查成功,重置失败计数器为 0"
fi
log_message "服务 '$service_name' 运行正常 (HTTP 200)。"
else
log_message "服务 '$service_name' 响应异常或未运行。"
# 检查失败,累加计数器
failure_count=$((failure_count + 1))
write_service_state "$service_name" "$failure_count"
log_message "失败计数器更新: $((failure_count - 1)) -> $failure_count (阈值: $MAX_FAILURES)"
# 判断是否达到阈值
if [ "$failure_count" -ge "$MAX_FAILURES" ]; then
log_message "错误: 连续失败达到阈值($MAX_FAILURES次),触发服务启动"
write_service_state "$service_name" 0
# 尝试启动服务
start_service "$service_name" "$dir_path" "$script_path"
else
log_message "警告: 未达到启动阈值,等待下次检查确认"
fi
fi
done
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论