登录后用户特定的 502 错误——追溯到 DiscourseUpdates.has_unseen_features?

我们遇到了同样的问题,并进一步追踪了根源。

根本原因是 DiscourseUpdates.has_unseen_features? 调用了 GitUtils.has_commit?,该函数执行以下命令:

git merge-base --is-ancestor <sha> HEAD

在较新的 Discourse Docker 镜像中,容器内的仓库被配置为带有提示远程(promisor remote)的部分克隆。当功能对应的 SHA 不在本地时,Git 会尝试从远程进行懒加载(upload-pack),每次调用大约需要 3–4 秒。

由于会检查多个功能,这导致请求耗时超过 30 秒,并最终引发 502 错误(Unicorn 超时),尤其对于会执行此检查的 staff 用户而言。

关键点:

  • 仅针对 staff 用户发生(通过 CurrentUserSerializer

  • 由部分克隆中缺失的提交引起

  • 对缺失对象执行的 Git 操作会触发缓慢的远程查找

  • 可通过在容器内执行 git merge-base --is-ancestor <missing_sha> HEAD 复现

一个简单的缓解方案是对 GitUtils.has_commit? 的结果进行缓存(例如按 HEAD+SHA 缓存),从而避免重复调用耗时的 Git 操作。