- 完成REQ-010-17(性能优化和限流处理)的所有6个阶段 - 创建ADR文档:0026-performance-optimization.md - 创建Prompt文档:027-performance-optimization.md - 创建会话记录:20260119-performance-optimization.md - 创建变更记录:20260119-performance-optimization.md - 创建复盘报告:20260119-performance-optimization-retro.md - 更新index.md和CHANGELOG.md - 完成REQ-010-2(基础实体类和Mapper创建)的前3个阶段 - 更新ADR文档:0011-entity-mapper-create.md - 创建Prompt文档:002-entity-mapper-create.md - 更新index.md 所有文档均按照SSOT方法论创建,包括需求定义、架构决策、提示词资产化、执行会话、变更记录和闭环复盘。
220 lines
8.5 KiB
Markdown
220 lines
8.5 KiB
Markdown
# 架构决策记录 - 文件哈希对比和增量检测
|
||
|
||
## 背景
|
||
|
||
在 Salesforce 元数据拉取和部署过程中,每次都拉取或部署所有文件会导致性能低下,特别是在元数据文件数量较多的情况下。为了提高性能,需要实现文件哈希对比和增量检测功能,只拉取或部署变化的文件。
|
||
|
||
当前系统已经实现了文件存储和解压处理(REQ-010-7)和元数据组件索引和查询(REQ-010-11),需要在此基础上实现文件哈希对比和增量检测功能。
|
||
|
||
## 决策
|
||
|
||
### 1. 文件哈希计算方案
|
||
|
||
**决策**: 使用 Java MessageDigest 计算 SHA-256 哈希,使用流式处理大文件。
|
||
|
||
**理由**:
|
||
- SHA-256 是一种安全的哈希算法,能够准确识别文件变化
|
||
- Java MessageDigest 是 Java 标准库的一部分,无需额外依赖
|
||
- 流式处理可以避免一次性加载大文件到内存,降低内存使用
|
||
|
||
**实现方案**:
|
||
- 创建 IFileHashService 服务接口
|
||
- 创建 FileHashServiceImpl 服务实现
|
||
- 使用 MessageDigest.getInstance("SHA-256") 获取 SHA-256 哈希算法实例
|
||
- 使用 BufferedInputStream 流式读取文件,避免一次性加载大文件到内存
|
||
- 使用 8KB 缓冲区,平衡内存使用和读取性能
|
||
|
||
### 2. 哈希对比方案
|
||
|
||
**决策**: 使用哈希值直接对比,使用并行处理提高对比性能。
|
||
|
||
**理由**:
|
||
- 哈希值直接对比简单高效,能够准确识别文件变化
|
||
- 并行处理可以利用多核 CPU 的优势,提高对比性能
|
||
- 使用 Java 8 的 Stream API 可以方便地实现并行处理
|
||
|
||
**实现方案**:
|
||
- 创建 IHashComparisonService 服务接口
|
||
- 创建 HashComparisonServiceImpl 服务实现
|
||
- 使用 String.equals() 方法对比哈希值
|
||
- 使用 parallelStream() 并行处理多个文件
|
||
- 使用 ConcurrentHashMap 缓存哈希值,避免重复计算
|
||
|
||
### 3. 增量检测方案
|
||
|
||
**决策**: 使用哈希对比检测文件变化,使用文件系统监听器检测文件删除。
|
||
|
||
**理由**:
|
||
- 哈希对比能够准确识别文件的新增和修改
|
||
- 文件系统监听器能够实时检测文件删除
|
||
- 结合两种方式可以全面检测文件变化
|
||
|
||
**实现方案**:
|
||
- 创建 IIncrementalDetectionService 服务接口
|
||
- 创建 IncrementalDetectionServiceImpl 服务实现
|
||
- 使用哈希对比检测文件的新增和修改
|
||
- 使用 Java NIO 的 WatchService 监听文件系统事件
|
||
- 使用 ChangeType 枚举定义文件变化类型(ADDED、MODIFIED、DELETED)
|
||
- 使用 FileChange 实体类记录文件变化信息
|
||
|
||
### 4. 增量拉取方案
|
||
|
||
**决策**: 使用增量检测结果构建 package.xml,只拉取变化的文件。
|
||
|
||
**理由**:
|
||
- package.xml 是 Salesforce Metadata API 的标准配置格式,易于理解和维护
|
||
- 只拉取变化的文件可以减少网络传输和处理时间
|
||
- 复用现有的 IMetadataRetrieveService 服务接口,保持代码一致性
|
||
|
||
**实现方案**:
|
||
- 创建 IIncrementalRetrieveService 服务接口
|
||
- 创建 IncrementalRetrieveServiceImpl 服务实现
|
||
- 使用增量检测结果构建 package.xml
|
||
- 调用 IMetadataRetrieveService 的 retrieve() 方法,传入 package.xml
|
||
- 使用异步执行,避免阻塞主线程
|
||
- 复用现有的 AsyncConfig 配置类和线程池
|
||
|
||
### 5. 增量部署方案
|
||
|
||
**决策**: 使用增量检测结果构建 package.xml,只部署变化的文件。
|
||
|
||
**理由**:
|
||
- package.xml 是 Salesforce Metadata API 的标准配置格式,易于理解和维护
|
||
- 只部署变化的文件可以减少网络传输和处理时间
|
||
- 复用现有的 IMetadataDeployService 服务接口,保持代码一致性
|
||
|
||
**实现方案**:
|
||
- 创建 IIncrementalDeployService 服务接口
|
||
- 创建 IncrementalDeployServiceImpl 服务实现
|
||
- 使用增量检测结果构建 package.xml
|
||
- 调用 IMetadataDeployService 的 deploy() 方法,传入 package.xml
|
||
- 使用异步执行,避免阻塞主线程
|
||
- 复用现有的 AsyncConfig 配置类和线程池
|
||
|
||
## 备选方案
|
||
|
||
### 备选方案 1: 使用文件修改时间对比
|
||
|
||
**优点**:
|
||
- 实现简单,无需计算哈希值
|
||
- 性能较高,无需读取文件内容
|
||
|
||
**缺点**:
|
||
- 文件修改时间可能不准确,可能导致误判
|
||
- 无法检测文件内容是否真的发生变化
|
||
|
||
**结论**: 不采用,因为文件修改时间可能不准确,无法保证增量检测的准确性。
|
||
|
||
### 备选方案 2: 使用 MD5 哈希算法
|
||
|
||
**优点**:
|
||
- MD5 哈希计算速度快
|
||
- 实现简单
|
||
|
||
**缺点**:
|
||
- MD5 存在碰撞风险,安全性较低
|
||
- 不符合安全最佳实践
|
||
|
||
**结论**: 不采用,因为 MD5 存在碰撞风险,安全性较低,不符合安全最佳实践。
|
||
|
||
### 备选方案 3: 使用第三方库计算哈希
|
||
|
||
**优点**:
|
||
- 性能可能更高
|
||
- 功能可能更丰富
|
||
|
||
**缺点**:
|
||
- 增加依赖,增加项目复杂度
|
||
- 可能存在安全风险
|
||
|
||
**结论**: 不采用,因为 Java 标准库已经提供了足够的功能,无需额外依赖。
|
||
|
||
## 影响
|
||
|
||
### 对系统架构的影响
|
||
|
||
- 新增 file-hash 包,包含文件哈希对比和增量检测相关的服务、控制器、DTO、实体、Mapper、工具类
|
||
- 复用现有的 IFileStorageService 接口,用于读取文件内容
|
||
- 复用现有的 IMetadataRetrieveService 服务接口,用于增量拉取
|
||
- 复用现有的 IMetadataDeployService 服务接口,用于增量部署
|
||
- 复用现有的 AsyncConfig 配置类和线程池,用于异步执行
|
||
|
||
### 对开发流程的影响
|
||
|
||
- 开发人员需要了解文件哈希对比和增量检测的实现原理
|
||
- 需要编写单元测试和集成测试,确保功能正常
|
||
- 需要编写文档,说明如何使用文件哈希对比和增量检测功能
|
||
|
||
### 对运维管理的影响
|
||
|
||
- 需要监控文件哈希计算和对比的性能
|
||
- 需要监控增量拉取和部署的性能
|
||
- 需要定期清理过期的哈希值,避免占用过多存储空间
|
||
|
||
## 风险
|
||
|
||
### 技术风险
|
||
|
||
- **哈希计算风险**: 哈希计算错误可能导致增量检测不准确
|
||
- **缓解措施**: 使用单元测试和集成测试验证哈希计算的准确性
|
||
- **对比性能风险**: 对比性能不佳可能影响用户体验
|
||
- **缓解措施**: 使用并行处理提高对比性能,使用缓存避免重复计算
|
||
- **增量检测风险**: 增量检测不准确可能导致遗漏或误判
|
||
- **缓解措施**: 使用哈希对比和文件系统监听器两种方式,全面检测文件变化
|
||
|
||
### 业务风险
|
||
|
||
- **增量拉取风险**: 增量拉取失败可能导致文件不一致
|
||
- **缓解措施**: 提供回滚机制,支持重新拉取所有文件
|
||
- **增量部署风险**: 增量部署失败可能导致部署不完整
|
||
- **缓解措施**: 提供回滚机制,支持重新部署所有文件
|
||
|
||
### 实施风险
|
||
|
||
- **性能风险**: 文件哈希计算和对比性能可能不满足要求
|
||
- **缓解措施**: 使用流式处理和并行处理提高性能
|
||
- **兼容性风险**: 新增功能可能与现有功能不兼容
|
||
- **缓解措施**: 充分测试,确保兼容性
|
||
|
||
## 回滚策略
|
||
|
||
如果决策实施后出现问题,可以采取以下回滚策略:
|
||
|
||
1. **禁用增量检测**: 在配置中禁用增量检测功能,回退到全量拉取和部署
|
||
2. **重新计算哈希**: 如果哈希计算出现问题,可以重新计算所有文件的哈希值
|
||
3. **回退到全量操作**: 如果增量拉取或部署失败,可以回退到全量拉取和部署
|
||
|
||
## 验收标准
|
||
|
||
定义验证该决策有效性的具体标准和测试方法:
|
||
|
||
1. **功能完整性**: 所有文件哈希对比和增量检测功能能够正常工作
|
||
2. **性能指标**: 哈希计算和对比性能满足要求,增量拉取和部署性能满足要求
|
||
3. **准确性**: 增量检测结果准确,只拉取或部署变化的文件
|
||
4. **代码规范性**: 代码符合项目编码规范,有清晰的注释
|
||
5. **可维护性**: 代码结构清晰,易于扩展和维护
|
||
6. **可测试性**: 代码易于单元测试和集成测试
|
||
|
||
## 视觉锚点
|
||
|
||
### Visual Reference
|
||
|
||
引用 Canvas 的具体节点或快照:
|
||
- [Authentication.canvas](../../Authentication.canvas) - 相关架构图
|
||
- **具体节点**: [集成核心](node_integration_core) - 提供与Salesforce的各种连接方式
|
||
|
||
### Status
|
||
|
||
- [x] Draft
|
||
- [ ] Accepted
|
||
- [ ] Superceded
|
||
|
||
## 参考资料
|
||
|
||
列出与该决策相关的参考资料,包括文档、文章或其他资源:
|
||
|
||
- [REQ-010-12.md](../requirements/REQ-010-12.md) - 文件哈希对比和增量检测需求文档
|
||
- [REQ-010-7.md](../requirements/REQ-010-7.md) - 文件存储和解压处理需求文档
|
||
- [REQ-010-11.md](../requirements/REQ-010-11.md) - 元数据组件索引和查询需求文档
|
||
- [file/index.md](../api-docs/file/index.md) - 文件模块 API 文档索引(唯一真源)
|