로그인 후 사용자별 502 오류 발생 — DiscourseUpdates.has_unseen_features?로 원인 확인

안녕하세요,

제 Discourse에서 로그인 후 특정 관리자(admin) 계정에서만 502 오류가 발생하는 이상한 문제를 겪고 있습니다. 다른 상황은 다음과 같습니다:

  • 익명 사용자는 사이트를 정상적으로 접근할 수 있습니다.

  • 다른 사용자 계정은 로그인하고 사이트를 정상적으로 사용할 수 있습니다.

  • 문제는 특정 계정(관리자 계정)에서만 발생합니다.


:puzzle_piece: 환경 정보

  • Discourse는 공식 Docker 설정으로 설치되었습니다.

  • 리버스 프록시 / CDN: ArvanCloud (Cloudflare와 유사)

  • 국제 인터넷 접속이 제한적이거나 불안정합니다 (GitHub 및 일부 외부 서비스에 접근 불가)

  • Discourse는 약 1개월 동안 업데이트되지 않았습니다


:red_exclamation_mark: 증상

사이트에 접근할 때:

  • 프라이빗/시크릿 모드로 사이트를 열면 → 사이트가 정상적으로 로드됩니다.

  • 주 계정으로 로그인하면 → 즉시 502 Bad Gateway 오류가 발생합니다.

  • 다른 계정으로 로그인하면 → 모든 기능이 정상적으로 작동합니다.

따라서 문제는 명확하게 사용자별로 발생하며 인증 후 트리거됩니다.


:page_facing_up: CDN (ArvanCloud) 오류 로그

주요 오류 두 가지가 나타납니다:

1. Upstream timeout while reading upstream

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

영향을 받는 URL은 대부분 자산(assets)입니다. 예를 들어:

  • /assets/browser-detect-*.js

  • /assets/plugins/automation-*.js

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

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

2. Upstream prematurely closed connection

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?

이는 크래시/타임아웃이 로그인된 사용자의 새 기능 공지사항을 확인하는 동안 발생한다는 것을 시사합니다.

단일 사용자만 영향을 받는 점을 고려하면, 이 문제는 전역 사이트 렌더링이 아니라 사용자별 직렬화(user-specific serialization) 과정에서 트리거되는 것으로 보입니다.


도움말을 주시면 감사하겠습니다.

감사합니다.

다른 브라우저나 기기에서도 시도해 보셨나요? 브라우저 확장 프로그램을 비활성화해 보셨나요?

수정: 제가 오해한 것 같습니다. 시크릿 모드에서 사용자 로그인 상태일 때도 사이트가 로드되나요?

네, 여러 기기와 브라우저에서 테스트해 보았고, 브라우저 확장 프로그램과는 관련이 없습니다.

제가 겪는 문제는 기기별이 아니라 사용자 계정에 따라 달라집니다:

  • 관리자 계정으로 이미 로그인되어 있던 기기에서 사이트를 열면 즉시 502 Bad Gateway 오류가 발생합니다.

  • 시크릿(프라이빗) 모드에서는 사이트가 정상적으로 로드되고 로그인 페이지에 접근할 수 있습니다.

  • 이후 다른(비관리자) 계정으로 로그인하면 성공적으로 로그인되고 사이트가 정상적으로 작동합니다.

  • 그러나 관리자 계정으로 로그인하려고 이메일과 비밀번호를 입력한 직후에는 항상 502 오류가 발생하며, 페이지가 로드되지 않습니다.

저희도 동일한 문제를 겪었고, 원인을 더 깊이 추적해 보았습니다.

근본 원인은 DiscourseUpdates.has_unseen_features?GitUtils.has_commit?를 호출하고, 이 함수가 다음을 실행하기 때문입니다:

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

새로운 Discourse Docker 이미지에서는 컨테이너 내부의 저장소가 **promisor remote를 사용하는 부분 클론(partial clone)**으로 설정되어 있습니다. 기능 SHA가 로컬에 존재하지 않는 경우, Git은 원격에서 지연 로드(lazy fetch)를 시도하며(upload-pack), 이 과정에서 호출당 약 3~4초가 소요됩니다.

여러 기능이 검사되므로 요청 시간이 30초 이상 걸리게 되며, 특히 이 검사가 실행되는 스태프 사용자의 경우 결국 502(Unicorn 타임아웃) 오류가 발생합니다.

주요 사항:

  • 스태프에게만 발생함(CurrentUserSerializer를 통해)

  • 부분 클론에서 커밋이 누락되어 발생함

  • 누락된 객체에 대한 Git 작업이 느린 원격 조회를 유발함

  • 컨테이너 내부에서 git merge-base --is-ancestor <missing_sha> HEAD로 재현 가능

간단한 완화 방안은 GitUtils.has_commit? 결과를 캐싱하는 것입니다(예: HEAD+SHA별로). 이를 통해 반복되는 비용이 높은 git 호출을 방지할 수 있습니다.