Help us learn about your current experience with the documentation. Take the survey.
导入器设计原则
安全
- 上传的文件必须经过验证。例如:
- 导入器不得添加进行 HTTP 调用的第三方 Ruby gem。 导入器使用与集成相同的 Ruby gem 策略,有关导入器使用 Ruby gem 的更多信息,请参阅该页面。
- 所有 HTTP 调用必须使用
Import::Clients::HTTP,它:
日志记录
- 日志应包含导入器类型,如
github、bitbucket、bitbucket_server。您可以在Gitlab::ImportSources中找到完整的导入源列表。 - 日志应包含任何可能有助于调试的信息:
- 对象标识符,如
id、iid和对象类型 - 错误或状态消息
- 对象标识符,如
- 日志不应包含敏感或私人信息,包括但不限于:
- 用户名
- 电子邮件地址
- 在适用的情况下,我们应该在
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终止。它可能还需要提高其 Sidekiqmax_retries_after_interruption。请参考 GitHub 导入器实现。
- 如果 Worker 必须长时间运行,它必须使用
- 依赖缓存值的 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值。
- 包含
- 如果必须批量插入记录,考虑手动运行回调。