Специфичные для пользователя ошибки 502 после входа — связаны с DiscourseUpdates.has_unseen_features?

Здравствуйте,
У меня возникла странная проблема с моим Discourse: ошибки 502 возникают только для одной конкретной учетной записи (администратора) после входа в систему, в то время как:

  • Анонимные пользователи могут нормально получать доступ к сайту

  • Другие учетные записи пользователей могут входить в систему и использовать сайт без проблем

  • Проблема проявляется только для одной конкретной учетной записи (учетной записи администратора)


:puzzle_piece: Окружение

  • Discourse установлен с помощью официальной настройки Docker

  • Обратный прокси / CDN: ArvanCloud (аналогично Cloudflare)

  • Доступ к международному интернету ограничен / нестабилен (GitHub и некоторые внешние сервисы недоступны)

  • Discourse не обновлялся около 1 месяца


:red_exclamation_mark: Симптомы

При доступе к сайту:

  • Если открыть сайт в режиме инкогнито/приватном режиме → сайт загружается нормально

  • Если войти в систему с помощью основной учетной записи → сразу возникает ошибка 502 Bad Gateway

  • Если войти в систему с помощью другой учетной записи → всё работает нормально

Таким образом, проблема явно специфична для пользователя и возникает после аутентификации.


:page_facing_up: Журналы ошибок CDN (ArvanCloud)

Появляются две основные ошибки:

1. Тайм-аут при чтении данных от upstream

upstream timed out (110: Connection timed out) while reading upstream

Затронутые URL-адреса в основном относятся к ресурсам, например:

  • /assets/browser-detect-*.js

  • /assets/plugins/automation-*.js

  • /assets/plugins/discourse-gamification-*.js

  • /assets/plugins/discourse-lazy-videos-*.js

2. Upstream преждевременно закрыл соединение

upstream prematurely closed connection while reading response header from upstream

Например:

  • /stylesheets/common_theme_rtl_*.css

  • /theme-javascripts/*.js

Таким образом, CDN ожидает ответ от Discourse, но бэкенд истекает по тайм-ауту или закрывает соединение.


:magnifying_glass_tilted_left: Что я обнаружил на бэкенде

В трассировках стека Rails путь ошибки указывает на:

  • current_user_serializer.rb

  • discourse_updates.rb

  • метод: DiscourseUpdates.has_unseen_features?

Это указывает на то, что сбой/тайм-аут происходит при проверке объявлений о новых функциях для вошедших в систему пользователей.

Поскольку затронут только один пользователь, это сильно указывает на то, что проблема возникает во время сериализации, специфичной для пользователя, а не при глобальном отображении сайта.


Буду признателен за любые рекомендации.
Большое спасибо.

Вы пробовали на других браузерах или устройствах? Пробовали ли вы отключить расширения вашего браузера?

Редакция: Возможно, я неправильно понял. Загружается ли сайт в режиме инкогнито И при входе в систему как пользователь?

Да, я протестировал это на нескольких устройствах и в разных браузерах, и проблема не связана с расширениями браузера.

То, что я наблюдаю, зависит от пользователя, а не от устройства:

  • На любом устройстве, где учётная запись администратора уже была авторизована, открытие сайта сразу приводит к ошибке 502 Bad Gateway.

  • В режиме инкогнито/приватном режиме сайт загружается нормально, и я могу перейти на страницу входа.

  • Оттуда я могу успешно войти с другой (неадминистраторской) учётной записью, и сайт работает без проблем.

  • Но когда я пытаюсь войти с учётной записью администратора, сразу после ввода email и пароля я неизменно получаю ошибку 502, и страница никогда не загружается.

Мы столкнулись с той же проблемой и проследовали дальше в её поисках.

Коренная причина заключается в том, что DiscourseUpdates.has_unseen_features? вызывает GitUtils.has_commit?, который выполняет:

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

В более новых образах Docker для Discourse репозиторий внутри контейнера настроен как частичный клон с промисорным удалённым репозиторием. Если SHA-идентификатор функции отсутствует локально, Git пытается выполнить ленивую подгрузку из удалённого репозитория (upload-pack), что занимает примерно 3–4 секунды на каждый вызов.

Поскольку проверяется несколько функций, это приводит к времени выполнения запроса более 30 секунд и, в конечном итоге, к ошибке 502 (тайм-аут Unicorn), особенно для пользователей со статусом персонала, для которых выполняется эта проверка.

Ключевые моменты:

  • Возникает только для пользователей со статусом персонала (через CurrentUserSerializer)

  • Вызвано отсутствием коммитов в частичном клоне

  • Операции Git с отсутствующими объектами запускают медленные запросы к удалённому репозиторию

  • Воспроизводится с помощью команды git merge-base --is-ancestor <missing_sha> HEAD внутри контейнера

Простым решением является кэширование результатов GitUtils.has_commit? (например, по комбинации HEAD+SHA), что позволяет избежать повторных дорогостоящих вызовов Git.