트러블 슈팅 - 다중 파드 환경에서 상담 세션이 유지되지 않아 발생한 간헐적 403 오류

발생 현상

운영 배포 후 커머스관리 → 상담관리 → 회원상담 관리 → 회원기본정보에서 상세보기를 클릭하면 간헐적으로 오류가 발생했다. 항상 실패하는 것이 아니라 정상 조회와 오류가 번갈아 나타나는 형태였다.

운영 BFF 로그에서는 다음 오류가 반복적으로 확인됐다.

API Error: [Status: 403 FORBIDDEN] [Code: 0] [Message: null]

같은 로그에 나타난 400 / 3700 / 멤버정보가 존재하지 않습니다 오류는 회원 검색 과정의 오류로 구분했다. 앞서 확인한 HTTP 주소 호출 문제와도 별개의 문제로 분석했다.

기존 처리 방식과 원인 분석

기존에는 회원을 검색하면 Commerce가 무작위 상담 ID인 contextId를 발급하고, 해당 ID와 회원번호의 관계를 Commerce 세션에 저장했다.

회원 검색
→ Commerce 세션에 ‘상담 ID ↔ 회원번호’ 저장
→ 화면에 상담 ID 전달
→ 목록·상세 조회 시 같은 세션에서 상담 ID 확인

따라서 후속 요청에서도 처음 정보를 저장한 Commerce 세션이 유지돼야 한다는 조건이 있었다.

운영처럼 요청이 여러 파드로 분산되는 환경에서는 처리 경로가 달라질 수 있다. 이때 동일한 세션이 이어지지 않으면, 검색 시 발급한 상담 ID가 있어도 후속 요청에서는 저장된 회원번호를 찾지 못해 403으로 거절될 수 있었다.

간헐적으로 동작한 이유도 이 구조로 설명할 수 있다. 같은 세션으로 이어지는 요청은 정상 처리되지만, 세션이 이어지지 않는 요청은 상담 정보 검증에 실패하는 것이다.

즉, 파드가 2개인 것 자체가 문제가 아니라, 여러 파드에서 동일한 상담 정보를 확인할 수 있도록 세션을 유지·공유해야 하는 구조가 문제의 핵심이었다. 다만 운영 로그의 개별 403을 모두 같은 원인으로 확정하려면 요청별 처리 파드와 세션 정보를 연결한 추가 확인이 필요하다.

개발·스테이지에서 발견하기 어려웠던 이유

대화에서 최종 확인한 환경 차이는 다음과 같았다.

환경파드 수문제 발견에 미친 영향
개발1개다른 파드로 요청이 분산되는 상황을 확인하기 어려움
스테이지1개운영과 같은 다중 파드 요청 흐름을 검증하기 어려움
운영2개요청 분산으로 세션 유지 문제에 노출될 수 있음

개발과 스테이지에서 정상 동작하더라도 운영의 요청 분산 상황까지 검증한 것은 아니었다. 기능 테스트뿐 아니라 실제 운영과 유사한 파드 구성에서의 검증이 필요했다.

수정 내용

상담 대상 확인 정보를 이미 Redis를 사용하는 BFF 로그인 세션에 저장하도록 변경했다.

세션을 없애고 Redis로 대체한 것이 아니라, 기존 Redis 기반 로그인 세션을 활용해 여러 BFF 파드가 같은 상담 정보를 확인하도록 한 것이다.

수정 후 흐름은 다음과 같다.

① 회원 검색
   Commerce에서 회원정보 조회

② BFF에서 상담 ID 발급
   로그인 세션에 ‘상담원 + 상담 ID ↔ 회원번호’ 저장
   해당 세션 정보는 기존 Redis 저장소에 보관

③ 목록·상세 조회
   BFF가 현재 로그인 세션에서 상담 ID 확인
   저장된 회원번호를 Commerce에 전달

④ 주문 조회
   Commerce가 해당 회원의 주문인지 확인한 뒤 응답

이 과정에서 다음 검증도 유지하거나 추가했다.

  • 화면에서 전달한 회원번호 대신 로그인 세션에서 확인한 회원번호를 사용한다.
  • 다른 로그인 세션이나 다른 상담원 계정의 상담 ID는 사용할 수 없도록 한다.
  • 회원번호가 없거나 0, 음수이면 조회 전에 거절한다.
  • 상세 조회에서는 주문번호와 회원번호가 함께 일치하는지 확인하는 기존 검사를 유지한다.
  • 상담 정보를 확인할 수 없으면 403 / 1914와 함께 **“회원정보를 다시 조회해 주세요.”**라는 오류를 반환한다.

화면이 상담 ID를 받아 다시 보내는 방식은 유지했으므로 FE 수정은 필요하지 않았다.

순차 배포를 위한 호환 처리

Commerce에는 BFF가 검증한 회원번호를 전달하는 내부 헤더 X-Counsel-Member-Id를 추가했다.

새 헤더가 있으면 해당 회원번호로 처리하고, 헤더가 없으면 기존 Commerce 세션에서 상담 ID를 검증하도록 했다. Commerce를 먼저 배포한 뒤에도 아직 업데이트되지 않은 BFF가 기존 방식으로 요청할 수 있기 때문이다.

배포 순서는 Commerce 전체 파드 배포 완료 → BFF 배포로 정했다. 전환 과정에서 기존 화면에 남아 있는 상담 ID는 새 방식과 호환되지 않을 수 있으므로 회원 재조회가 필요할 수 있다.

검증 결과

실제 Redis를 사용해, 한 BFF 역할의 객체가 저장한 상담 정보를 다른 BFF 역할의 객체가 동일한 로그인 쿠키로 조회할 수 있는지 확인했다. 다른 세션·계정의 상담 ID 차단, 회원번호 조작 방지, 구버전 요청 호환과 주문 소유권 검사도 테스트했다.

구분결과
BFF 전체 테스트16개 통과
Commerce 전체 테스트49개 통과, 기존 비활성 테스트 55개 건너뜀
이번에 추가한 테스트총 13개 통과

코드 수정과 테스트는 완료했다. 운영에서의 최종 해결 여부는 배포 후 여러 파드로 요청이 분산되는 상황에서 반복 조회하고, 동일한 403 오류가 재발하는지 확인해 판단한다.

재발 방지

  • 세션에 데이터를 저장하는 기능은 저장 위치와 파드 간 공유 여부를 함께 검토한다.
  • 배포 전 2개 이상의 파드에서 검색과 후속 조회가 서로 다른 파드로 전달되는 상황을 검증한다.
  • 오류 분석 시 요청 식별자, 처리 파드, 세션 식별값의 해시 등을 연결해 요청 흐름을 추적한다.
  • 상태 코드만 보고 원인을 묶지 않고, 상담 정보 검증 실패와 회원 검색 실패를 구분해 분석한다.

댓글

첫 번째 댓글을 남겨보세요.