datai/docs/archive/decisions/adr/0017-metadata-deploy-core.md

16 KiB
Raw Permalink Blame History

架构决策记录 - 元数据部署核心功能

背景

在 REQ-010-6元数据拉取核心功能和 REQ-010-7文件存储和解压处理我们已经实现了从 Salesforce Metadata API 拉取元数据的功能,以及文件存储和解压处理功能。现在需要实现元数据部署的核心功能,将本地的元数据部署到 Salesforce 组织中。

本需求面临的主要问题包括:

  1. 部署操作可能需要较长时间,需要异步执行避免阻塞主线程
  2. 需要实时监控部署状态,及时反馈部署进度
  3. 需要支持部署取消功能,避免长时间运行的部署任务占用资源
  4. 需要记录部署历史,便于查询和审计
  5. 需要解析部署结果,提取错误信息和代码覆盖率

相关约束条件:

  • 必须基于现有的 Spring Boot 3 + Vue 3 技术栈
  • 必须在 datai-salesforce-metadata 模块下实现
  • 必须使用 SessionManager 进行会话管理和自动重新登录
  • 必须使用现有的集成核心功能进行 Salesforce API 调用
  • 必须使用异步线程池执行长时间任务
  • 必须遵循现有的异常处理机制和日志记录规范

决策

1. 手动触发部署方案

决策: 使用 RESTful API 接口实现手动触发部署,调用 MetadataApiClient 的 deploy() 方法。

理由:

  • RESTful API 是标准的接口设计模式,易于使用和理解
  • 可以与前端组件无缝集成
  • 支持多种客户端Web、移动端、第三方应用
  • 符合项目现有的 API 设计规范

实现方案:

  • 创建 MetadataDeployController 控制器
  • 提供 POST /metadata/deploy/trigger 接口
  • 接收任务ID、组织配置ID和Zip文件作为参数
  • 调用 MetadataApiService 的 deployAsync() 方法
  • 返回 Job ID 和初始状态

2. 异步部署执行方案

决策: 使用 Spring 的 @Async 注解和自定义线程池实现异步部署执行。

理由:

  • Spring 的 @Async 注解简化了异步编程
  • 自定义线程池可以更好地控制并发度和资源使用
  • 支持并发部署,提高系统吞吐量
  • 部署任务不阻塞系统响应,提高用户体验

实现方案:

  • 配置自定义线程池ThreadPoolTaskExecutor
  • 使用 @Async 注解标记异步方法
  • 异步方法中调用 MetadataApiClient 的 deploy() 方法
  • 使用 Future 对象跟踪异步任务状态

3. 状态监控方案

决策: 使用状态机模式管理部署状态,使用轮询机制检查部署状态。

理由:

  • 状态机模式可以清晰地定义状态转换规则
  • 轮询机制简单可靠,易于实现
  • 可以实时监控部署状态,及时反馈部署进度
  • 支持多种部署状态Pending/Processing/Success/Failed/Partial_Success/Cancelled

实现方案:

  • 定义 DeployStatus 枚举Pending/Processing/Success/Failed/Partial_Success/Cancelled
  • 使用状态机管理部署状态转换
  • 使用定时任务轮询部署状态
  • 将状态更新到数据库datai_meta_job_execution 表)

4. 部署历史记录方案

决策: 使用 MyBatis Plus 的 BaseMapper 实现部署历史记录查询。

理由:

  • MyBatis Plus 提供了强大的 CRUD 操作,简化开发
  • 支持分页查询,提高查询性能
  • 支持条件查询,灵活满足不同查询需求
  • 符合项目现有的持久层框架

实现方案:

  • 使用 datai_meta_job_execution 表存储部署历史记录
  • 使用 MyBatis Plus 的 BaseMapper 实现查询
  • 支持分页查询(使用 Page 对象)
  • 支持条件查询(使用 QueryWrapper

5. 部署进度查询方案

决策: 使用轮询机制获取部署进度,使用缓存提高查询性能。

理由:

  • 轮询机制简单可靠,易于实现
  • 缓存可以提高查询性能,减少数据库访问
  • 支持实时进度查询,提高用户体验
  • 支持进度百分比显示,直观展示部署进度

实现方案:

  • 使用定时任务轮询部署状态
  • 使用 ConcurrentHashMap 缓存部署进度信息
  • 提供 GET /metadata/deploy/progress/{jobId} 接口查询进度
  • 进度信息包括:状态、进度百分比、已处理组件数、总组件数

6. 部署取消方案

决策: 使用 Future.cancel() 取消异步任务,使用状态机管理取消状态。

理由:

  • Future.cancel() 可以安全地取消异步任务
  • 状态机可以清晰地管理取消状态
  • 取消后资源正确释放,避免资源泄漏
  • 取消状态更新及时,用户可以及时获知取消结果

实现方案:

  • 使用 Future.cancel() 取消异步任务
  • 将状态更新为 Cancelled
  • 释放相关资源(如文件句柄、数据库连接等)
  • 记录取消日志,便于审计

7. 部署结果解析方案

决策: 使用 JSON 解析库处理 API 响应,使用正则表达式提取错误信息。

理由:

  • JSON 解析库(如 Jackson功能强大易于使用
  • 正则表达式可以灵活地提取错误信息
  • 支持多种部署状态,适应不同场景
  • 错误信息详细,便于问题排查

实现方案:

  • 使用 Jackson 解析 API 响应
  • 提取部署状态、错误信息、代码覆盖率
  • 使用正则表达式提取错误信息
  • 将解析结果存储到数据库datai_meta_job_log 表)

备选方案

1. 手动触发部署方案备选

备选方案 A: 使用消息队列(如 RabbitMQ触发部署。

优点:

  • 支持分布式部署
  • 支持任务重试和死信队列
  • 支持任务优先级

缺点:

  • 引入额外依赖,增加系统复杂度
  • 部署成本高
  • 对于简单的部署场景,过于重量级

备选方案 B: 使用定时任务触发部署。

优点:

  • 实现简单

缺点:

  • 不支持实时触发
  • 用户体验差
  • 不符合需求

2. 异步部署执行方案备选

备选方案 A: 使用 CompletableFuture 实现异步执行。

优点:

  • Java 8 原生支持
  • 支持链式调用和组合

缺点:

  • 不如 Spring 的 @Async 注解简洁
  • 需要手动管理线程池

备选方案 B: 使用消息队列实现异步执行。

优点:

  • 支持分布式部署
  • 支持任务重试和死信队列

缺点:

  • 引入额外依赖,增加系统复杂度
  • 部署成本高
  • 对于简单的异步场景,过于重量级

3. 状态监控方案备选

备选方案 A: 使用事件驱动架构监控状态。

优点:

  • 实时性好
  • 解耦度高

缺点:

  • 实现复杂
  • 引入额外依赖(如消息队列)
  • 对于简单的状态监控,过于重量级

备选方案 B: 使用 WebSocket 推送状态更新。

优点:

  • 实时性好
  • 用户体验好

缺点:

  • 实现复杂
  • 需要维护长连接
  • 对于简单的状态监控,过于重量级

4. 部署历史记录方案备选

备选方案 A: 使用 Elasticsearch 存储部署历史记录。

优点:

  • 查询性能好
  • 支持全文搜索

缺点:

  • 引入额外依赖,增加系统复杂度
  • 部署成本高
  • 对于简单的历史记录查询,过于重量级

备选方案 B: 使用 Redis 缓存部署历史记录。

优点:

  • 查询性能好

缺点:

  • 数据持久性差
  • 不支持复杂查询
  • 不符合需求

5. 部署进度查询方案备选

备选方案 A: 使用 WebSocket 推送进度更新。

优点:

  • 实时性好
  • 用户体验好

缺点:

  • 实现复杂
  • 需要维护长连接
  • 对于简单的进度查询,过于重量级

备选方案 B: 使用 Server-Sent Events (SSE) 推送进度更新。

优点:

  • 实时性好
  • 实现相对简单

缺点:

  • 不支持双向通信
  • 浏览器兼容性问题
  • 对于简单的进度查询,过于重量级

6. 部署取消方案备选

备选方案 A: 使用中断线程的方式取消部署。

优点:

  • 实现简单

缺点:

  • 不安全,可能导致资源泄漏
  • 不推荐使用
  • 不符合最佳实践

备选方案 B: 使用标志位的方式取消部署。

优点:

  • 实现简单
  • 相对安全

缺点:

  • 需要在代码中频繁检查标志位
  • 不如 Future.cancel() 简洁

7. 部署结果解析方案备选

备选方案 A: 使用 XML 解析库处理 API 响应。

优点:

  • 功能强大

缺点:

  • API 响应主要是 JSON 格式
  • 不如 JSON 解析库简洁
  • 不符合需求

备选方案 B: 使用字符串操作提取错误信息。

优点:

  • 实现简单

缺点:

  • 不够灵活
  • 容易出错
  • 不如正则表达式强大

影响

系统架构影响

  1. 新增模块: 在 datai-salesforce-metadata 模块下新增 deploy 包,包含部署相关的服务、控制器、枚举和 DTO
  2. 接口定义: 定义 IMetadataDeployService 接口,提供统一的部署服务抽象
  3. 状态机: 使用状态机模式管理部署状态,提高状态管理的可维护性
  4. 异步执行: 使用 Spring 的 @Async 注解和自定义线程池实现异步部署执行
  5. 轮询机制: 使用定时任务轮询部署状态,实现实时监控

开发流程影响

  1. 开发工作量: 需要开发 7 个主要功能模块,预计工作量 5-7 人天
  2. 测试工作量: 需要进行单元测试、集成测试和性能测试,预计工作量 3-4 人天
  3. 代码规范: 需要遵循项目现有的代码规范和设计模式
  4. 文档维护: 需要更新接口文档和 API 文档

运维管理影响

  1. 配置管理: 需要新增配置项(线程池配置、轮询间隔等)
  2. 监控告警: 需要配置部署任务监控和告警通知
  3. 日志管理: 需要记录部署操作日志和错误日志
  4. 任务管理: 需要定期检查部署任务状态,清理过期任务

风险

技术风险

  1. 异步执行风险: 异步执行机制复杂可能导致状态管理困难

    • 缓解措施: 使用状态机模式管理状态,使用 Future 对象跟踪异步任务
    • 监控指标: 监控异步任务执行时间和状态转换
  2. 状态轮询风险: 状态轮询频率不当可能导致 API 限流

    • 缓解措施: 设置合理的轮询间隔(如 5 秒),使用指数退避策略
    • 监控指标: 监控 API 调用次数和响应时间
  3. 部署取消风险: 部署取消功能复杂可能导致资源泄漏

    • 缓解措施: 使用 Future.cancel() 安全取消,确保资源正确释放
    • 监控指标: 监控取消操作的成功率和资源释放情况

业务风险

  1. 历史记录风险: 部署历史记录过多可能影响查询性能

    • 缓解措施: 使用分页查询,定期清理过期历史记录
    • 监控指标: 监控历史记录查询性能
  2. 进度查询风险: 进度查询不准确可能导致用户体验差

    • 缓解措施: 使用缓存提高查询性能,优化轮询策略
    • 监控指标: 监控进度查询的准确性和响应时间
  3. 结果解析风险: 部署结果解析不完善可能导致错误信息不准确

    • 缓解措施: 使用 JSON 解析库和正则表达式双重验证,充分测试
    • 监控指标: 监控结果解析的成功率和准确性

实施风险

  1. 性能风险: 部署操作可能影响系统性能

    • 缓解措施: 使用异步执行,限制并发数,使用线程池管理资源
    • 监控指标: 监控系统 CPU 和内存使用情况
  2. 兼容性风险: 不同版本的 Salesforce Metadata API 可能存在兼容性问题

    • 缓解措施: 使用版本化的 API 客户端,充分测试
    • 监控指标: 监控 API 调用成功率和错误率

回滚策略

1. 手动触发部署回滚策略

如果手动触发部署出现问题,可以立即停止部署:

  1. 禁用部署接口
  2. 回滚已部署的元数据(如果有)
  3. 修复问题后重新启用

2. 异步部署执行回滚策略

如果异步部署执行出现问题,可以临时使用同步执行:

  1. 修改代码,移除 @Async 注解
  2. 限制并发数,避免系统过载
  3. 优化后重新切换回异步执行

3. 状态监控回滚策略

如果状态监控出现问题,可以临时使用数据库查询:

  1. 修改代码,直接查询数据库获取状态
  2. 优化后重新切换回轮询机制

4. 整体回滚策略

如果整个功能出现问题,可以回滚到 REQ-010-7 的状态:

  1. 停止使用元数据部署功能
  2. 修复问题后重新启用

验收标准

功能验收标准

  1. 手动触发部署

    • 能够成功手动触发部署
    • 支持选择任务ID
    • 支持选择组织配置
    • 支持上传Zip文件
    • 触发成功返回Job ID
    • API接口符合RESTful规范
  2. 异步部署执行

    • 异步部署执行正常工作
    • 使用线程池管理异步任务
    • 支持并发部署
    • 部署任务不阻塞系统响应
  3. 状态监控

    • 状态监控正常工作
    • 使用状态机管理部署状态
    • 支持状态查询
    • 状态更新及时
  4. 部署历史记录

    • 部署历史记录成功
    • 支持分页查询
    • 支持条件查询
    • 历史记录完整
  5. 部署进度查询

    • 部署进度查询成功
    • 支持实时进度查询
    • 进度信息准确
    • 支持进度百分比显示
  6. 部署取消

    • 部署取消功能正常工作
    • 支持取消正在进行的部署任务
    • 取消后资源正确释放
    • 取消状态更新及时
  7. 部署结果解析

    • 部署结果解析成功
    • 错误信息提取正确
    • 代码覆盖率提取正确
    • 支持多种部署状态
    • 错误信息详细

性能验收标准

  1. 部署触发性能

    • 部署触发响应时间 < 1s
    • 并发触发 10 个部署任务无性能下降
  2. 状态轮询性能

    • 状态轮询任务执行时间 < 1s
    • 不影响系统正常运行
  3. 进度查询性能

    • 进度查询响应时间 < 500ms
    • 并发查询 100 次无性能下降
  4. 历史记录查询性能

    • 历史记录查询响应时间 < 1s
    • 分页查询 100 条记录无性能下降

安全性验收标准

  1. 认证安全

    • 部署操作需要认证
    • 使用 SessionManager 进行会话管理
    • 自动重新登录功能正常
  2. 数据安全

    • 部署数据传输加密
    • 敏感信息不记录到日志
    • 部署历史记录权限控制

代码质量验收标准

  1. 代码规范

    • 代码符合项目编码规范
    • 有清晰的注释
    • 通过代码审查
  2. 测试覆盖

    • 单元测试覆盖率 > 80%
    • 集成测试覆盖主要场景
    • 性能测试通过
  3. 文档完整

    • 接口文档完整
    • API 文档完整
    • 使用文档完整

视觉锚点

Visual Reference

引用 Canvas 的具体节点或快照:

Status

  • Draft
  • Accepted
  • Superceded

参考资料

列出与该决策相关的参考资料,包括文档、文章或其他资源:

  1. REQ-010-8.md - 元数据部署核心功能需求文档
  2. REQ-010-6.md - 元数据拉取核心功能需求文档
  3. REQ-010-7.md - 文件存储和解压处理需求文档
  4. 004-元数据部署网页资料链接地址 - 官方文档和开源项目参考
  5. metadata-module.md - Salesforce Metadata API 模块说明
  6. index.md - Salesforce SOAP API Java 客户端参考文档