# 架构决策记录 - 文件哈希对比和增量检测 ## 背景 在 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 文档索引(唯一真源)