Help us learn about your current experience with the documentation. Take the survey.

导入器设计原则

安全

  • 上传的文件必须经过验证。例如:
  • 导入器不得添加进行 HTTP 调用的第三方 Ruby gem。 导入器使用与集成相同的 Ruby gem 策略,有关导入器使用 Ruby gem 的更多信息,请参阅该页面。
  • 所有 HTTP 调用必须使用 Import::Clients::HTTP,它:
    • 确保 HTTP 调用强制执行 网络设置
    • 具有额外的 安全加固 功能。
    • 是我们进行安全 HTTP 调用的唯一真实来源。
    • 确保所有响应大小都经过验证。

日志记录

  • 日志应包含导入器类型,如 githubbitbucketbitbucket_server。您可以在 Gitlab::ImportSources 中找到完整的导入源列表。
  • 日志应包含任何可能有助于调试的信息:
    • 对象标识符,如 idiid 和对象类型
    • 错误或状态消息
  • 日志不应包含敏感或私人信息,包括但不限于:
    • 用户名
    • 电子邮件地址
  • 在适用的情况下,我们应该在 Gitlab::Import::ImportFailureService 中跟踪错误,以帮助在 UI 中显示错误。
  • 如果缺少关键标识符,日志记录应在开发环境中引发错误,如 此 MR 所示。
  • 应在导入每条记录之前和之后创建日志行,包含该记录的标识符。

性能

  • 应使用默认 TTL 为 24 小时的缓存来防止重复的数据库查询和 API 调用。
  • 循环遍历集合的 worker 应配备进度指针,以便在被打断时能够从中断处继续。
  • 写入密集的 worker 应实现 defer_on_database_health_signal 以避免数据库饱和。但是,在撰写本文时,一个已知问题 阻止了我们使用此功能。
  • 我们应该对 worker 并发性施加限制,以避免资源饱和。您可以在 Bitbucket 的 ParallelScheduling 中找到这方面的示例。
  • 导入器应在暂存环境中进行大规模测试,尤其是在实现新功能或启用功能标志时。

韧性

  • Worker 应该是幂等的,以便在失败时可以安全重试。
  • Worker 应该在重新排队时加入延迟,以尊重并发批处理限制。
  • 单个 Worker 不应长时间运行。长时间运行的 Worker 可能会因为部署而被 Sidekiq 中断,或者被 StuckProjectImportJobsWorker 误识别为属于卡住的导入任务并应该失败。
    • 如果 Worker 必须长时间运行,它必须使用 Gitlab::Import::RefreshImportJidWorker 刷新其 JID,以避免被 StuckProjectImportJobsWorker 终止。它可能还需要提高其 Sidekiq max_retries_after_interruption。请参考 GitHub 导入器实现
  • 依赖缓存值的 Worker 必须实现回退机制,以便在缓存未命中时获取数据。
    • 如果可能且性能允许,重新获取数据。
    • 优雅地处理缺失的值。
  • 长时间运行的 Worker 应该使用 worker_resource_boundary :memory 进行注释,以便将其放置在具有两小时终止宽限期的分片上。长的终止宽限期不能替代编写快速 Worker。可以在 I&I 团队 Grafana 仪表板 上监控 Apdex SLO 合规性。
  • 创建数据的 Worker 不应因为单个记录导入失败而导致整个导入失败。它们必须记录适当的错误,并根据错误的性质决定是否重试。
  • Import Stage Worker(包含 StageMethods)和 Advance Stage Worker(包含 Gitlab::Import::AdvanceStage)应该有 retries: 6,以使其更能抵抗系统中断。使用指数退避,六次重试大约跨越 20 分钟。任何更高的重试都会使导入时间过长。
  • 应该能够重试导入的一部分,例如重新导入缺失的问题,而不覆盖整个目标项目。

一致性

  • 导入器应在保存记录后触发回调。有问题的回调可以单独为导入禁用:
    • 包含 Importable 模块。
    • 配置回调以在 importing? 时跳过。
    • 在正在导入的对象上设置 importing 值。
  • 如果必须批量插入记录,考虑手动运行回调。