일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Spring
- kotlin
- CloudWatch
- 오블완
- PETERICA
- kotlin spring
- CKA 기출문제
- IntelliJ
- kotlin querydsl
- AI
- Java
- kotlin coroutine
- 기록으로 실력을 쌓자
- Linux
- Kubernetes
- AWS EKS
- 정보처리기사 실기 기출문제
- aws
- 코틀린 코루틴의 정석
- 공부
- 티스토리챌린지
- MySQL
- Elasticsearch
- APM
- CKA
- 정보처리기사실기 기출문제
- mysql 튜닝
- Pinpoint
- 정보처리기사 실기
- minikube
- Today
- Total
피터의 개발이야기
[Spring Gateway] 308 영구 리다이렉션 병목현상 해결 본문
ㅁ 개요
Spring Cloud Gateway 로그 상에서 308 PERMANENT_REDIRECT 상태 코드가 지속적으로 발견되었다. 이를 모니터링하고 원인을 분석하는 과정을 정리하였다.
ㅁ Http status Code
Http Status Code는 크게 다섯 가지 HTTP 상태 코드 범주(또는 클래스)가 있다. 각각은 서버에서 브라우저로의 다른 응답을 나타낸다.
- 1XX — 정보 코드 : 서버가 요청을 확인하고 처리 중이다.
- 2XX — 성공 코드 : 서버가 요청을 성공적으로 수신, 처리하였다.
- 3XX — 리디렉션 코드 : 서버가 요청을 받았지만 다른 곳으로 리디렉션된다.
- 4XX — 클라이언트 오류 코드 : 서버가 페이지 또는 웹사이트를 찾을 수 없거나 연결할 수 없다. 이것은 사이트 측의 오류이다.
- 5XX — 서버 오류 코드 : 클라이언트가 유효한 요청을 했지만 서버가 요청을 완료하지 못하였다.
ㅁ 30X : Redirection messages
CODE | NAME | DESC | |
300 | Multiple Choice 여러 선택항목 |
선택 항목이 여러 개 있다. 지정한 URI에 대해서 콘텐츠 협상을 수행한 결과 서버에서 콘텐츠를 결정하지 못하고 클라이언트에게 복수 개의 링크를 응답할 때 사용한다.클라이언트는 요청을 마치기 위해 추가 동작을 취해야 한다. |
|
301 | Moved Permanently 영구 이동 |
지정한 리소스가 새로운 URI로 이동하였다. 이동할 곳의 새로운 URI는 응답 헤더 Location에 기록합니다. |
|
302 | Found 다른 위치 찾음 |
요청한 리소스를 다른 URI에서 찾았다. 요청한 URI가 없으므로 클라이언트 메소드를 그대로 유지한 채 응답 헤더 Location에 표시된 다른 URI로 요청을 재송신할 필요가 있다. 302의 의미를 정확하게 개선해서 307을 정의하였으므로 이 응답 코드의 사용은 권장하지 않는다. |
|
303 | See Other 다른 위치 보기 |
다른 위치로 요청하라. 요청에 대한 처리 결과를 응답 헤더 Location에 표시된 URI에서 GET으로 취득할 수 있습니다. 브라우저의 폼 요청을 POST로 처리하고 그 결과 화면으로 리다이렉트시킬 때 자주 사용하는 응답 코드이다. |
|
304 | Not Modified 수정되지 않음 |
마지막 요청 이후 요청한 페이지는 수정되지 않았다. If-Modified-Since와 같은 조건부 GET 요청일 때 지정한 리소스가 갱신되지 않았음을 알려 준다. 이 응답 코드에는 바디가 없다. |
|
305 | Use Proxy 프록시 사용 |
지정한 리소스에 액세스하려면 프록시를 통해야 한다. 응답 헤더 Location에 프록시의 URI를 기록한다. |
|
306 | Unused 미사용 |
예전 버전에서 사용하다가 현재는 사용하지 않는 상태 코드이다. | |
307 | Temporary Redirect 임시 리다이렉션 |
임시로 리다이렉션 요청이 필요하다. 요청한 URI가 없으므로 클라이언트 메소드를 그대로 유지한 채 응답 헤더 Location에 표시된 다른 URI로 요청을 재송신할 필요가 있다. 클라이언트는 향후 요청 시 원래 위치를 계속 사용해야 한다. 302의 의미를 정확하게 재정의해서 HTTP/1.1의 307 응답으로 추가되었다. |
|
308 | Permanent Redirect 영구 리다이렉션 |
이것은 리소스가 이제 HTTP 응답 헤더의 Location:에 명시된 영구히 다른 URI에 위치하고 있음을 의미한다. 이것은 301 Moved Permanently HTTP 응답 코드와 동일한 의미를 가지고 있으며, 사용자 에이전트가 반드시 HTTP 메소드를 변경하지 말아야 하는 점만 다르다. 만약 첫 요청에 POST가 사용되었다면, 두번째 요청도 반드시 POST를 사용해야 한다. |
3xx HTTP 상태 코드란 재지정 그룹에 속한다. 예를 들어 페이지를 보려고 링크를 클릭하면 브라우저가 서버에 연결을 요청한다. 서버는 이에 대해 응답을 돌려보낸다. 이 때 원하는 웹사이트가 이전을 하는 등 문제로 존재하지 않는다면 서버는 “당신이 원하는 페이지는 여기에 없으니 어디로 이동해라”는 응답을 내보낸다.
301 | 302 | 307 | 308 | |
Permanent(영구성) | O | X | X | O |
Same Method | X | X | O | O |
URL이 리다이렉트 되었을 때, 최초의 요청 방법 (GET or POST)을 유지하지 않고 무조건 GET으로 변경시키면서 리다이렉트 시키는것이 301 또는 302이고, 원래의 method (GET, POST)를 유지하면서 리다이렉트 시키는 것이 307 또는 308이다. 이중에서 "308 Permanent Redirect"은 임시가 아니라 영원히 리다이렉트 되었다는 의미이다.
ㅁ Gateway와 Front서버의 병목현상 확인
Gateway trace 로그에서 308 영구 리다이렉션이 지속적으로 발생하였다. 무한 리다이렉션으로 인해 처리속도(elapsed_time)이 1초 이상 소요되는 상황이 발생하였다.
Request failed with status code 404
at createError (node_modules/axios/lib/core/createError.js:16:15)
at settle (node_modules/axios/lib/core/settle.js:17:12)
at Unzip.handleStreamEnd (node_modules/axios/lib/adapters/http.js:269:11)
at Unzip.emit (node:events:394:28)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
Front 서버에서도 에러코드가 발생하고 있었고, 시간이 지날수록 무한 리다이렉션이 중첩되면서 응답속도는 더욱 늦어졌다. 그래서 2시간이 지나면 개발 FrontEnd 서버를 재기동 해야만 했다.
ㅁ 무한 루프의 고리를 찾아서...
Spring Cloud Gateway에서는 authentication 모듈과 통신하여 토큰을 체크하고 없는 경우 로그인페이지로 리다이렉션을 시키고 있는데, 일부 Front에서 호출하는 API에서 토큰 정보가 없었다.
Front Main(토큰정보 없음) 요청 -> Gateway Redirection -> Front Main(토큰정보 없음) 요청 gateway
결국 요청을 주는 Front 소스를 확인한 결과, API 호출 후 Exception에 대한 catch문이 없었다. 다시 말해 Http Status 308에 대한 방어 로직이 되어 있지 않아 다시 Gateway에 요청을 보내면서 무한 리다이렉션이 발생하였다.
'Programming > Spring' 카테고리의 다른 글
[Spring]Testcontainers란 무엇입니까? (2) | 2024.01.23 |
---|---|
[Spring] Hateoas(헤이티오스)란 (0) | 2023.08.08 |
@NotNull @NotEmpty @NotBlank (0) | 2023.06.22 |
[MacOS M1] DNS resolutions Error에 대한 Jar 설정 (0) | 2023.04.24 |
[Spring log4j] EFS에 error 로그 기록 시 AppenderLoggingException 처리 (0) | 2022.12.14 |