# AutoFMA 借鉴实施计划 ## 项目背景 基于对 AutoFMA(自动光学量测机上位机)项目的分析,提取可借鉴的架构设计和实现模式,应用到 YZWater3(污水处理厂监控系统)中,提升系统的健壮性、可维护性和性能。 ## 借鉴点清单 | 序号 | 功能 | 来源 | 优先级 | 状态 | |:---:|:---|:---|:---:|:---:| | 1 | 数据库在线备份增强 | DatabaseBackupService | P0 | ✅ | | 2 | 数据保留清理服务 | DataRetentionService | P0 | ✅ | | 3 | 配置服务热加载 | ConfigService | P1 | ✅ | | 4 | 审计日志 Channel 异步写入 | AuditService | P1 | ✅ | | 5 | 日志缓冲服务 | LogBufferService | P2 | ✅ | --- ## P0 - 数据安全与维护 ### 1. 数据库在线备份增强 **当前实现**: `BackupService.cs` - 简单的 VACUUM INTO 备份 **借鉴来源**: `AutoFMA.Core/Services/DatabaseBackupService.cs` **改进内容**: - ✅ WAL checkpoint (TRUNCATE) - 合并未落盘数据 - ✅ 临时文件写入 → 验证 → 原子替换(避免备份失败时损坏旧备份) - ✅ `Interlocked.CompareExchange` 防重入 - ✅ 定时备份(每 24 小时) - ✅ 启动时自动备份 **实施文件**: - `src/YZWater.Core/Services/BackupService.cs` - 增强现有实现 --- ### 2. 数据保留清理服务 **当前实现**: 无 **借鉴来源**: `AutoFMA.Core/Services/DataRetentionService.cs` **新增内容**: - ✅ 启动时立即清理一次 + 每 24 小时定时清理 - ✅ 支持多表独立配置保留天数 - ✅ `Interlocked` 防重入 - ✅ 配置化保留天数 **清理范围**: - `alarm_records` - 报警记录(默认 90 天) - `flow_records` - 流量记录(默认 360 天) - `analog_records` - 模拟量记录(默认 360 天) - `audit_logs` - 审计日志(默认 365 天) **实施文件**: - `src/YZWater.Core/Services/DataRetentionService.cs` - 新增 - `src/YZWater.Core/Models/SystemConfig.cs` - 新增保留天数配置 --- ## P1 - 架构升级 ### 3. 配置服务热加载 **当前实现**: `ConfigService.cs` - 手动加载/保存 **借鉴来源**: `AutoFMA.Core/Services/ConfigService.cs` **改进内容**: - ✅ `FileSystemWatcher` 监听配置文件变更 - ✅ `_isSaving` 标记避免自己触发的变更 - ✅ 原子写入(临时文件 → 覆盖) - ✅ `SemaphoreSlim` 读写互斥 - ✅ `ConfigChanged` 事件通知 - ✅ 权限校验(Engineer 以上才可修改) **实施文件**: - `src/YZWater.Core/Services/ConfigService.cs` - 增强现有实现 --- ### 4. 审计日志 Channel 异步写入 **当前实现**: `AuditService.cs` - 直接写入数据库 **借鉴来源**: `AutoFMA.Core/Services/AuditService.cs` **改进内容**: - ✅ `Channel` 有界队列(防密集写入时线程池打满) - ✅ 后台单线程串行写入数据库 - ✅ 退出时 flush(`_writerTask.Wait(5s)`) - ✅ `FullMode = DropOldest` 防止队列满时阻塞 **实施文件**: - `src/YZWater.Core/Services/AuditService.cs` - 重构为实例类 --- ## P2 - 性能优化 ### 5. 日志缓冲服务 **当前实现**: 无(各 ViewModel 各自订阅日志) **借鉴来源**: `AutoFMA.Core/Services/LogBufferService.cs` **新增内容**: - ✅ 统一订阅 `LogService`,维护单一缓冲区 - ✅ Dashboard 和 LogViewer 共用此缓冲 - ✅ 超过阈值(`TrimThreshold`)再裁剪,减少 O(N) 移动频率 - ✅ `LogAdded` 事件通知 **实施文件**: - `src/YZWater.Core/Services/LogBufferService.cs` - 新增 --- ## 实施顺序 ``` Phase 1 (P0 - 数据安全) ✅ 已完成 ├── 1.1 增强 BackupService ✅ └── 1.2 新增 DataRetentionService ✅ Phase 2 (P1 - 架构升级) ✅ 已完成 ├── 2.1 增强 ConfigService ✅ └── 2.2 重构 AuditService ✅ Phase 3 (P2 - 性能优化) ✅ 已完成 └── 3.1 新增 LogBufferService ✅ ``` ## 实施完成日期 2026-09-06 --- ## 配置项扩展 在 `SystemConfig` 中新增以下配置: ```csharp // 数据保留配置 public DataRetentionConfig DataRetention { get; set; } = new(); public class DataRetentionConfig { /// 报警记录保留天数(默认 90 天) public int AlarmRecordRetentionDays { get; set; } = 90; /// 流量记录保留天数(默认 360 天) public int FlowRecordRetentionDays { get; set; } = 360; /// 模拟量记录保留天数(默认 360 天) public int AnalogRecordRetentionDays { get; set; } = 360; /// 审计日志保留天数(默认 365 天) public int AuditLogRetentionDays { get; set; } = 365; } // 备份配置 public BackupConfig Backup { get; set; } = new(); public class BackupConfig { /// 是否启用定时备份 public bool EnableScheduledBackup { get; set; } = true; /// 定时备份间隔(小时,默认 24 小时) public int BackupIntervalHours { get; set; } = 24; /// 保留备份数量(默认 7 个) public int KeepBackupCount { get; set; } = 7; } ``` --- ## 测试验证 每个功能实施后需验证: 1. **BackupService 增强** - [ ] 启动时自动备份 - [ ] 定时备份正常触发 - [ ] 备份失败时不损坏旧备份 - [ ] 并发调用时防重入正常 2. **DataRetentionService** - [ ] 启动时立即清理 - [ ] 定时清理正常触发 - [ ] 各表独立保留天数 - [ ] 并发调用时防重入正常 3. **ConfigService 热加载** - [ ] 外部修改配置文件后自动加载 - [ ] 保存时原子写入 - [ ] 自己触发的变更不重复加载 - [ ] `ConfigChanged` 事件正常触发 4. **AuditService Channel 写入** - [ ] 高并发写入时不阻塞主线程 - [ ] 退出时数据不丢失 - [ ] 队列满时丢弃旧数据 5. **LogBufferService** - [ ] Dashboard 和 LogViewer 共享缓冲 - [ ] 超过阈值自动裁剪 - [ ] `LogAdded` 事件正常触发 --- ## 注意事项 1. **向后兼容**: 所有改进保持现有 API 兼容,现有代码无需修改即可运行 2. **配置可选**: 新增配置项都有默认值,无需修改配置文件即可使用 3. **日志规范**: 使用 Serilog 记录日志,保持与现有代码一致 4. **异常处理**: 所有新功能都有完善的异常处理,不影响主流程 --- ## 参考资料 - AutoFMA 项目: `E:\设备\自动光学量测机\AutoFMA` - YZWater3 项目: `E:\Source\YZWater3` - SQLite WAL 模式: https://www.sqlite.org/wal.html - System.Threading.Channels: https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.channels