같은 브라우저에서 정상적으로 로그인된것을 확인 후 새로고침을 누르자 로그인 화면으로 돌아갑니다. 웹앱이 두 대의 서버에서 각각 실행 중인 운영환경으로 보입니다. 이때는 새로고침 요청에 세션 쿠키가 실렸는지, 그리고 그 요청을 받은 서버가 세션을 찾았는지를 차례로 보면 점검 범위가 좁아집니다.

서버가 바뀌는 순간의 세션 조회
서버 측 세션을 사용하는 웹앱에서는 로그인 상태가 애플리케이션 서버의 저장소에 기록됩니다. 브라우저는 보통 쿠키로 세션 ID를 보내고, 서버는 그 ID로 로그인 상태를 조회합니다. 로그인 요청을 받은 A가 자기 메모리에만 세션을 저장했다면, 같은 ID가 B로 전달되어도 B의 메모리에는 해당 세션이 없습니다. 이때 앱은 요청을 미인증으로 처리해 로그인 화면으로 돌려보낼 수 있습니다. Spring Session — Spring Boot와 Redis 세션 저장
NGINX에서 라운드 로빈이나 최소 연결 방식으로 요청을 분산하면 한 브라우저의 연속 요청이 서로 다른 서버에 도착할 수 있습니다. 로그인 직후의 첫 화면이 열렸다면 그 요청이 A에서 처리됐을 가능성도 있습니다. 새로고침 요청의 처리 서버와 세션 조회 결과를 함께 봐야 가설을 확인할 수 있습니다. NGINX — HTTP 로드 밸런싱과 세션 고정

쿠키 전송과 서버 로그 대조
Chrome 개발자 도구의 Network에서 Preserve log를 켠 뒤 테스트 계정으로 로그인합니다. 인증 응답의 Headers에서 세션을 발급하거나 갱신한 Set-Cookie를 찾습니다. 로그인 직후와 새로고침 직후의 보호 페이지 요청에서 최종 발급된 세션 쿠키가 전송됐는지 Cookies 탭으로 확인합니다. 로그인 화면으로 이동했다면 리다이렉트를 처음 반환한 요청부터 봅니다. Chrome 개발자 문서 — Network 기능
쿠키가 빠졌다면 해당 요청의 호스트와 경로, HTTPS 사용 여부를 쿠키의 Domain, Path, Secure 속성과 대조합니다. 외부 인증 서비스가 끼는 등 사이트 간 이동이 있다면 SameSite의 전송 조건도 확인합니다. MDN — Set-Cookie 응답 헤더
쿠키가 전송됐다면 요청 ID를 기준으로 프록시와 앱 로그를 맞춰 봅니다. NGINX에서는 액세스 로그에 기록한 $upstream_addr로 연결 대상의 주소를 확인할 수 있습니다. 한 요청에서 서버 주소가 여러 개 기록됐다면 앱 로그와 대조해 어떤 인스턴스가 최종 응답을 만들었는지 확인합니다. 세션 쿠키 원문은 로그에서 빼고, 요청 ID와 인스턴스 이름, 세션 조회 결과를 남겨 비교합니다. NGINX — upstream 변수
예를 들어 같은 세션 쿠키를 보낸 /mypage 요청이 A에서 200으로 끝나고, 새로고침 요청은 B에서 로그인 화면으로 보내는 302를 반환했다고 가정해 보겠습니다. B의 앱이 쿠키를 받았는지 확인한 뒤, 세션 저장소 조회에 오류가 났는지, 조회는 됐지만 세션이 없었는지 구분합니다. 세션이 없고 두 서버가 각각 로컬 메모리를 쓴다면 저장 범위로 증상을 설명할 수 있습니다. 같은 서버에서도 세션이 사라진다면 만료 시각과 프로세스 재시작 기록을 먼저 대조합니다.

세션 고정과 공용 저장소의 선택 기준
세션 고정은 같은 클라이언트의 요청이 같은 서버로 가도록 분산 방식을 조정합니다. 예를 들어 NGINX의 ip_hash는 클라이언트 IP를 기준으로 서버를 선택합니다. 해당 서버를 사용할 수 없거나 접속 IP가 바뀌면 다른 서버로 갈 수 있습니다. 서버 재시작으로 메모리 세션이 사라지는 경우도 고려해야 합니다. NGINX — HTTP 로드 밸런싱과 세션 고정
서버가 바뀌어도 로그인을 유지해야 한다면 여러 인스턴스가 같은 세션을 읽고 쓸 수 있는 구성이 필요합니다. Spring Session의 Redis 연동이 한 예입니다. 이미 공용 저장소를 사용 중이라면 각 서버가 같은 저장소와 세션 키 접두사(네임스페이스)를 쓰는지, 세션 만료 설정이 일치하는지, B의 조회 시점에 접속 오류가 있었는지 확인합니다. Spring Session — Spring Boot와 Redis 세션 저장
결론
로그인 화면이 다시 뜬 요청에서 쿠키 전송 여부, 응답을 만든 서버, 세션 조회 결과를 차례로 확인합니다. 서버가 바뀌어도 로그인 상태를 유지해야 한다면 검증 환경에서 처음 로그인한 서버를 분산 대상에서 제외합니다. 이후 같은 쿠키로 보호 페이지를 열고, 다른 서버가 기존 세션을 읽어 정상 응답했는지 확인합니다.