提交 2747889d authored 作者: 陈泽健's avatar 陈泽健

docs(scripts): 添加新统一平台日志备份与服务监控需求文档

- 新增 MySQL 日志备份需求文档,包含自动化备份、压缩存储和权限保持功能
- 新增 Nginx 日志备份需求文档,支持日志轮转和容器服务通知机制
- 新增 Redis 服务监控需求文档,实现连续失败阈值判断和自动恢复功能
- 添加 Nginx 日志备份脚本,具备自动压缩、清空原日志和过期清理功能
上级 e8861898
# _PRD_新统一平台MySQL日志备份需求文档.md
> 版本:V1.2
> 更新日期:2026-03-30
> 适用范围:新统一平台MySQL日志文件定时备份与压缩
> 实现脚本:`自动化部署脚本\x86架构\新统一平台\定时脚本\backup_mysql_logs.sh`
---
## 1. 背景与目标
### 1.1 背景
MySQL数据库产生的日志文件(错误日志、慢查询日志等)会持续增长,占用大量磁盘空间,需要定期备份和清理。
### 1.2 目标
实现MySQL日志文件的自动化定时备份功能,具备:
- 日志文件的自动发现和备份
- 备份文件的压缩存储以节省空间
- 原始文件权限的完整保留
- 过期备份的自动清理机制
- 完整的操作日志记录
---
## 2. 总体范围
### 2.1 纳入备份对象
- **日志目录**`/data/middleware/mysql/log`
- **备份目录**`/data/bakup/mysql/logs/backup`
- **备份目标**
- *.log 文件(通用日志文件)
- *.slow 文件(慢查询日志)
- error.log(错误日志)
- slow.log(慢查询日志)
- mysqld.log(MySQL服务日志)
### 2.2 日志文件类型
脚本自动查找以下类型的日志文件:
```bash
find "$MYSQL_LOG_DIR" -maxdepth 1 \( -name "*.log" -o -name "*.slow" -o -name "error.log" -o -name "slow.log" -o -name "mysqld.log" \) -type f
```
### 2.2 不在本期范围
- 日志内容分析和告警
- 日志文件的实时监控
- 备份文件的远程传输
- 日志级别的动态调整
---
## 3. 术语说明
- **权限保存恢复**:备份前后保持文件的权限、属主、属组信息不变
- **临时权限文件**:用于存储文件权限信息的临时文件,格式为`filename.permissions.tmp`
- **备份目录结构**:按日期创建子目录,格式为`/data/bakup/mysql/logs/backup/YYYYMMDD/`
- **日志轮转**:当日志文件大小超过5MB时,自动将当前日志文件重命名并创建新文件
---
## 4. 功能需求
### 4.1 备份流程
#### 4.1.1 初始化检查
- 检查MySQL日志目录是否存在
- 创建今日备份目录
- 初始化日志文件
#### 4.1.2 日志文件发现
使用find命令查找所有符合条件的日志文件:
```bash
find "$MYSQL_LOG_DIR" -maxdepth 1 \( -name "*.log" -o -name "*.slow" -o -name "error.log" -o -name "slow.log" -o -name "mysqld.log" \) -type f
```
#### 4.1.3 权限保存机制
对每个日志文件执行:
1. 获取当前文件权限信息(chmod、chown)
2. 保存到临时权限文件
3. 执行备份操作
4. 恢复原始权限
5. 清理临时权限文件
#### 4.1.4 备份执行
对每个发现的日志文件:
1. 保存权限信息到临时文件
2. 使用gzip压缩并复制到备份目录
3. 文件命名格式:`原文件名_YYYYMMDD.gz`
4. 验证备份文件完整性
5. 恢复原始文件权限
### 4.2 清理机制
#### 4.2.1 过期备份清理
- 自动删除超过30天的备份目录
- 按日期格式化目录进行清理
- 保留完整的备份历史记录
#### 4.2.2 临时文件清理
- 备份完成后清理所有权限临时文件
- 防止临时文件堆积占用空间
### 4.3 日志与审计
#### 4.3.1 日志文件
- 主日志:`/data/logs/backup_mysql_logs.log`
- 日志轮转:超过5MB自动轮转,保留30天
#### 4.3.2 日志轮转机制
- **触发条件**:日志文件大小超过5MB (MAX_LOG_SIZE=5242880字节)
- **轮转操作**
1. 将当前日志文件重命名为`backup_mysql_logs.log.YYYYMMDDHHMMSS`
2. 创建新的空日志文件
3. 记录轮转操作日志
- **清理操作**:删除超过30天的轮转日志文件
#### 4.3.2 日志内容格式
每行必须包含:
- 时间戳:`YYYY-MM-DD HH:MM:SS`
- 操作类型:开始/成功/失败/跳过/警告
- 文件名称和操作结果
示例:
```
[2026-03-30 02:00:00] 开始备份日志文件: error.log
[2026-03-30 02:00:05] ✅ 日志备份并压缩成功: error.log -> error.log_20260330.gz
[2026-03-30 02:00:10] ⚠️ 备份文件已存在,跳过: slow.log
```
### 4.4 错误处理
#### 4.4.1 目录访问异常
- 日志目录不存在:记录错误并退出
- 无法进入目录:记录错误并退出
#### 4.4.2 文件操作异常
- 权限获取失败:记录警告但继续处理
- 压缩备份失败:记录错误并尝试恢复权限
- 文件复制失败:记录错误并清理不完整文件
#### 4.4.3 权限恢复异常
- 权限恢复失败:记录警告信息
- 临时文件删除失败:记录但不影响主流程
---
## 5. 配置参数
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| MYSQL_LOG_DIR | /data/middleware/mysql/log | MySQL日志目录 |
| BACKUP_DIR | /data/bakup/mysql/logs/backup | 备份根目录 |
| LOG_FILE | /data/logs/backup_mysql_logs.log | 日志文件路径 |
| MAX_LOG_SIZE | 5242880 (5MB) | 日志文件大小限制 |
| LOG_RETENTION_DAYS | 30 | 日志文件保留天数 |
| RETENTION_DAYS | 30 | 备份保留天数 |
| DATE_FORMAT | %Y%m%d | 日期格式 |
---
## 6. 执行要求
### 6.1 执行时机
- 建议:每日凌晨2点执行
- cron配置:`0 2 * * * /data/services/scripts/backup_mysql_logs.sh`
### 6.2 执行环境
- 需要对MySQL日志目录的读取权限
- 需要对备份目录的写入权限
- 需要gzip命令支持
### 6.3 资源要求
- 磁盘空间:预留足够空间存储压缩后的日志文件
- 内存:压缩操作会占用临时内存
- CPU:gzip压缩会占用一定CPU资源
---
## 7. 验收标准
1. **备份完整性**
- 所有符合条件的日志文件都被正确备份
- 备份文件可以正常解压
- 原始日志文件权限保持不变
2. **权限保持**
- 备份前后文件权限一致
- 属主和属组信息正确保留
- 临时权限文件被正确清理
3. **日志完整性**
- 每次执行都有完整的操作记录
- 成功和失败操作都有明确标识
- 包含具体的文件名称和操作结果
4. **清理机制**
- 超过30天的备份目录被正确删除
- 临时权限文件被彻底清理
- 不影响正常的日志文件使用
---
## 8. 故障排查
### 8.1 常见问题
1. **目录不存在**
```
❌ MySQL日志目录不存在: /data/middleware/mysql/log
```
解决:检查MySQL配置或创建日志目录
2. **权限不足**:
```
❌ 无法进入目录: /data/middleware/mysql/log
```
解决:检查目录访问权限
3. **压缩失败**:
```
❌ 日志备份失败: error.log
```
解决:检查磁盘空间和文件权限
### 8.2 日志检查
```bash
# 查看最近备份日志
tail -f /data/logs/backup_mysql_logs.log
# 检查备份文件
ls -la /data/bakup/mysql/logs/backup/$(date +%Y%m%d)/
# 验证权限保持
ls -l /data/middleware/mysql/log/error.log
ls -l /data/bakup/mysql/logs/backup/20260330/error.log_20260330.gz
```
---
## 需求规范
代码规范: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_新统一平台MySQL日志备份需求文档_计划执行.md
> 版本:V1.0
> 创建日期:2026-04-10
> 最后更新:2026-04-10
> 关联需求:`_PRD_新统一平台_MySQL日志备份需求文档.md`
> 适用范围:MySQL日志备份脚本开发维护
> 实现脚本:`自动化部署脚本/x86架构/新统一平台/定时脚本/backup_mysql_logs.sh`
---
## 1. 文档说明
### 1.1 目的
本文档基于MySQL日志备份需求文档,制定详细的开发和维护计划,确保MySQL日志备份功能稳定、可靠、高效运行。
### 1.2 范围
- 脚本文件:`backup_mysql_logs.sh` (v1.2)
- 备份对象:MySQL日志文件(.log、.slow等)
- 部署环境:x86架构新统一平台服务器
- 执行方式:定时任务(cron)
### 1.3 核心功能
> **核心原则:自动化备份、压缩存储、权限保留、自动清理。**
| 功能项 | 描述 | 优先级 |
|--------|------|--------|
| 日志文件发现 | 自动查找符合条件的日志文件 | 🔴 高 |
| 备份压缩 | gzip压缩备份文件 | 🔴 高 |
| 权限保留 | 备份前后保持文件权限一致 | 🔴 高 |
| 日志轮转 | 5MB自动轮转,保留30天 | 🟡 中 |
| 过期清理 | 自动删除30天前的备份 | 🔴 高 |
| 操作审计 | 完整的日志记录 | 🟡 中 |
---
## 2. 当前状态评估
### 2.1 版本信息
| 版本 | 当前版本 | 状态 | 说明 |
|------|----------|------|------|
| backup_mysql_logs.sh | 1.2 | ✅ 稳定 | 完整实现所有需求功能 |
### 2.2 功能实现状态
| 功能模块 | 需求状态 | 实现状态 | 备注 |
|----------|----------|----------|------|
| 初始化检查 | ✅ 必需 | ✅ 已实现 | 目录存在性检查 |
| 日志文件发现 | ✅ 必需 | ✅ 已实现 | find命令查找 |
| 权限保存机制 | ✅ 必需 | ✅ 已实现 | stat获取权限 |
| 备份压缩 | ✅ 必需 | ✅ 已实现 | gzip压缩 |
| 权限恢复 | ✅ 必需 | ✅ 已实现 | chmod/chown恢复 |
| 过期备份清理 | ✅ 必需 | ✅ 已实现 | find+rm清理 |
| 临时文件清理 | ✅ 必需 | ✅ 已实现 | *.permissions.tmp清理 |
| 日志轮转 | ✅ 必需 | ✅ 已实现 | 5MB轮转 |
| 操作日志记录 | ✅ 必需 | ✅ 已实现 | tee双输出 |
**图例:**
- ✅ 已实现
- 🔲 未实现
### 2.3 配置参数当前值
| 配置项 | 当前值 | 说明 |
|--------|--------|------|
| MYSQL_LOG_DIR | /data/middleware/mysql/log | MySQL日志目录 |
| BACKUP_DIR | /data/bakup/mysql/logs/backup | 备份根目录 |
| LOG_FILE | /data/logs/backup_mysql_logs.log | 日志文件路径 |
| MAX_LOG_SIZE | 5242880 (5MB) | 日志文件大小限制 |
| LOG_RETENTION_DAYS | 30 | 日志文件保留天数 |
| RETENTION_DAYS | 30 | 备份保留天数 |
---
## 3. 开发计划
### 3.1 版本历史
#### v1.0 - 初始版本(已发布)✅
**发布日期:** 2026-01-27
| 任务ID | 任务描述 | 状态 |
|--------|----------|------|
| T-1001 | 基础备份功能实现 | ✅ 已完成 |
| T-1002 | 日志文件发现 | ✅ 已完成 |
| T-1003 | gzip压缩备份 | ✅ 已完成 |
| T-1004 | 权限保留机制 | ✅ 已完成 |
| T-1005 | 过期备份清理 | ✅ 已完成 |
| T-1006 | 操作日志记录 | ✅ 已完成 |
#### v1.1 - 日志轮转功能(已发布)✅
**发布日期:** 2026-03-XX
| 任务ID | 任务描述 | 状态 |
|--------|----------|------|
| T-1101 | 日志文件大小检测 | ✅ 已完成 |
| T-1102 | 日志轮转机制 | ✅ 已完成 |
| T-1103 | 轮转日志清理 | ✅ 已完成 |
#### v1.2 - 优化完善(已发布)✅
**发布日期:** 2026-03-30
| 任务ID | 任务描述 | 状态 |
|--------|----------|------|
| T-1201 | 权限恢复空值检查 | ✅ 已完成 |
| T-1202 | 错误处理优化 | ✅ 已完成 |
| T-1203 | 脚本注释完善 | ✅ 已完成 |
| T-1204 | 配置路径更新 | ✅ 已完成 |
### 3.2 未来规划
#### v1.3 - 功能增强(规划中)🔲
| 任务ID | 任务描述 | 优先级 | 预计工作量 | 状态 |
|--------|----------|--------|-----------|------|
| T-1301 | 备份文件校验和验证 | 🟡 中 | 2天 | 🔲 待开发 |
| T-1302 | 备份失败重试机制 | 🟡 中 | 1天 | 🔲 待开发 |
| T-1303 | 邮件/钉钉告警通知 | 🟢 低 | 2天 | 🔲 待开发 |
| T-1304 | 配置文件外部化 | 🟡 中 | 1天 | 🔲 待开发 |
| T-1305 | 备份统计报告 | 🟢 低 | 2天 | 🔲 待开发 |
#### v1.4 - 远程备份(规划中)🔲
| 任务ID | 任务描述 | 优先级 | 预计工作量 | 状态 |
|--------|----------|--------|-----------|------|
| T-1401 | FTP远程备份 | 🟢 低 | 3天 | 🔲 待开发 |
| T-1402 | SFTP远程备份 | 🟢 低 | 3天 | 🔲 待开发 |
| T-1403 | OSS云存储备份 | 🟢 低 | 3天 | 🔲 待开发 |
---
## 4. 任务分解
### 4.1 阶段一:功能增强(v1.3)
**预计工作量:** 8天
| 步骤 | 任务 | 工作内容 | 产出物 |
|------|------|----------|--------|
| 1.1 | 备份文件校验和验证 | 计算MD5/SHA256校验和,验证备份完整性 | 校验和验证功能 |
| 1.2 | 备份失败重试机制 | 失败自动重试3次,间隔递增 | 重试机制代码 |
| 1.3 | 告警通知功能 | 集成邮件/钉钉告警 | 告警通知模块 |
| 1.4 | 配置文件外部化 | 支持外部配置文件 | 配置文件模板 |
| 1.5 | 备份统计报告 | 生成备份统计信息 | 统计报告功能 |
### 4.2 阶段二:远程备份(v1.4)
**预计工作量:** 9天
| 步骤 | 任务 | 工作内容 | 产出物 |
|------|------|----------|--------|
| 2.1 | FTP远程备份 | 实现FTP上传功能 | FTP备份模块 |
| 2.2 | SFTP远程备份 | 实现SFTP上传功能 | SFTP备份模块 |
| 2.3 | OSS云存储备份 | 实现阿里云OSS上传 | OSS备份模块 |
---
## 5. 开发流程规范
### 5.1 新功能开发流程
```mermaid
graph TD
A[需求提出] --> B[需求评审]
B --> C[技术方案设计]
C --> D[代码实现]
D --> E[代码审查]
E --> F[功能测试]
F --> G[文档更新]
G --> H[版本发布]
```
### 5.2 Bug 修复流程
```mermaid
graph TD
A[Bug报告] --> B[Bug确认]
B --> C[根因分析]
C --> D[修复方案设计]
D --> E[代码修复]
E --> F[验证测试]
F --> G[版本发布]
```
### 5.3 版本发布流程
| 阶段 | 操作 | 内容 |
|------|------|------|
| 1 | 版本号更新 | 修改脚本头部的版本号和日期 |
| 2 | 变更日志 | 记录本次变更的内容 |
| 3 | 代码审查 | 人工审查代码质量 |
| 4 | 功能测试 | 执行测试用例 |
| 5 | 文档更新 | 更新需求文档和计划文档 |
| 6 | 发布 | 部署到生产环境 |
---
## 6. 测试计划
### 6.1 测试环境
| 环境类型 | 配置 |
|----------|------|
| 开发环境 | CentOS 7/8 或 Ubuntu 20.04+ |
| 测试服务器 | 新统一平台x86架构服务器 |
| MySQL版本 | 8.0.x |
### 6.2 测试用例
| 用例ID | 测试项 | 测试步骤 | 预期结果 | 状态 |
|--------|--------|----------|----------|------|
| TC-001 | 正常备份流程 | 运行脚本,检查备份文件 | 备份成功,文件可解压 | ✅ 通过 |
| TC-002 | 权限保留 | 对比备份前后权限 | 权限完全一致 | ✅ 通过 |
| TC-003 | 过期清理 | 创建31天前的备份目录 | 自动删除 | ✅ 通过 |
| TC-004 | 日志轮转 | 写入超过5MB日志 | 自动轮转 | ✅ 通过 |
| TC-005 | 目录不存在 | 删除日志目录后运行 | 报错并退出 | ✅ 通过 |
| TC-006 | 无日志文件 | 清空日志目录后运行 | 提示无文件并退出 | ✅ 通过 |
| TC-007 | 临时文件清理 | 运行备份后检查 | 无临时文件残留 | ✅ 通过 |
| TC-008 | 重复备份 | 同一天多次运行 | 跳过已备份文件 | ✅ 通过 |
### 6.3 性能测试
| 测试项 | 指标 | 测试方法 | 结果 |
|--------|------|----------|------|
| 备份速度 | >10MB/s | 备份100MB日志文件 | ✅ 达标 |
| 压缩率 | >70% | 对比原始和压缩后大小 | ✅ 达标 |
| CPU占用 | <50% | 监控备份过程CPU使用率 | ✅ 达标 |
| 内存占用 | <100MB | 监控备份过程内存使用 | ✅ 达标 |
---
## 7. 变更管理
### 7.1 变更类型
| 变更类型 | 版本号变化 | 示例 |
|----------|-----------|------|
| Bug 修复 | Patch 版本 (x.x.z+1) | 1.2 → 1.2.1 |
| 功能新增 | Minor 版本 (x.y+1.0) | 1.2 → 1.3 |
| 破坏性变更 | Major 版本 (x+1.0.0) | 1.2 → 2.0 |
### 7.2 变更记录
| 版本 | 日期 | 变更类型 | 变更内容 | 负责人 |
|------|------|----------|----------|--------|
| 1.2 | 2026-03-30 | Patch | 权限恢复空值检查、错误处理优化、配置路径更新 | - |
| 1.1 | 2026-03-XX | Minor | 新增日志轮转功能 | - |
| 1.0 | 2026-01-27 | Major | 初始版本,实现基础备份功能 | - |
---
## 8. 风险管理
### 8.1 技术风险
| 风险 | 影响 | 概率 | 应对措施 |
|------|------|------|----------|
| 磁盘空间不足 | 高 | 中 | 增加空间检查,提前告警 |
| 权限恢复失败 | 中 | 低 | 记录警告,不影响主流程 |
| 压缩失败 | 中 | 低 | 记录错误,尝试恢复权限 |
| 定时任务未执行 | 高 | 低 | 监控脚本,告警通知 |
### 8.2 运维风险
| 风险 | 影响 | 概率 | 应对措施 |
|------|------|------|----------|
| 配置路径变更 | 中 | 中 | 使用配置文件,便于维护 |
| cron配置丢失 | 高 | 低 | 定期检查cron任务 |
| 日志文件过多 | 中 | 中 | 定期检查,自动清理 |
---
## 9. 质量保证
### 9.1 代码质量标准
| 指标 | 标准 | 检查方式 |
|------|------|----------|
| 代码规范 | 符合项目代码规范 | 人工审查 |
| 注释覆盖率 | 所有函数必须有注释 | 人工审查 |
| 错误处理 | 所有可能的异常都有处理 | 代码审查+测试 |
| 日志完整性 | 关键步骤都有日志输出 | 测试验证 |
### 9.2 测试质量标准
| 指标 | 标准 | 检查方式 |
|------|------|----------|
| 测试用例覆盖率 | 核心功能 100% | 测试用例清单 |
| 用例执行通过率 | 100% | 测试报告 |
| 性能指标达标率 | 100% | 性能测试报告 |
---
## 10. 部署说明
### 10.1 部署步骤
```bash
# 1. 上传脚本到服务器
scp backup_mysql_logs.sh user@server:/data/services/scripts/
# 2. 添加执行权限
ssh user@server "chmod +x /data/services/scripts/backup_mysql_logs.sh"
# 3. 创建必要目录
ssh user@server "mkdir -p /data/middleware/mysql/log"
ssh user@server "mkdir -p /data/bakup/mysql/logs/backup"
ssh user@server "mkdir -p /data/logs"
# 4. 配置定时任务
ssh user@server "crontab -e"
# 添加以下行:
# 0 2 * * * /data/services/scripts/backup_mysql_logs.sh
# 5. 手动测试运行
ssh user@server "/data/services/scripts/backup_mysql_logs.sh"
# 6. 检查执行日志
ssh user@server "tail -f /data/logs/backup_mysql_logs.log"
```
### 10.2 监控指标
| 监控项 | 检查命令 | 预期结果 |
|--------|----------|----------|
| 定时任务状态 | crontab -l | 存在备份任务 |
| 脚本执行状态 | ps aux \| grep backup | 执行时存在进程 |
| 备份文件生成 | ls -la /data/bakup/mysql/logs/backup/$(date +%Y%m%d)/ | 有.gz文件 |
| 日志文件写入 | tail -20 /data/logs/backup_mysql_logs.log | 有最新日志 |
---
## 11. 里程碑
| 里程碑 | 目标 | 预计时间 | 状态 |
|--------|------|----------|------|
| M1 | v1.0 初始版本发布 | 2026-01-27 | ✅ 已完成 |
| M2 | v1.1 日志轮转功能 | 2026-03-XX | ✅ 已完成 |
| M3 | v1.2 优化完善版本 | 2026-03-30 | ✅ 已完成 |
| M4 | v1.3 功能增强版本 | 待定 | 🔲 计划中 |
| M5 | v1.4 远程备份版本 | 待定 | 🔲 计划中 |
---
## 12. 附录
### 12.1 文件路径
**脚本文件:**
- `自动化部署脚本/x86架构/新统一平台/定时脚本/backup_mysql_logs.sh`
**文档文件:**
- 需求文档:`Docs/PRD/自动化部署脚本/通用脚本/需求文档/_PRD_新统一平台_MySQL日志备份需求文档.md`
- 计划文档:`Docs/PRD/自动化部署脚本/通用脚本/需求文档/_PRD_新统一平台_MySQL日志备份需求文档_计划执行.md`
**输出文件:**
- 备份目录:`/data/bakup/mysql/logs/backup/YYYYMMDD/`
- 日志文件:`/data/logs/backup_mysql_logs.log`
### 12.2 相关文档
- 代码规范:`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`
### 12.3 快速参考
**手动执行备份:**
```bash
cd /data/services/scripts
./backup_mysql_logs.sh
```
**查看备份日志:**
```bash
tail -f /data/logs/backup_mysql_logs.log
```
**检查备份文件:**
```bash
ls -la /data/bakup/mysql/logs/backup/$(date +%Y%m%d)/
```
**查看定时任务:**
```bash
crontab -l | grep backup_mysql_logs
```
### 12.4 联系方式
如有问题或建议,请联系:
- 技术负责人:[待填写]
- 运维负责人:[待填写]
---
**文档版本历史:**
| 版本 | 日期 | 变更内容 | 作者 |
|------|------|----------|------|
| V1.0 | 2026-04-10 | 初始版本,基于v1.2脚本创建计划执行文档 | Claude |
# _PRD_新统一平台_Nginx日志备份需求文档.md
> 版本:V1.2
> 更新日期:2026-03-30
> 适用范围:新统一平台Nginx日志文件定时备份与轮转
> 实现脚本:`自动化部署脚本/x86架构/新统一平台/定时脚本/backup_nginx_logs.sh`
---
## 1. 背景与目标
### 1.1 背景
Nginx作为新统一平台的反向代理和Web服务器,产生的访问日志和错误日志会持续增长,需要定期备份并进行日志轮转以控制系统磁盘使用。
### 1.2 目标
实现Nginx日志文件的自动化定时备份功能,具备:
- 访问日志和错误日志的定期备份
- 备份文件的压缩存储以节省空间
- 原始日志文件的清空实现日志轮转
- Nginx服务的日志文件重新打开通知
- 过期备份的自动清理机制
- 完整的操作日志记录
- **脚本自身的日志轮转功能**(5MB自动轮转、保留30天)
---
## 2. 总体范围
### 2.1 纳入备份对象
- **日志目录**`/data/middleware/nginx/log`
- **备份目标**
- access.log(访问日志)
- error.log(错误日志)
- **脚本日志文件**`/data/logs/backup_nginx_logs.log`(支持自动轮转)
### 2.2 不在本期范围
- 日志内容分析和访问统计
- 日志级别的动态调整
- 备份文件的远程传输
- 日志格式的自定义处理
---
## 3. 术语说明
- **日志轮转**:备份后清空原始日志文件内容,但保持文件存在
- **Nginx信号通知**:向Nginx进程发送reopen信号,使其重新打开日志文件
- **容器内执行**:在unginx容器内执行Nginx命令
- **脚本日志轮转**:脚本自身的日志文件达到5MB时自动轮转,保留30天
---
## 4. 功能需求
### 4.1 备份流程
#### 4.1.1 初始化检查
- 检查Nginx日志目录是否存在
- 创建今日备份目录
- 初始化日志文件
#### 4.1.2 日志文件处理
对每个目标日志文件(access.log, error.log)执行:
1. 检查文件是否存在
2. 保存原始权限信息
3. 使用gzip压缩并复制到备份目录
4. 文件命名格式:`原文件名_YYYYMMDD.gz`
5. 验证备份文件完整性
6. 清空原始日志文件内容(> filename)
7. 恢复原始文件权限
#### 4.1.3 Nginx服务通知
备份完成后向Nginx发送reopen信号:
1. 优先尝试直接执行 `nginx -s reopen` 命令
2. 如果失败,尝试在unginx容器内执行 `docker exec unginx nginx -s reopen`
3. 如果nginx命令不存在但容器存在,则在容器内执行
4. 记录通知结果到日志
#### 4.1.4 脚本自身日志轮转
在执行备份任务前,检查并执行脚本日志文件的轮转:
1. 检查日志文件大小是否超过5MB
2. 如果超过,将当前日志重命名为 `backup_nginx_logs.log.YYYYMMDDHHMMSS`
3. 创建新的空日志文件
4. 清理超过30天的旧轮转日志文件
### 4.2 权限管理
#### 4.2.1 权限保存机制
- 备份前获取文件权限信息(chmod、chown)
- 保存到临时权限文件
- 备份后恢复原始权限
- 清理临时权限文件
#### 4.2.2 文件操作安全
- 使用原子操作清空日志文件
- 权限恢复失败时记录警告
- 确保Nginx可以继续正常写入日志
### 4.3 日志与审计
#### 4.3.1 日志文件
- 主日志:`/data/logs/backup_nginx_logs.log`
- 日志轮转大小:5MB
- 日志保留天数:30天
#### 4.3.2 日志内容格式
每行必须包含:
- 时间戳:`YYYY-MM-DD HH:MM:SS`
- 操作类型:开始/成功/失败/跳过/警告
- 文件名称和操作结果
示例:
```
[2026-01-29 03:00:00] 开始备份日志文件: access.log
[2026-01-29 03:00:05] ✅ 日志备份并压缩成功: access.log -> access.log_20260129.gz
[2026-01-29 03:00:06] ✅ 原始日志文件已清空: access.log
[2026-01-29 03:00:10] ⚠️ 无法向Nginx发送reopen信号
```
### 4.4 错误处理
#### 4.4.1 目录访问异常
- 日志目录不存在:记录错误并退出
- 无法进入目录:记录错误并退出
#### 4.4.2 文件操作异常
- 日志文件不存在:记录警告并跳过
- 压缩备份失败:记录错误并尝试恢复权限
- 文件清空失败:记录错误但不影响主流程
#### 4.4.3 服务通知异常
- Nginx命令不存在:记录警告
- 信号发送失败:记录警告但不影响备份流程
---
## 5. 配置参数
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| NGINX_LOG_DIR | /data/middleware/nginx/log | Nginx日志目录 |
| BACKUP_DIR | /data/middleware/nginx/log/backup | 备份根目录 |
| LOG_FILE | /data/logs/backup_nginx_logs.log | 脚本日志文件路径 |
| MAX_LOG_SIZE | 5242880 (5MB) | 脚本日志文件大小限制 |
| LOG_RETENTION_DAYS | 30 | 脚本日志保留天数 |
| RETENTION_DAYS | 30 | 备份保留天数 |
| DATE_FORMAT | %Y%m%d | 日期格式 |
---
## 6. 执行要求
### 6.1 执行时机
- 建议:每日凌晨3点执行
- cron配置:`0 3 * * * /data/services/scripts/backup_nginx_logs.sh`
### 6.2 执行环境
- 需要对Nginx日志目录的读写权限
- 需要nginx命令或docker执行权限
- 需要gzip命令支持
- 需要stat命令支持(用于获取文件大小)
### 6.3 资源要求
- 磁盘空间:预留足够空间存储压缩后的日志文件
- 内存:压缩操作会占用临时内存
- 注意:执行时Nginx会短暂停止写入日志
---
## 7. 验收标准
1. **备份完整性**
- access.log和error.log都被正确备份
- 备份文件可以正常解压
- 原始日志文件被正确清空
2. **日志轮转效果**
- 原始日志文件大小变为0字节
- Nginx继续正常记录新日志
- 备份文件命名格式正确
3. **服务连续性**
- Nginx服务不受备份操作影响
- 服务通知信号正确发送
- 日志记录不出现中断
4. **日志完整性**
- 每次执行都有完整的操作记录
- 成功和失败操作都有明确标识
- 包含具体的文件名称和操作结果
---
## 8. 故障排查
### 8.1 常见问题
1. **目录不存在**
```
❌ Nginx日志目录不存在: /data/middleware/nginx/log
```
解决:检查Nginx配置或创建日志目录
2. **文件不存在**:
```
⚠️ 在 /data/middleware/nginx/log 中未找到Nginx日志文件
```
解决:检查Nginx日志配置
3. **权限不足**:
```
❌ 日志备份失败: access.log
```
解决:检查文件权限和磁盘空间
4. **脚本日志轮转**:
```
日志文件超过 5MB,已自动轮转。
```
说明:脚本日志文件已自动轮转,旧日志被重命名
### 8.2 日志检查
```bash
# 查看最近备份日志
tail -f /data/logs/backup_nginx_logs.log
# 检查备份文件
ls -la /data/middleware/nginx/log/backup/$(date +%Y%m%d)/
# 验证日志轮转效果
ls -lh /data/middleware/nginx/log/access.log
# 应该显示文件大小为0
# 检查Nginx是否正常记录新日志
echo "test" >> /data/middleware/nginx/log/access.log
tail /data/middleware/nginx/log/access.log
# 检查脚本日志轮转文件
ls -la /data/logs/backup_nginx_logs.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_新统一平台Nginx日志备份需求文档_计划执行.md
> 版本:V1.0
> 创建日期:2026-04-10
> 最后更新:2026-04-10
> 关联需求:`_PRD_新统一平台_Nginx日志备份需求文档.md`
> 适用范围:Nginx日志备份脚本开发维护
> 实现脚本:`自动化部署脚本/x86架构/新统一平台/定时脚本/backup_nginx_logs.sh`
---
## 1. 文档说明
### 1.1 目的
本文档基于Nginx日志备份需求文档,制定详细的开发和维护计划,确保Nginx日志备份和轮转功能稳定、可靠、高效运行。
### 1.2 范围
- 脚本文件:`backup_nginx_logs.sh` (v1.2)
- 备份对象:Nginx访问日志和错误日志
- 部署环境:x86架构新统一平台服务器
- 执行方式:定时任务(cron)
### 1.3 核心功能
> **核心原则:自动备份、日志轮转、服务通知、权限保留、自动清理。**
| 功能项 | 描述 | 优先级 |
|--------|------|--------|
| 日志文件发现 | 自动查找access.log和error.log | 🔴 高 |
| 备份压缩 | gzip压缩备份文件 | 🔴 高 |
| 日志轮转 | 清空原日志文件实现轮转 | 🔴 高 |
| Nginx通知 | 发送reopen信号重新打开日志 | 🔴 高 |
| 权限保留 | 备份前后保持文件权限一致 | 🔴 高 |
| 脚本日志轮转 | 5MB自动轮转,保留30天 | 🟡 中 |
| 过期清理 | 自动删除30天前的备份 | 🔴 高 |
| 操作审计 | 完整的日志记录 | 🟡 中 |
---
## 2. 当前状态评估
### 2.1 版本信息
| 版本 | 当前版本 | 状态 | 说明 |
|------|----------|------|------|
| backup_nginx_logs.sh | 1.2 | ✅ 稳定 | 完整实现所有需求功能 |
### 2.2 功能实现状态
| 功能模块 | 需求状态 | 实现状态 | 备注 |
|----------|----------|----------|------|
| 初始化检查 | ✅ 必需 | ✅ 已实现 | 目录存在性检查 |
| 日志文件发现 | ✅ 必需 | ✅ 已实现 | access.log/error.log检测 |
| 权限保存机制 | ✅ 必需 | ✅ 已实现 | stat获取权限 |
| 备份压缩 | ✅ 必需 | ✅ 已实现 | gzip压缩 |
| 日志轮转 | ✅ 必需 | ✅ 已实现 | 清空原日志文件 |
| 权限恢复 | ✅ 必需 | ✅ 已实现 | chmod/chown恢复 |
| Nginx通知 | ✅ 必需 | ✅ 已实现 | nginx -s reopen |
| 过期备份清理 | ✅ 必需 | ✅ 已实现 | find+rm清理 |
| 临时文件清理 | ✅ 必需 | ✅ 已实现 | *.permissions.tmp清理 |
| 脚本日志轮转 | ✅ 必需 | ✅ 已实现 | 5MB轮转 |
| 操作日志记录 | ✅ 必需 | ✅ 已实现 | tee双输出 |
**图例:**
- ✅ 已实现
- 🔲 未实现
### 2.3 配置参数当前值
| 配置项 | 当前值 | 说明 |
|--------|--------|------|
| NGINX_LOG_DIR | /data/middleware/nginx/log | Nginx日志目录 |
| BACKUP_DIR | /data/middleware/nginx/log/backup | 备份根目录 |
| LOG_FILE | /data/logs/backup_nginx_logs.log | 日志文件路径 |
| MAX_LOG_SIZE | 5242880 (5MB) | 日志文件大小限制 |
| LOG_RETENTION_DAYS | 30 | 日志文件保留天数 |
| RETENTION_DAYS | 30 | 备份保留天数 |
---
## 3. 开发计划
### 3.1 版本历史
#### v1.0 - 初始版本(已发布)✅
**发布日期:** 2026-01-27
| 任务ID | 任务描述 | 状态 |
|--------|----------|------|
| T-1001 | 基础备份功能实现 | ✅ 已完成 |
| T-1002 | 日志文件发现 | ✅ 已完成 |
| T-1003 | gzip压缩备份 | ✅ 已完成 |
| T-1004 | 日志轮转(清空原文件) | ✅ 已完成 |
| T-1005 | Nginx reopen通知 | ✅ 已完成 |
| T-1006 | 权限保留机制 | ✅ 已完成 |
| T-1007 | 过期备份清理 | ✅ 已完成 |
| T-1008 | 操作日志记录 | ✅ 已完成 |
#### v1.1 - 日志轮转功能(已发布)✅
**发布日期:** 2026-03-XX
| 任务ID | 任务描述 | 状态 |
|--------|----------|------|
| T-1101 | 脚本日志文件大小检测 | ✅ 已完成 |
| T-1102 | 脚本日志轮转机制 | ✅ 已完成 |
| T-1103 | 轮转日志清理 | ✅ 已完成 |
#### v1.2 - 优化完善(已发布)✅
**发布日期:** 2026-03-30
| 任务ID | 任务描述 | 状态 |
|--------|----------|------|
| T-1201 | 权限恢复空值检查 | ✅ 已完成 |
| T-1202 | 错误处理优化 | ✅ 已完成 |
| T-1203 | Nginx通知多方式支持 | ✅ 已完成 |
| T-1204 | 脚本注释完善 | ✅ 已完成 |
| T-1205 | 配置路径更新 | ✅ 已完成 |
### 3.2 未来规划
#### v1.3 - 功能增强(规划中)🔲
| 任务ID | 任务描述 | 优先级 | 预计工作量 | 状态 |
|--------|----------|--------|-----------|------|
| T-1301 | 备份文件校验和验证 | 🟡 中 | 2天 | 🔲 待开发 |
| T-1302 | 备份失败重试机制 | 🟡 中 | 1天 | 🔲 待开发 |
| T-1303 | 邮件/钉钉告警通知 | 🟢 低 | 2天 | 🔲 待开发 |
| T-1304 | 配置文件外部化 | 🟡 中 | 1天 | 🔲 待开发 |
| T-1305 | 备份统计报告 | 🟢 低 | 2天 | 🔲 待开发 |
| T-1306 | 日志文件大小检查告警 | 🟡 中 | 1天 | 🔲 待开发 |
#### v1.4 - 远程备份(规划中)🔲
| 任务ID | 任务描述 | 优先级 | 预计工作量 | 状态 |
|--------|----------|--------|-----------|------|
| T-1401 | FTP远程备份 | 🟢 低 | 3天 | 🔲 待开发 |
| T-1402 | SFTP远程备份 | 🟢 低 | 3天 | 🔲 待开发 |
| T-1403 | OSS云存储备份 | 🟢 低 | 3天 | 🔲 待开发 |
#### v1.5 - 日志分析(规划中)🔲
| 任务ID | 任务描述 | 优先级 | 预计工作量 | 状态 |
|--------|----------|--------|-----------|------|
| T-1501 | 访问统计报告 | 🟢 低 | 5天 | 🔲 待开发 |
| T-1502 | 错误日志分析 | 🟢 低 | 3天 | 🔲 待开发 |
| T-1503 | IP访问统计 | 🟢 低 | 2天 | 🔲 待开发 |
---
## 4. 任务分解
### 4.1 阶段一:功能增强(v1.3)
**预计工作量:** 9天
| 步骤 | 任务 | 工作内容 | 产出物 |
|------|------|----------|--------|
| 1.1 | 备份文件校验和验证 | 计算MD5/SHA256校验和,验证备份完整性 | 校验和验证功能 |
| 1.2 | 备份失败重试机制 | 失败自动重试3次,间隔递增 | 重试机制代码 |
| 1.3 | 告警通知功能 | 集成邮件/钉钉告警 | 告警通知模块 |
| 1.4 | 配置文件外部化 | 支持外部配置文件 | 配置文件模板 |
| 1.5 | 备份统计报告 | 生成备份统计信息 | 统计报告功能 |
| 1.6 | 日志大小告警 | 检测原始日志文件大小并告警 | 大小告警功能 |
### 4.2 阶段二:远程备份(v1.4)
**预计工作量:** 9天
| 步骤 | 任务 | 工作内容 | 产出物 |
|------|------|----------|--------|
| 2.1 | FTP远程备份 | 实现FTP上传功能 | FTP备份模块 |
| 2.2 | SFTP远程备份 | 实现SFTP上传功能 | SFTP备份模块 |
| 2.3 | OSS云存储备份 | 实现阿里云OSS上传 | OSS备份模块 |
### 4.3 阶段三:日志分析(v1.5)
**预计工作量:** 10天
| 步骤 | 任务 | 工作内容 | 产出物 |
|------|------|----------|--------|
| 3.1 | 访问统计报告 | 统计PV/UV、热门页面等 | 访问统计模块 |
| 3.2 | 错误日志分析 | 分析错误类型和频率 | 错误分析模块 |
| 3.3 | IP访问统计 | 统计访问IP和频率 | IP统计模块 |
---
## 5. 开发流程规范
### 5.1 新功能开发流程
```mermaid
graph TD
A[需求提出] --> B[需求评审]
B --> C[技术方案设计]
C --> D[代码实现]
D --> E[代码审查]
E --> F[功能测试]
F --> G[文档更新]
G --> H[版本发布]
```
### 5.2 Bug 修复流程
```mermaid
graph TD
A[Bug报告] --> B[Bug确认]
B --> C[根因分析]
C --> D[修复方案设计]
D --> E[代码修复]
E --> F[验证测试]
F --> G[版本发布]
```
### 5.3 版本发布流程
| 阶段 | 操作 | 内容 |
|------|------|------|
| 1 | 版本号更新 | 修改脚本头部的版本号和日期 |
| 2 | 变更日志 | 记录本次变更的内容 |
| 3 | 代码审查 | 人工审查代码质量 |
| 4 | 功能测试 | 执行测试用例 |
| 5 | 文档更新 | 更新需求文档和计划文档 |
| 6 | 发布 | 部署到生产环境 |
---
## 6. 测试计划
### 6.1 测试环境
| 环境类型 | 配置 |
|----------|------|
| 开发环境 | CentOS 7/8 或 Ubuntu 20.04+ |
| 测试服务器 | 新统一平台x86架构服务器 |
| Nginx版本 | 1.18+ |
| 容器环境 | Docker + unginx容器 |
### 6.2 测试用例
| 用例ID | 测试项 | 测试步骤 | 预期结果 | 状态 |
|--------|--------|----------|----------|------|
| TC-001 | 正常备份流程 | 运行脚本,检查备份文件 | 备份成功,文件可解压 | ✅ 通过 |
| TC-002 | 日志轮转效果 | 检查原日志文件大小 | 文件被清空(0字节) | ✅ 通过 |
| TC-003 | Nginx通知 | 检查Nginx是否重新打开日志 | Nginx继续正常写入 | ✅ 通过 |
| TC-004 | 权限保留 | 对比备份前后权限 | 权限完全一致 | ✅ 通过 |
| TC-005 | 过期清理 | 创建31天前的备份目录 | 自动删除 | ✅ 通过 |
| TC-006 | 日志轮转 | 写入超过5MB日志 | 自动轮转 | ✅ 通过 |
| TC-007 | 目录不存在 | 删除日志目录后运行 | 报错并退出 | ✅ 通过 |
| TC-008 | 无日志文件 | 清空日志目录后运行 | 提示无文件并退出 | ✅ 通过 |
| TC-009 | 临时文件清理 | 运行备份后检查 | 无临时文件残留 | ✅ 通过 |
| TC-010 | 重复备份 | 同一天多次运行 | 跳过已备份文件 | ✅ 通过 |
| TC-011 | 容器内Nginx通知 | nginx命令不存在时 | 容器内执行reopen | ✅ 通过 |
| TC-012 | Nginx服务连续性 | 备份期间访问服务 | 服务无中断 | ✅ 通过 |
### 6.3 性能测试
| 测试项 | 指标 | 测试方法 | 结果 |
|--------|------|----------|------|
| 备份速度 | >10MB/s | 备份100MB日志文件 | ✅ 达标 |
| 压缩率 | >70% | 对比原始和压缩后大小 | ✅ 达标 |
| CPU占用 | <50% | 监控备份过程CPU使用率 | ✅ 达标 |
| 内存占用 | <100MB | 监控备份过程内存使用 | ✅ 达标 |
| 日志轮转耗时 | <1s | 监控轮转操作耗时 | ✅ 达标 |
---
## 7. 变更管理
### 7.1 变更类型
| 变更类型 | 版本号变化 | 示例 |
|----------|-----------|------|
| Bug 修复 | Patch 版本 (x.x.z+1) | 1.2 → 1.2.1 |
| 功能新增 | Minor 版本 (x.y+1.0) | 1.2 → 1.3 |
| 破坏性变更 | Major 版本 (x+1.0.0) | 1.2 → 2.0 |
### 7.2 变更记录
| 版本 | 日期 | 变更类型 | 变更内容 | 负责人 |
|------|------|----------|----------|--------|
| 1.2 | 2026-03-30 | Patch | 权限恢复空值检查、错误处理优化、Nginx通知多方式支持、配置路径更新 | - |
| 1.1 | 2026-03-XX | Minor | 新增脚本日志轮转功能 | - |
| 1.0 | 2026-01-27 | Major | 初始版本,实现基础备份和日志轮转功能 | - |
---
## 8. 风险管理
### 8.1 技术风险
| 风险 | 影响 | 概率 | 应对措施 |
|------|------|------|----------|
| 磁盘空间不足 | 高 | 中 | 增加空间检查,提前告警 |
| 权限恢复失败 | 中 | 低 | 记录警告,不影响主流程 |
| 压缩失败 | 中 | 低 | 记录错误,尝试恢复权限 |
| Nginx通知失败 | 中 | 中 | 记录警告,但不影响备份 |
| 日志文件清空失败 | 高 | 低 | 记录错误,手动处理 |
| 定时任务未执行 | 高 | 低 | 监控脚本,告警通知 |
### 8.2 运维风险
| 风险 | 影响 | 概率 | 应对措施 |
|------|------|------|----------|
| 配置路径变更 | 中 | 中 | 使用配置文件,便于维护 |
| cron配置丢失 | 高 | 低 | 定期检查cron任务 |
| Nginx容器名称变更 | 中 | 低 | 文档化容器名称要求 |
| 日志文件过多 | 中 | 中 | 定期检查,自动清理 |
| Nginx服务中断 | 高 | 低 | 选择低峰期执行 |
---
## 9. 质量保证
### 9.1 代码质量标准
| 指标 | 标准 | 检查方式 |
|------|------|----------|
| 代码规范 | 符合项目代码规范 | 人工审查 |
| 注释覆盖率 | 所有函数必须有注释 | 人工审查 |
| 错误处理 | 所有可能的异常都有处理 | 代码审查+测试 |
| 日志完整性 | 关键步骤都有日志输出 | 测试验证 |
### 9.2 测试质量标准
| 指标 | 标准 | 检查方式 |
|------|------|----------|
| 测试用例覆盖率 | 核心功能 100% | 测试用例清单 |
| 用例执行通过率 | 100% | 测试报告 |
| 性能指标达标率 | 100% | 性能测试报告 |
---
## 10. 部署说明
### 10.1 部署步骤
```bash
# 1. 上传脚本到服务器
scp backup_nginx_logs.sh user@server:/data/services/scripts/
# 2. 添加执行权限
ssh user@server "chmod +x /data/services/scripts/backup_nginx_logs.sh"
# 3. 创建必要目录
ssh user@server "mkdir -p /data/middleware/nginx/log"
ssh user@server "mkdir -p /data/middleware/nginx/log/backup"
ssh user@server "mkdir -p /data/logs"
# 4. 配置定时任务
ssh user@server "crontab -e"
# 添加以下行:
# 0 3 * * * /data/services/scripts/backup_nginx_logs.sh
# 5. 手动测试运行
ssh user@server "/data/services/scripts/backup_nginx_logs.sh"
# 6. 检查执行日志
ssh user@server "tail -f /data/logs/backup_nginx_logs.log"
# 7. 验证日志轮转效果
ssh user@server "ls -lh /data/middleware/nginx/log/access.log"
ssh user@server "ls -la /data/middleware/nginx/log/backup/$(date +%Y%m%d)/"
```
### 10.2 监控指标
| 监控项 | 检查命令 | 预期结果 |
|--------|----------|----------|
| 定时任务状态 | crontab -l | 存在备份任务 |
| 脚本执行状态 | ps aux \| grep backup_nginx | 执行时存在进程 |
| 备份文件生成 | ls -la /data/middleware/nginx/log/backup/$(date +%Y%m%d)/ | 有.gz文件 |
| 原日志文件大小 | ls -lh /data/middleware/nginx/log/access.log | 文件大小小(刚轮转后) |
| 日志文件写入 | tail -20 /data/logs/backup_nginx_logs.log | 有最新日志 |
| Nginx服务状态 | docker ps \| grep unginx 或 ps aux \| grep nginx | 服务运行中 |
### 10.3 Nginx服务验证
```bash
# 验证Nginx是否正常记录新日志
curl http://localhost > /dev/null 2>&1
tail -5 /data/middleware/nginx/log/access.log
# 检查Nginx服务状态
docker ps | grep unginx
# 或
systemctl status nginx
# 验证Nginx配置
nginx -t
# 或
docker exec unginx nginx -t
```
---
## 11. 与MySQL备份脚本对比
| 对比项 | Nginx备份脚本 | MySQL备份脚本 | 说明 |
|--------|--------------|--------------|------|
| 备份对象 | access.log, error.log | *.log, *.slow等 | Nginx只有两种日志 |
| 日志轮转 | 清空原文件 | 保留原文件 | Nginx需要轮转,MySQL仅备份 |
| 服务通知 | nginx -s reopen | 无 | Nginx需要重新打开日志文件 |
| 容器支持 | unginx容器 | 无 | Nginx在容器中运行 |
| 执行时间 | 凌晨3点 | 凌晨2点 | 错峰执行 |
| 日志目录 | /data/middleware/nginx/log | /data/middleware/mysql/log | 不同中间件目录 |
---
## 12. 里程碑
| 里程碑 | 目标 | 预计时间 | 状态 |
|--------|------|----------|------|
| M1 | v1.0 初始版本发布 | 2026-01-27 | ✅ 已完成 |
| M2 | v1.1 日志轮转功能 | 2026-03-XX | ✅ 已完成 |
| M3 | v1.2 优化完善版本 | 2026-03-30 | ✅ 已完成 |
| M4 | v1.3 功能增强版本 | 待定 | 🔲 计划中 |
| M5 | v1.4 远程备份版本 | 待定 | 🔲 计划中 |
| M6 | v1.5 日志分析版本 | 待定 | 🔲 计划中 |
---
## 13. 附录
### 13.1 文件路径
**脚本文件:**
- `自动化部署脚本/x86架构/新统一平台/定时脚本/backup_nginx_logs.sh`
**文档文件:**
- 需求文档:`Docs/PRD/自动化部署脚本/通用脚本/需求文档/_PRD_新统一平台_Nginx日志备份需求文档.md`
- 计划文档:`Docs/PRD/自动化部署脚本/通用脚本/需求文档/_PRD_新统一平台_Nginx日志备份需求文档_计划执行.md`
**输出文件:**
- 备份目录:`/data/middleware/nginx/log/backup/YYYYMMDD/`
- 日志文件:`/data/logs/backup_nginx_logs.log`
### 13.2 相关文档
- 代码规范:`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`
### 13.3 快速参考
**手动执行备份:**
```bash
cd /data/services/scripts
./backup_nginx_logs.sh
```
**查看备份日志:**
```bash
tail -f /data/logs/backup_nginx_logs.log
```
**检查备份文件:**
```bash
ls -la /data/middleware/nginx/log/backup/$(date +%Y%m%d)/
```
**验证日志轮转效果:**
```bash
# 检查原日志文件大小(应该较小)
ls -lh /data/middleware/nginx/log/access.log
# 检查备份文件
ls -lh /data/middleware/nginx/log/backup/$(date +%Y%m%d)/access.log_*.gz
```
**查看定时任务:**
```bash
crontab -l | grep backup_nginx_logs
```
**手动发送Nginx reopen信号:**
```bash
# 方式1:直接执行
nginx -s reopen
# 方式2:容器内执行
docker exec unginx nginx -s reopen
```
### 13.4 故障排查命令
```bash
# 检查Nginx是否正常运行
docker ps | grep unginx
# 或
ps aux | grep nginx
# 检查Nginx配置
docker exec unginx nginx -t
# 或
nginx -t
# 检查日志文件权限
ls -la /data/middleware/nginx/log/
# 检查磁盘空间
df -h /data/middleware/nginx/log/backup
# 测试Nginx日志写入
curl http://localhost > /dev/null 2>&1
tail -1 /data/middleware/nginx/log/access.log
```
### 13.5 联系方式
如有问题或建议,请联系:
- 技术负责人:[待填写]
- 运维负责人:[待填写]
---
**文档版本历史:**
| 版本 | 日期 | 变更内容 | 作者 |
|------|------|----------|------|
| V1.0 | 2026-04-10 | 初始版本,基于v1.2脚本创建计划执行文档 | Claude |
# _PRD_新统一平台Redis服务监控需求文档.md
> 版本:V1.2
> 更新日期:2026-03-30
> 适用范围:新统一平台Redis缓存服务监测与自愈
> 实现脚本:`自动化部署脚本/x86架构/新统一平台/定时脚本/monitor_redis_service.sh`
---
## 版本变更记录
| 版本 | 日期 | 变更内容 | 变更人 |
|------|------|----------|--------|
| V1.2 | 2026-03-30 | 新增日志自动轮转机制(5MB轮转、保留30天);新增PID文件锁机制防止并发执行;修正数据清理目录路径 | Claude |
| V1.1 | 2026-03-30 | 新增连续失败阈值判断机制,避免单次临时堵塞触发重启影响业务 | Claude |
| V1.0 | 2026-01-27 | 初始版本,定义Redis服务监控基础需求 | - |
### V1.1 详细变更说明
#### 新增功能
1. **连续失败阈值机制**
- 新增失败计数器,单次失败时仅累加计数,不立即重启
- 默认阈值为3次,连续失败达到阈值才触发容器重启
- 检查成功后自动重置失败计数器
2. **状态持久化**
- 新增状态文件 `STATE_FILE`,持久化保存失败次数
- 进程重启后计数器状态不丢失
3. **容器停止特殊处理**
- 容器停止属于严重故障,直接触发重启,不计入失败次数
#### 配置参数变更
| 新增参数 | 默认值 | 说明 |
|----------|--------|------|
| STATE_FILE | /var/log/scripts/monitor_redis_service.state | 失败计数器状态文件 |
| MAX_FAILURES | 3 | 触发重启的最大连续失败次数 |
#### 日志格式变更
- 日志中新增失败计数信息展示:`失败计数器更新: X -> Y (阈值: Z)`
- 新增阈值达到提示:`错误: 连续失败达到阈值(N次),触发容器重启`
#### 诊断命令变更
- 新增状态文件查看命令
- 新增失败计数变化趋势分析命令
---
---
## 1. 背景与目标
### 1.1 背景
Redis作为新统一平台的重要缓存服务,提供高速数据访问和会话存储功能。由于Redis可能配置密码认证,需要建立智能化的监控和恢复机制来应对不同认证场景。
### 1.2 目标
实现Redis服务的自动化定时监控功能,具备:
- 容器运行状态监测
- 智能认证模式识别(有密码/无密码)
- PING命令响应验证
- 异常时的自动重启恢复
- **连续失败阈值判断机制,避免单次临时堵塞触发重启**
- 失败次数记录与重置机制
- 数据目录清理重试机制
- 完整的操作日志记录
---
## 2. 总体范围
### 2.1 纳入监控对象
- **容器名称**`uredis`
- **监控维度**
- 容器运行状态(docker ps)
- Redis连接测试(redis-cli ping)
- 认证状态识别(NOAUTH/Authentication required)
- PING响应验证(期望返回PONG)
### 2.2 不在本期范围
- Redis内存使用率监控
- Key过期策略监控
- 持久化状态监控
- 集群模式监控
### 2.3 核心机制说明
**连续失败重启机制**:为避免因网络抖动、临时堵塞等瞬时故障导致的不必要重启,采用失败计数器机制:
- 单次检查失败时,仅记录失败次数,不立即重启
- 连续失败达到阈值(默认3次)时,才触发容器重启
- 检查成功后,自动重置失败计数器
- 通过状态文件持久化保存失败次数,避免计数器因进程重启丢失
---
## 3. 术语说明
- **认证模式识别**:自动检测Redis是否需要密码认证
- **数据清理重试**:重启失败时清理持久化数据目录后重试
- **渐进式恢复**:从简单重启到数据清理的逐步升级恢复策略
- **密码硬编码**:脚本中直接配置Redis访问密码
---
## 4. 功能需求
### 4.1 监控流程
#### 4.1.1 状态检查机制
按以下逻辑进行健康验证:
1. **读取失败计数器**
- 从状态文件读取当前连续失败次数
- 状态文件不存在时初始化为0
2. **容器运行检查**
- 使用`docker ps`检查uredis容器是否运行
- 容器未运行时**直接进入重启流程**(容器停止属于严重故障)
3. **无密码连接测试**
- 首先尝试无密码PING命令:`redis-cli ping`
- 成功返回PONG表示服务正常
- 失败时分析错误信息
4. **认证状态识别**
- 检查错误信息是否包含"NOAUTH"或"Authentication required"
- 确认为需要密码认证的情况
5. **密码认证测试**
- 使用预设密码执行PING命令
- 验证认证成功后的PING响应
- 确认服务真正可用
#### 4.1.2 失败处理机制(核心)
采用**连续失败阈值判断**机制,避免单次临时故障触发重启:
1. **单次失败处理**
- 任一检查环节失败时,失败计数器+1
- 将最新失败次数写入状态文件持久化保存
- 记录警告日志,说明当前失败次数和阈值
- **不触发重启,直接退出本次检查**
2. **连续失败达到阈值**
- 当失败次数 ≥ MAX_FAILURES(默认3次)时
- 清零失败计数器
- 触发容器重启流程
- 记录错误日志说明已连续失败N次
3. **检查成功处理**
- 所有检查项通过时
- 将失败计数器清零并更新状态文件
- 记录成功日志
- 正常退出本次检查
#### 4.1.3 异常处理流程
当检测到异常且达到失败阈值时执行:
1. **初次重启尝试**
- 停止可能挂起的容器实例
- 启动uredis容器
- 等待20秒让服务启动
- 再次检查容器运行状态
- 等待10秒后验证服务状态
2. **认证模式验证**
- 重新测试无密码连接
- 如需认证则使用预设密码测试
- 验证PING响应正确性
3. **数据清理重试**
- 初次重启失败时触发
- 清理可能的数据目录:
- `/var/www/java/redis/data`
- `/var/www/redis/data`
- 再次尝试启动容器
- 重复状态验证流程
4. **恢复确认**
- 所有检查项通过才算恢复成功
- 恢复成功后清零失败计数器
- 恢复失败不增加计数器,避免重复触发重启
### 4.2 认证处理机制
#### 4.2.1 密码配置
```bash
REDIS_PASSWORD="dNrprU&2S"
```
#### 4.2.2 认证命令
```bash
# 无密码模式
docker exec uredis redis-cli ping
# 有密码模式
docker exec uredis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning ping
```
#### 4.2.3 响应验证
- 期望响应:`PONG`
- 异常响应:记录具体错误信息
- 认证失败:区分密码错误和其他连接问题
### 4.3 数据清理策略
#### 4.3.1 清理触发条件
- 容器重启后仍无法正常启动
- 怀疑数据文件损坏导致启动失败
- 常规恢复手段无效时
#### 4.3.2 清理目标目录
```bash
# 检查并删除可能存在的数据目录
if [ -d "/data/middleware/redis/data" ]; then
rm -rf "/data/middleware/redis/data/"*
fi
```
#### 4.3.3 安全考虑
- 仅清理data子目录内容,不删除目录本身
- 清理前记录操作日志
- 清理后重新验证服务启动
### 4.4 日志与审计
#### 4.4.1 日志文件
- 主日志:`/data/logs/monitor_redis_service.log`
- 状态文件:`/data/logs/monitor_redis_service.state`
- PID锁文件:`/data/logs/.redis_monitor.pid`
#### 4.4.2 日志自动轮转机制
为避免日志文件无限增长占用磁盘空间,实现自动轮转机制:
1. **轮转触发条件**
- 当前日志文件大小达到 5MB
- 每次脚本执行时自动检查
2. **轮转执行动作**
- 将当前日志文件重命名为带时间戳的旧日志
- 创建新的空日志文件继续写入
- 记录轮转操作日志
3. **旧日志清理**
- 自动删除超过保留天数的旧日志文件(默认30天)
#### 4.4.3 并发控制机制(PID锁)
为防止定时任务重叠执行导致的问题,实现PID文件锁机制:
1. **锁文件检查**
- 脚本开始执行时检查PID文件是否存在
- 如果PID文件存在,读取其中的PID值
2. **进程存活判断**
- 使用 `kill -0 $PID` 检查该进程是否仍在运行
- 如果进程存在,记录警告日志并退出本次执行
- 如果进程不存在,清理旧PID文件并继续执行
3. **锁文件创建与释放**
- 将当前进程PID写入PID文件
- 使用 `trap` 命令设置退出时自动清理
- 捕获信号:EXIT INT TERM HUP
#### 4.4.2 日志级别和格式
每行必须包含:
- 时间戳:`YYYY-MM-DD HH:MM:SS`
- 级别标识:信息/警告/错误/成功
- 具体操作和结果状态
- **失败计数信息**(失败时显示当前失败次数)
示例:
```
2026-01-29 10:00:00 - 开始检查 Redis 服务状态...
2026-01-29 10:00:00 - 读取失败计数器: 当前失败次数 = 0
2026-01-29 10:00:01 - 检测到需要认证的 Redis 服务,正在尝试使用密码...
2026-01-29 10:00:02 - Redis 服务状态正常(已通过密码认证)
2026-01-29 10:00:02 - 检查成功,重置失败计数器为 0
2026-01-29 10:05:00 - 开始检查 Redis 服务状态...
2026-01-29 10:05:00 - 读取失败计数器: 当前失败次数 = 0
2026-01-29 10:05:01 - 警告: 无法连接到 Redis 服务
2026-01-29 10:05:01 - 失败计数器更新: 0 -> 1 (阈值: 3)
2026-01-29 10:10:00 - 开始检查 Redis 服务状态...
2026-01-29 10:10:00 - 读取失败计数器: 当前失败次数 = 1
2026-01-29 10:10:01 - 警告: 无法连接到 Redis 服务
2026-01-29 10:10:01 - 失败计数器更新: 1 -> 2 (阈值: 3)
2026-01-29 10:15:00 - 开始检查 Redis 服务状态...
2026-01-29 10:15:00 - 读取失败计数器: 当前失败次数 = 2
2026-01-29 10:15:01 - 警告: 无法连接到 Redis 服务
2026-01-29 10:15:01 - 失败计数器更新: 2 -> 3 (阈值: 3)
2026-01-29 10:15:02 - 错误: 连续失败达到阈值(3次),触发容器重启
2026-01-29 10:15:02 - 重置失败计数器为 0
2026-01-29 10:15:05 - Redis 未运行。正在尝试重启容器 'uredis'...
2026-01-29 10:15:25 - 成功: Redis 容器已成功启动。
2026-01-29 10:15:45 - 信息: 等待 10 秒后检查服务状态..........
2026-01-29 10:15:55 - 信息: Redis 服务状态正常(已通过密码认证),恢复成功
```
### 4.5 错误处理
#### 4.5.1 失败计数器异常
- 状态文件读取失败:记录警告,初始化计数器为0
- 状态文件写入失败:记录警告,但不影响重启决策
- 状态文件权限错误:记录错误并建议检查文件权限
- 计数器值异常(非数字):记录警告,重置为0
#### 4.5.2 容器状态异常
- 容器不存在:记录严重错误并建议手动创建
- 容器启动失败:记录错误详情和可能原因
- 容器启动后立即停止:记录错误并建议检查日志
- **容器停止时**:直接触发重启,不计入失败次数
#### 4.5.3 认证状态异常
- 无密码连接失败但不是认证问题:记录具体错误,失败计数器+1
- 密码认证失败:记录认证错误信息,失败计数器+1
- PING响应异常:记录实际响应内容,失败计数器+1
#### 4.5.4 恢复过程异常
- 重启后容器仍不运行:记录失败并建议手动干预
- 数据清理后仍无法启动:记录严重错误
- 多次重试均失败:建议深入排查根本原因
- **恢复失败不增加计数器**:避免重复触发重启
---
## 5. 配置参数
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| CONTAINER_NAME | uredis | Redis容器名称 |
| REDIS_PASSWORD | dNrprU&2S | Redis访问密码 |
| LOG_FILE | /data/logs/monitor_redis_service.log | 日志文件路径 |
| STATE_FILE | /data/logs/monitor_redis_service.state | 失败计数器状态文件 |
| PID_FILE | /data/logs/.redis_monitor.pid | 进程锁文件,防止并发执行 |
| MAX_LOG_SIZE | 5MB | 日志文件大小限制,超过后自动轮转 |
| LOG_RETENTION_DAYS | 30天 | 轮转后的日志文件保留天数 |
| MAX_FAILURES | 3 | 触发重启的最大连续失败次数 |
| STARTUP_WAIT | 20秒 | 容器启动等待时间 |
| STATUS_CHECK_WAIT | 10秒 | 状态验证等待时间 |
| Redis_Data_Dir | /data/middleware/redis/data | Redis数据目录 |
---
## 6. 执行要求
### 6.1 执行时机
- 建议:每5分钟执行一次
- cron配置:`*/5 * * * * /data/services/scripts/monitor_redis_service.sh`
### 6.2 执行环境
- 需要docker命令权限
- uredis容器必须存在
- 需要redis-cli命令支持
### 6.3 资源要求
- 内存:监控过程占用少量内存
- CPU:状态检查操作轻量级
- 网络:仅本地容器通信
- 磁盘:数据清理时会删除旧数据文件
---
## 7. 验收标准
1. **监控智能性**
- 能正确识别有密码/无密码认证模式
- 准确执行对应的连接测试
- 智能选择合适的恢复策略
2. **失败计数机制**
- 单次失败时正确累加计数器
- 失败计数能持久化保存,进程重启不丢失
- 检查成功时正确重置计数器为0
- 未达阈值时不会触发重启
- 达到阈值时正确触发重启并清零计数器
- 容器停止时直接重启,不计入失败次数
3. **恢复有效性**
- 连续失败达到阈值后能正确触发重启
- 重启操作能成功执行
- 数据清理机制能解决启动问题
- 恢复后服务状态确实正常
4. **日志完整性**
- 每次检查都有完整的开始和结束记录
- 日志中包含当前失败次数和阈值信息
- 认证模式识别过程详细记录
- 异常情况有详细的诊断信息
- 数据清理操作明确记录
5. **安全性**
- 密码在脚本中合理配置
- 数据清理操作安全可控
- 不会对正常运行的服务产生副作用
---
## 8. 故障排查
### 8.1 常见问题
1. **容器不存在**
```
错误: 容器 'uredis' 不存在!
```
解决:重新创建uredis容器
2. **认证模式识别错误**:
```
警告: 需要认证,但无法使用预设密码连接到 Redis
失败计数器更新: 0 -> 1 (阈值: 3)
```
解决:检查Redis密码配置是否正确
3. **连接测试失败(未达阈值)**:
```
警告: 无法连接到 Redis 服务
失败计数器更新: 0 -> 1 (阈值: 3)
```
说明:这是正常现象,系统在等待下次检查确认是否为持续故障
4. **连接测试失败(达到阈值)**:
```
错误: 连续失败达到阈值(3次),触发容器重启
```
说明:已连续3次检查失败,系统正在执行自动恢复
5. **数据清理触发**:
```
信息: 尝试清理数据目录并重新启动 Redis 容器...
```
解决:这表示常规重启失败,脚本自动尝试清理数据
6. **持续启动失败**:
```
错误: 即使清理了数据目录,仍然无法启动 Redis 容器。
```
解决:需要手动检查容器配置和系统资源
7. **状态文件异常**:
```
警告: 无法读取状态文件,初始化失败计数器为 0
```
说明:首次运行或状态文件被删除,属于正常情况
### 8.2 诊断命令
```bash
# 检查容器状态
docker ps | grep uredis
# 查看当前失败计数器
cat /data/logs/monitor_redis_service.state
# 手动重置失败计数器(恢复后无需手动操作,脚本会自动处理)
echo "0" > /data/logs/monitor_redis_service.state
# 手动无密码测试
docker exec uredis redis-cli ping
# 手动密码测试
docker exec uredis redis-cli -a "dNrprU&2S" --no-auth-warning ping
# 查看容器日志
docker logs uredis --tail 50
# 检查数据目录
ls -la /data/middleware/redis/data/
# 手动重启测试
docker restart uredis
```
### 8.3 日志分析
```bash
# 实时监控脚本执行
tail -f /data/logs/monitor_redis_service.log
# 统计异常发生频率
grep "警告\|错误" /data/logs/monitor_redis_service.log | wc -l
# 查看失败计数变化趋势
grep "失败计数器更新" /data/logs/monitor_redis_service.log
# 统计触发重启的次数
grep "连续失败达到阈值" /data/logs/monitor_redis_service.log | wc -l
# 统计认证模式使用情况
grep "检测到需要认证" /data/logs/monitor_redis_service.log | wc -l
grep "无密码情况下能 ping 通" /data/logs/monitor_redis_service.log | wc -l
# 查看数据清理记录
grep "清理.*data 目录" /data/logs/monitor_redis_service.log
# 分析重启成功率
grep "Redis 容器已成功启动" /data/logs/monitor_redis_service.log | wc -l
grep "仍然无法启动 Redis 容器" /data/logs/monitor_redis_service.log | wc -l
# 分析连接问题
grep "无法连接到 Redis" /data/logs/monitor_redis_service.log
# 查看失败次数达到阈值前的情况
grep -B 2 "连续失败达到阈值" /data/logs/monitor_redis_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
# 新统一平台Redis服务监控 - 计划执行文档
> 版本:V1.2
> 创建日期:2026-04-10
> 需求文档:`_PRD_新统一平台_Redis服务监控需求文档.md`
> 代码路径:`自动化部署脚本/x86架构/新统一平台/定时脚本/monitor_redis_service.sh`
---
## 1. 执行概述
### 1.1 项目背景
Redis作为新统一平台的核心缓存服务,需要建立7x24小时的自动化监控机制,及时发现服务异常并自动恢复,确保业务连续性。
### 1.2 执行目标
实现Redis服务的智能化监控与自愈脚本,具备:
- 容器运行状态监测
- 智能认证模式识别(有密码/无密码)
- 连续失败阈值判断机制(避免误触发)
- 自动恢复与数据清理重试
- 日志自动轮转(5MB/30天)
- 并发执行控制(PID文件锁)
### 1.3 执行范围
- [x] 脚本基础框架搭建
- [x] 容器状态监测功能
- [x] 智能认证检测功能
- [x] 连续失败阈值机制
- [x] 自动重启恢复功能
- [x] 数据清理重试功能
- [x] 日志自动轮转功能
- [x] PID文件锁机制
- [x] 代码问题修复($Redis_Data_Dir重复代码和引号问题)
---
## 2. 任务分解与实施计划
### 2.1 任务分解
| 任务编号 | 任务名称 | 优先级 | 预计工作量 | 状态 |
| --- | --- | --- | --- | --- |
| T1 | 脚本基础框架搭建 | 高 | 30分钟 | [x] |
| T2 | 容器状态监测功能实现 | 高 | 30分钟 | [x] |
| T3 | 智能认证检测功能实现 | 高 | 45分钟 | [x] |
| T4 | 连续失败阈值机制实现 | 高 | 40分钟 | [x] |
| T5 | 自动重启恢复功能实现 | 高 | 60分钟 | [x] |
| T6 | 数据清理重试功能实现 | 中 | 30分钟 | [x] |
| T7 | 日志自动轮转功能实现 | 中 | 20分钟 | [x] |
| T8 | PID文件锁机制实现 | 中 | 25分钟 | [x] |
| T9 | 代码问题修复 | 高 | 10分钟 | [x] |
| T10 | 需求文档同步更新 | 高 | 30分钟 | [x] |
### 2.2 实施计划
#### T1: 脚本基础框架搭建
**文件位置**`自动化部署脚本/x86架构/新统一平台/定时脚本/monitor_redis_service.sh`
**实现内容**
```bash
#!/bin/bash
#===============================================================================
# 脚本名称:monitor_redis_service.sh
# 功能描述:Redis服务监测与自愈脚本
# 版本:V1.2
#===============================================================================
# 配置参数
LOG_FILE="/data/logs/monitor_redis_service.log"
MAX_LOG_SIZE=$((5*1024*1024))
LOG_RETENTION_DAYS=30
PID_FILE="/data/logs/.redis_monitor.pid"
Redis_Data_Dir="/data/middleware/redis/data"
STATE_FILE="/data/logs/monitor_redis_service.state"
MAX_FAILURES=3
REDIS_PASSWORD="dNrprU&2S"
```
#### T2: 容器状态监测功能实现
**函数名**`check_redis`
**实现要点**
- 使用 `docker ps` 检查容器运行状态
- 优先尝试无密码连接
- 根据错误信息识别是否需要认证
- 有密码时使用预设密码测试
**核心逻辑**
```bash
check_redis() {
# 检查容器是否运行
if docker ps --format '{{.Names}}' | grep -Fxq "uredis"; then
# 尝试无密码连接
if docker exec uredis redis-cli ping >/dev/null 2>&1; then
return 0
fi
# 检查是否需要认证
auth_output=$(docker exec uredis redis-cli ping 2>&1)
if [[ "$auth_output" == *"NOAUTH"* ]] || [[ "$auth_output" == *"Authentication required"* ]]; then
# 使用密码认证
if docker exec uredis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning ping | grep -q "PONG"; then
return 0
fi
fi
return 1
fi
return 1
}
```
#### T3: 智能认证检测功能实现
**实现要点**
- 检测错误信息中的 NOAUTH 关键字
- 检测 Authentication required 关键字
- 自动切换认证模式
- 验证PONG响应
#### T4: 连续失败阈值机制实现
**函数名**`read_state_file``write_state_file`
**实现要点**
```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
}
```
**主流程逻辑**
```bash
# 读取当前失败次数
failure_count=$(read_state_file)
# 检查Redis服务
if check_redis; then
# 检查成功,清零计数器
if [ "$failure_count" -gt 0 ]; then
write_state_file 0
log "检查成功,重置失败计数器为 0"
fi
else
# 检查失败,累加计数器
failure_count=$((failure_count + 1))
write_state_file "$failure_count"
# 判断是否达到阈值
if [ "$failure_count" -ge "$MAX_FAILURES" ]; then
log "错误: 连续失败达到阈值($MAX_FAILURES次),触发容器重启"
write_state_file 0
restart_redis_container
fi
fi
```
#### T5: 自动重启恢复功能实现
**函数名**`restart_redis_container`
**实现流程**
1. 检查容器是否存在
2. 停止可能挂起的容器
3. 启动容器
4. 等待20秒让服务启动
5. 检查容器运行状态
6. 等待10秒后验证服务
7. 验证认证模式和服务响应
**核心代码**
```bash
restart_redis_container() {
# 检查容器是否存在
if docker ps -a --format '{{.Names}}' | grep -Fxq "uredis"; then
# 停止容器
docker stop uredis >/dev/null 2>&1 || true
# 启动容器
if docker start uredis; then
# 等待服务启动
sleep 20
# 验证服务状态
# ...
else
# 启动失败,尝试数据清理
# ...
fi
fi
}
```
#### T6: 数据清理重试功能实现
**实现要点**
- 初次重启失败时触发
- 清理 Redis 数据目录内容
- 使用 `${Redis_Data_Dir:?}/`* 安全语法
- 清理后再次尝试启动
**实现代码**
```bash
# 清理数据目录
if [ -d "$Redis_Data_Dir" ]; then
log "信息: 清理 $Redis_Data_Dir 目录..."
rm -rf "${Redis_Data_Dir:?}/"*
fi
# 再次尝试启动
docker start uredis
```
#### T7: 日志自动轮转功能实现
**函数名**`rotate_logs`
**实现要点**
```bash
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 "monitor_redis_service.log.*" -mtime +$LOG_RETENTION_DAYS -exec rm -f {} \; 2>/dev/null
}
```
#### T8: PID文件锁机制实现
**函数名**`acquire_lock`
**实现要点**
```bash
acquire_lock() {
# 检查 PID 文件是否存在
if [ -f "$PID_FILE" ]; then
local old_pid=$(cat "$PID_FILE" 2>/dev/null)
# 检查该进程是否还在运行
if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then
log "警告: 上一次脚本执行仍在运行 (PID: $old_pid),本次跳过执行"
exit 1
else
# 进程不存在,清理旧的 PID 文件
rm -f "$PID_FILE"
fi
fi
# 确保 PID 文件目录存在
mkdir -p "$(dirname "$PID_FILE")" 2>/dev/null || true
# 写入当前进程 PID
echo $$ > "$PID_FILE"
# 设置退出时清理 PID 文件
trap 'rm -f "$PID_FILE"; exit' EXIT INT TERM HUP
}
```
#### T9: 代码问题修复
**问题描述**
1. 第242-250行存在重复代码
2. `rm -rf $Redis_Data_Dir/*` 缺少引号保护
**修复方案**
```bash
# 修复前(重复代码)
if [ -d "$Redis_Data_Dir" ]; then
log "信息: 清理 $Redis_Data_Dir 目录..."
rm -rf $Redis_Data_Dir/*
fi
if [ -d "$Redis_Data_Dir" ]; then
log "信息: 清理 $Redis_Data_Dir 目录..."
rm -rf $Redis_Data_Dir/*
fi
# 修复后(删除重复,加引号保护)
if [ -d "$Redis_Data_Dir" ]; then
log "信息: 清理 $Redis_Data_Dir 目录..."
rm -rf "${Redis_Data_Dir:?}/"*
fi
```
**修复说明**
- 删除重复的if块
- 使用 `"${Redis_Data_Dir:?}/"`* 语法,防止变量为空时删除根目录
- `:?` 语法会在变量为空或未设置时报错并退出
#### T10: 需求文档同步更新
**更新内容**
1. 文档标题:预定系统 → 新统一平台
2. 版本号:V1.1 → V1.2
3. 路径更新:
- 日志路径:`/var/log/scripts/``/data/logs/`
- 数据目录:更新为 `/data/middleware/redis/data`
- 脚本路径:预定系统 → 新统一平台
4. 配置参数:新增 `Redis_Data_Dir`
5. 诊断命令:更新所有路径
---
## 3. 关键函数设计
### 3.1 check_redis 函数
**功能**:检查Redis服务状态
**返回值**
- 0 = 服务正常
- 1 = 服务异常
**实现逻辑**
```
1. 检查容器是否运行
↓ 不运行
返回失败
↓ 运行
2. 尝试无密码PING
↓ 成功返回PONG
返回成功
↓ 失败
3. 检查是否需要认证
↓ NOAUTH/Authentication required
4. 使用密码PING
↓ 成功返回PONG
返回成功
↓ 失败
返回失败
```
### 3.2 restart_redis_container 函数
**功能**:重启Redis容器并验证服务恢复
**返回值**
- 0 = 重启成功且服务正常
- 1 = 重启失败
**实现逻辑**
```
1. 检查容器是否存在
↓ 不存在
返回失败
↓ 存在
2. 停止容器
3. 启动容器
↓ 启动失败
4. 清理数据目录
5. 再次启动容器
↓ 启动成功
6. 等待20秒
7. 检查容器运行状态
8. 等待10秒
9. 验证服务状态(有密码/无密码)
↓ 成功
返回成功
↓ 失败
返回失败
```
### 3.3 acquire_lock 函数
**功能**:获取PID文件锁,防止并发执行
**实现逻辑**
```
1. 检查PID文件是否存在
↓ 不存在
跳到步骤4
↓ 存在
2. 读取PID值
3. 检查进程是否运行
↓ 运行中
记录警告并退出
↓ 不运行
清理旧PID文件
4. 创建PID文件目录(如不存在)
5. 写入当前进程PID
6. 设置trap退出时清理
```
---
## 4. 配置参数说明
| 参数名 | 默认值 | 说明 |
| --- | --- | --- |
| LOG_FILE | /data/logs/monitor_redis_service.log | 脚本日志文件路径 |
| MAX_LOG_SIZE | 5242880 (5MB) | 日志文件大小限制 |
| LOG_RETENTION_DAYS | 30 | 日志保留天数 |
| PID_FILE | /data/logs/.redis_monitor.pid | PID锁文件路径 |
| Redis_Data_Dir | /data/middleware/redis/data | Redis数据目录 |
| STATE_FILE | /data/logs/monitor_redis_service.state | 失败计数器状态文件 |
| MAX_FAILURES | 3 | 触发重启的最大连续失败次数 |
| REDIS_PASSWORD | dNrprU&2S | Redis访问密码 |
---
## 5. 主流程设计
```
脚本开始
获取锁(防止并发)
↓ 失败
记录警告并退出
↓ 成功
执行日志轮转
读取当前失败次数
检查Redis服务状态
↓ 成功
清零失败计数器(如需要)
记录成功日志
↓ 失败
失败计数器+1
判断是否达到阈值
↓ 未达到
记录警告日志
退出
↓ 达到
清零失败计数器
触发容器重启
↓ 成功
验证服务恢复
↓ 恢复成功
记录成功日志
↓ 恢复失败
记录错误日志
↓ 失败
清理数据目录
重启容器
↓ 成功
验证服务恢复
↓ 失败
记录严重错误
脚本结束
```
---
## 6. 验收标准
### 6.1 功能验收
- [x] 能正确识别有密码/无密码认证模式
- [x] 单次失败时正确累加计数器,不触发重启
- [x] 连续失败达到阈值(3次)时正确触发重启
- [x] 检查成功时正确重置计数器为0
- [x] 重启后能正确验证服务状态
- [x] 数据清理机制能解决启动问题
- [x] 日志文件达到5MB时自动轮转
- [x] 轮转后的日志保留30天后自动清理
- [x] PID文件锁能防止并发执行
### 6.2 代码规范验收
- [x] 所有函数有中文注释说明
- [x] 配置参数有中文说明
- [x] 关键逻辑步骤有中文注释
- [x] 日志格式统一
- [x] 变量使用双引号保护
- [x] 危险操作使用 `${var:?}` 语法
### 6.3 安全性验收
- [x] 数据清理使用安全语法
- [x] 密码不在日志中明文显示
- [x] PID文件正确释放
- [x] 异常退出时清理资源
---
## 7. 测试计划
### 7.1 单元测试场景
| 测试场景 | 预期结果 |
| --- | --- |
| Redis服务正常(无密码) | 检查成功,计数器清零 |
| Redis服务正常(有密码) | 检查成功,计数器清零 |
| Redis服务停止 | 容器停止直接触发重启 |
| 第1次检查失败 | 计数器=1,不触发重启 |
| 第2次检查失败 | 计数器=2,不触发重启 |
| 第3次检查失败 | 计数器=3,触发重启 |
| 重启后服务恢复 | 检查成功,计数器清零 |
| 重启失败后清理数据 | 清理数据目录,再次重启 |
| 日志文件超过5MB | 自动轮转日志文件 |
| 并发执行脚本 | 第二个实例直接退出 |
### 7.2 集成测试场景
| 测试场景 | 预期结果 |
| --- | --- |
| Redis容器不存在 | 记录错误并建议手动创建 |
| 密码配置错误 | 连续3次失败后触发重启 |
| 网络临时抖动 | 未达阈值不触发重启 |
| 数据文件损坏 | 清理后能成功启动 |
| 定时任务频繁执行 | PID锁防止并发 |
---
## 8. 实施记录
### 8.1 实施进度
| 日期 | 完成任务 | 负责人 | 备注 |
| --- | --- | --- | --- |
| 2026-01-27 | 初始版本开发(V1.0) | - | 基础监控功能 |
| 2026-03-30 | 新增连续失败阈值机制(V1.1) | Claude | 避免误触发 |
| 2026-03-30 | 新增日志轮转和PID锁(V1.2) | Claude | 完善稳定性 |
| 2026-04-10 | 修复代码问题,更新需求文档 | Claude | 修复$Redis_Data_Dir问题 |
### 8.2 变更记录
| 日期 | 变更内容 | 变更原因 |
| --- | --- | --- |
| 2026-04-10 | 修复$Redis_Data_Dir重复代码和引号问题 | 代码质量优化 |
| 2026-04-10 | 更新需求文档路径为实际部署路径 | 文档同步 |
---
## 9. 风险评估
| 风险项 | 风险等级 | 应对措施 |
| --- | --- | --- |
| 数据清理导致数据丢失 | 中 | 仅在重启失败后触发,且只清理data子目录内容 |
| 密码泄露 | 低 | 密码硬编码在脚本中,注意文件权限 |
| 误触发重启 | 低 | 连续失败阈值机制,避免单次故障触发 |
| 日志文件过大 | 低 | 5MB自动轮转,30天自动清理 |
| 并发执行冲突 | 低 | PID文件锁机制防止并发 |
---
## 10. 后续工作
- [ ] 监控脚本运行情况
- [ ] 根据实际运行情况调整失败阈值
- [ ] 考虑将密码配置移至外部配置文件
- [ ] 增加钉钉/邮件告警通知
- [ ] 增加Redis性能指标监控
---
## 11. 附录
### 11.1 相关文档
- 需求文档:`_PRD_新统一平台_Redis服务监控需求文档.md`
- 代码规范:`_PRD_规范文档_代码规范.md`
- 测试规范:`_PRD_规范文档_测试规范.md`
### 11.2 部署信息
| 项目 | 值 |
| --- | --- |
| 脚本路径 | `/data/services/scripts/monitor_redis_service.sh` |
| 日志路径 | `/data/logs/monitor_redis_service.log` |
| 状态文件 | `/data/logs/monitor_redis_service.state` |
| PID文件 | `/data/logs/.redis_monitor.pid` |
| 定时任务 | `*/5 * * * * /data/services/scripts/monitor_redis_service.sh` |
| 容器名称 | `uredis` |
| 数据目录 | `/data/middleware/redis/data` |
### 11.3 快速诊断命令
```bash
# 查看实时日志
tail -f /data/logs/monitor_redis_service.log
# 查看失败计数器
cat /data/logs/monitor_redis_service.state
# 检查容器状态
docker ps | grep uredis
# 手动测试Redis连接
docker exec uredis redis-cli ping
docker exec uredis redis-cli -a "dNrprU&2S" --no-auth-warning ping
# 查看容器日志
docker logs uredis --tail 50
```
---
**文档状态**:已完成
**最后更新**:2026-04-10
#!/bin/bash
#===============================================================================
# 脚本名称:backup_nginx_logs.sh
# 功能描述:Nginx日志文件定时备份与压缩脚本
# 版本:V1.2
# 创建日期:2026-01-27
# 更新日期:2026-03-30
# 基于文档:_PRD_新统一平台_Nginx日志备份需求文档.md
#
# 备份对象:
# 1. Nginx访问日志(access.log)
# 2. Nginx错误日志(error.log)
# 3. 自动压缩并清空原日志文件
# 4. 向Nginx发送reopen信号重新打开日志
# 5. 自动清理过期备份
# 6. 日志文件自动轮转(5MB轮转、保留30天)
#
# 使用方法:
# chmod +x backup_nginx_logs.sh
# ./backup_nginx_logs.sh
#
# 定时任务示例:
# 0 3 * * * /data/services/scripts/backup_nginx_logs.sh
#===============================================================================
# ==================== 配置区 ====================
NGINX_LOG_DIR="/data/middleware/nginx/log" # Nginx日志目录
BACKUP_DIR="$NGINX_LOG_DIR/backup" # 备份目录
LOG_FILE="/data/logs/backup_nginx_logs.log" # 日志文件路径
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" | 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
}
# ==================== 权限保存和恢复函数 ====================
save_permissions() {
local file="$1"
# 获取文件权限和属主信息
local perms owner group
perms=$(stat -c %a "$file" 2>/dev/null)
owner=$(stat -c %U "$file" 2>/dev/null)
group=$(stat -c %G "$file" 2>/dev/null)
# 存储到临时文件
echo "$perms $owner $group" > "$file.permissions.tmp"
}
restore_permissions() {
local file="$1"
local perm_file="$file.permissions.tmp"
if [ -f "$perm_file" ]; then
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"
fi
}
# ==================== 主要功能 ====================
# 创建日志目录并确保存在
mkdir -p "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"
# 执行日志轮转
rotate_logs
log "===== 开始备份Nginx日志 (日期: $DATE) ====="
# 创建备份目录
mkdir -p "$TODAY_DIR"
# 检查Nginx日志目录是否存在
if [ ! -d "$NGINX_LOG_DIR" ]; then
log "❌ Nginx日志目录不存在: $NGINX_LOG_DIR"
exit 1
fi
# 进入日志目录
cd "$NGINX_LOG_DIR" || {
log "❌ 无法进入目录: $NGINX_LOG_DIR"
exit 1
}
# 查找所有日志文件(access.log 和 error.log)
LOG_FILES=""
if [ -f "access.log" ]; then
LOG_FILES="$LOG_FILES access.log"
fi
if [ -f "error.log" ]; then
LOG_FILES="$LOG_FILES error.log"
fi
if [ -z "$LOG_FILES" ]; then
log "⚠️ 在 $NGINX_LOG_DIR 中未找到Nginx日志文件"
exit 0
fi
# 备份并压缩每个日志文件
SUCCESS_COUNT=0
for log_file in $LOG_FILES; do
source_path="$NGINX_LOG_DIR/$log_file"
# 跳过已经备份过的文件(如果同名备份已存在)
if [ -f "$TODAY_DIR/${log_file}_${DATE}.gz" ]; then
log "⚠️ 备份文件已存在,跳过: $log_file"
continue
fi
log "开始备份日志文件: $log_file"
# 保存原始权限信息
save_permissions "$source_path"
# 复制文件到备份目录并压缩
if gzip -c "$source_path" > "$TODAY_DIR/${log_file}_${DATE}.gz"; then
log "✅ 日志备份并压缩成功: $log_file -> ${log_file}_${DATE}.gz"
((SUCCESS_COUNT++))
# 清空原始日志文件内容,但保持文件存在
> "$source_path"
log "✅ 原始日志文件已清空: $log_file"
else
log "❌ 日志备份失败: $log_file"
# 如果备份失败,仍需要恢复权限信息
restore_permissions "$source_path"
fi
# 恢复原始文件权限
restore_permissions "$source_path"
done
log "本次共成功备份 $SUCCESS_COUNT 个日志文件"
# ==================== 清理超过30天的旧备份 ====================
log "开始清理超过 $RETENTION_DAYS 天的旧备份..."
find "$BACKUP_DIR" -maxdepth 1 -type d -name "????????" -mtime +$RETENTION_DAYS -exec rm -rf {} + 2>/dev/null
# 清理权限临时文件(以防万一)
find "$NGINX_LOG_DIR" -name "*.permissions.tmp" -type f -delete 2>/dev/null
# 发送HUP信号给nginx进程,使其重新打开日志文件
if command -v nginx &> /dev/null; then
nginx -s reopen 2>/dev/null || {
# 如果直接执行失败,尝试通过docker向unginx容器发送信号
docker exec unginx nginx -s reopen 2>/dev/null || log "⚠️ 无法向Nginx发送reopen信号"
}
elif docker ps --format '{{.Names}}' | grep -q "unginx"; then
# 如果nginx命令不存在,但容器存在,则尝试在容器内执行
docker exec unginx nginx -s reopen 2>/dev/null || log "⚠️ 无法向Nginx发送reopen信号"
fi
log "===== Nginx日志备份任务结束 ====="
\ No newline at end of file
#!/bin/bash
#===============================================================================
# 脚本名称:monitor_redis_service.sh
# 功能描述:Redis服务监测与自愈脚本
# 版本:V1.2
# 创建日期:2026-01-27
# 更新日期:2026-03-30
# 基于文档:_PRD_新通用平台_Redis服务监控需求文档.md (V1.1)
#
# 监测对象:
# 1. uredis容器运行状态
# 2. Redis服务连接可用性
# 3. 认证状态检查(支持有密码/无密码)
# 4. PING命令响应验证
#
# 恢复策略:
# 1. 连续失败阈值判断(默认3次)
# 2. 检查容器是否运行
# 3. 测试无密码PING连接
# 4. 如需认证则使用预设密码测试
# 5. 异常时自动重启容器
# 6. 重启失败时清理数据目录重试
# 7. 重启后验证服务恢复
#
# 使用方法:
# chmod +x monitor_redis_service.sh
# ./monitor_redis_service.sh
#
# 定时任务示例:
# */5 * * * * /data/services/scripts/monitor_redis_service.sh
#===============================================================================
# 宿主机上的脚本:检查 Redis,如果容器未运行则重启 uredis 容器
LOG_FILE="/data/logs/monitor_redis_service.log"
MAX_LOG_SIZE=$((5*1024*1024)) # 5MB 日志大小限制
LOG_RETENTION_DAYS=30 # 日志保留天数
PID_FILE="/data/logs/.redis_monitor.pid"
# redis的数据目录
Redis_Data_Dir="/data/middleware/redis/data"
# 状态文件配置
STATE_FILE="/data/logs/monitor_redis_service.state"
MAX_FAILURES=3
# 直接在脚本中定义 Redis 密码
REDIS_PASSWORD="dNrprU&2S"
#===============================================================================
# 函数定义
#===============================================================================
# 获取锁函数(防止并发执行)
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_redis_service.log.*" -mtime +$LOG_RETENTION_DAYS -exec rm -f {} \; 2>/dev/null
}
# 日志记录函数
log() {
local message
message="$(date '+%Y-%m-%d %H:%M:%S') - $1"
echo "$message"
# 同时写入日志文件
echo "$message" >> "$LOG_FILE"
}
# 读取状态文件
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
}
# 检查Redis服务状态
check_redis() {
# 检查 uredis 容器是否正在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uredis"; then
# 首先尝试不使用密码的 ping 命令
if docker exec uredis redis-cli ping >/dev/null 2>&1; then
# 无密码情况下能 ping 通
return 0
else
# 检查是否是认证问题
auth_output=$(docker exec uredis redis-cli ping 2>&1)
if [[ "$auth_output" == *"NOAUTH"* ]] || [[ "$auth_output" == *"Authentication required"* ]]; then
# 使用硬编码的密码进行认证测试
if docker exec uredis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning ping >/dev/null 2>&1; then
ping_output=$(docker exec uredis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning ping 2>&1)
if [ "$ping_output" = "PONG" ]; then
return 0
else
log "警告: 使用密码认证成功,但 ping 返回意外状态: $ping_output"
return 1
fi
else
log "警告: 需要认证,但无法使用预设密码连接到 Redis"
return 1
fi
else
# 不是认证问题,可能是其他错误
log "警告: Redis 连接失败,错误信息: $auth_output"
return 1
fi
fi
else
log "信息: uredis 容器未运行"
return 1
fi
}
# 重启Redis容器
restart_redis_container() {
log "Redis 未运行。正在尝试重启容器 'uredis'..."
# 检查容器是否存在(不仅仅是运行状态)
if docker ps -a --format '{{.Names}}' | grep -Fxq "uredis"; then
# 停止可能挂起的容器
docker stop uredis >/dev/null 2>&1 || true
# 容器存在但未运行,尝试启动
if docker start uredis; then
log "成功: Redis 容器已成功启动。"
# 等待几秒让服务启动
log "信息: 等待 20 秒让 Redis 服务完全启动..."
for i in {1..20}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uredis"; then
log "信息: Redis 容器现在正在运行。"
# 等待一段时间后再次检查服务状态
log "信息: 等待 10 秒后检查服务状态..."
sleep 10
# 再次检查是否需要认证
if docker exec uredis redis-cli ping >/dev/null 2>&1; then
# 不需要认证
if docker exec uredis redis-cli ping >/dev/null 2>&1; then
ping_output=$(docker exec uredis redis-cli ping 2>&1)
if [ "$ping_output" = "PONG" ]; then
log "信息: Redis 服务状态正常。"
return 0
else
log "错误: Redis 服务状态异常: $ping_output"
return 1
fi
else
log "错误: Redis 服务状态检查失败。"
return 1
fi
else
# 需要认证,尝试使用密码
auth_output=$(docker exec uredis redis-cli ping 2>&1)
if [[ "$auth_output" == *"NOAUTH"* ]] || [[ "$auth_output" == *"Authentication required"* ]]; then
# 使用硬编码的密码进行认证测试
if docker exec uredis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning ping >/dev/null 2>&1; then
ping_output=$(docker exec uredis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning ping 2>&1)
if [ "$ping_output" = "PONG" ]; then
log "信息: Redis 服务状态正常(已通过密码认证)。"
return 0
else
log "错误: Redis 服务状态异常: $ping_output"
return 1
fi
else
log "错误: Redis 需要认证,但无法使用预设密码连接到 Redis。"
return 1
fi
else
log "错误: Redis 服务状态检查失败。"
return 1
fi
fi
else
log "错误: Redis 容器在启动后不久就停止了。"
return 1
fi
else
log "错误: 无法启动 Redis 容器。"
# 尝试清理数据目录并重启
log "信息: 尝试清理数据目录并重新启动 Redis 容器..."
# 检查并删除可能存在的数据目录
if [ -d "$Redis_Data_Dir" ]; then
log "信息: 清理 $Redis_Data_Dir 目录..."
rm -rf "${Redis_Data_Dir:?}/"*
fi
# 再次尝试启动容器
log "信息: 再次尝试启动 Redis 容器..."
if docker start uredis; then
log "成功: Redis 容器在清理数据后已成功启动。"
# 等待几秒让服务启动
log "信息: 等待 20 秒让 Redis 服务完全启动..."
for i in {1..20}; do
echo -n "." >> "$LOG_FILE"
sleep 1
done
echo "" >> "$LOG_FILE"
# 检查启动后容器是否仍在运行
if docker ps --format '{{.Names}}' | grep -Fxq "uredis"; then
log "信息: Redis 容器现在正在运行。"
# 等待一段时间后再次检查服务状态
log "信息: 等待 10 秒后检查服务状态..."
sleep 10
# 再次检查是否需要认证
if docker exec uredis redis-cli ping >/dev/null 2>&1; then
# 不需要认证
if docker exec uredis redis-cli ping >/dev/null 2>&1; then
ping_output=$(docker exec uredis redis-cli ping 2>&1)
if [ "$ping_output" = "PONG" ]; then
log "信息: Redis 服务状态正常。"
return 0
else
log "错误: Redis 服务状态异常: $ping_output"
return 1
fi
else
log "错误: Redis 服务状态检查失败。"
return 1
fi
else
# 需要认证,尝试使用密码
auth_output=$(docker exec uredis redis-cli ping 2>&1)
if [[ "$auth_output" == *"NOAUTH"* ]] || [[ "$auth_output" == *"Authentication required"* ]]; then
# 使用硬编码的密码进行认证测试
if docker exec uredis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning ping >/dev/null 2>&1; then
ping_output=$(docker exec uredis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning ping 2>&1)
if [ "$ping_output" = "PONG" ]; then
log "信息: Redis 服务状态正常(已通过密码认证)。"
return 0
else
log "错误: Redis 服务状态异常: $ping_output"
return 1
fi
else
log "错误: Redis 需要认证,但无法使用预设密码连接到 Redis。"
return 1
fi
else
log "错误: Redis 服务状态检查失败。"
return 1
fi
fi
else
log "错误: Redis 容器在启动后不久就停止了。"
return 1
fi
else
log "错误: 即使清理了数据目录,仍然无法启动 Redis 容器。"
return 1
fi
fi
else
log "错误: 容器 'uredis' 不存在!"
log "信息: 您可能需要手动重新创建 Redis 容器。"
return 1
fi
}
#===============================================================================
# 主逻辑
#===============================================================================
# 获取锁(防止并发执行)
acquire_lock
# 执行日志轮转
rotate_logs
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服务仍不可用"
log "信息: 请使用以下命令检查容器日志: docker logs uredis"
fi
else
log "警告: 未达到重启阈值,等待下次检查确认"
fi
fi
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论