2시 배포, 3시 오픈, 그리고 장애
FlashAttribute를 세션에 의존한 구조가 다중 WAS에서 랜덤 장애를 만들었다.
쓱클럽 가입 프로세스를 맡아 개발한 뒤, 2시 반 배포를 마치고 3시 오픈을 앞둔 시점에 운영환경에서 가입 버튼이 랜덤으로 실패했다.
정상적으로 SSGPAY 비밀번호 입력창이 뜨다가도 에러 페이지로 넘어가고, 새로고침도 하지 않았는데 결과가 들쭉날쭉했다. 로컬과 사내 테스트 서버에서는 재현되지 않았고, 문제 지점은 Gate 페이지에서 Register 페이지로 넘어가는 구간이었다.
흐름은 다음과 같았다.
- Front 가입 화면에서 사용자의 SSGPAY 정보를 POST로 전달
- redirect로 register 페이지 이동
- FlashAttribute로 데이터를 전달
- Register 페이지에서 @ModelAttribute로 수신한 뒤 결제 등록 화면으로 이동
처음에는 화면 새로고침 시 재전송 경고를 피하고, 쿼리파라미터로 개인정보가 노출되지 않게 하려는 의도였다. 하지만 FlashAttribute는 내부적으로 세션을 쓰기 때문에, 운영 환경처럼 다중 WAS로 구성된 곳에서는 문제가 생겼다.
POST /gate가 서버 A에서 처리되고, redirect된 GET /register가 서버 B로 가면 세션에 저장된 FlashAttribute가 없어진다. 그 결과 어떤 요청은 정상, 어떤 요청은 에러로 끝나며 운영에서는 랜덤 장애처럼 보였다.
더 큰 문제는 이 화면이 실제로 오래 머무는 페이지가 아니라, 진입 직후 form을 submit하고 다음 단계로 넘어가는 브릿지 페이지였다는 점이다. 즉, redirect와 FlashAttribute, 세션 의존 자체가 필요 없는 설계였다.
수정 후 구조는 훨씬 단순해졌다.
- POST로 Gate 페이지를 호출
- 바로 화면을 렌더링
- 페이지 진입 즉시 다음 단계로 자동 submit
이제는 redirect도 없고, FlashAttribute도 없고, 세션 의존도 없다. 덕분에 구조는 단순해졌고, 운영 환경에서도 안전해졌다.
결국 배운 점은 분명하다. 깔끔해 보이는 구조와 운영에서 안전한 구조는 다를 수 있고, 사용자가 잠깐 스쳐 가는 화면이라면 그 페이지에 과한 의미를 부여하지 않는 편이 낫다.
이 요약은 원문 이해를 돕기 위한 큐레이션입니다. 저작권은 원저작자에게 있으며, 정확한 내용과 맥락은 원문을 확인하세요.
요약 오류, 출처 표기 문제, 삭제 요청은 문의 · 건의로 알려주세요.