준호씨의 블로그

Nginx 응답 - Http Status 499 Client Closed Request. 비동기 처리할 땐 조심히 본문

개발이야기

Nginx 응답 - Http Status 499 Client Closed Request. 비동기 처리할 땐 조심히

준호씨 2021. 5. 18. 00:11
반응형

오류를 디버깅을 하면서 kibana에 기록된 ingress로그에서 Http Status가 499로 찍혀 있는 것을 보게 되었습니다.

499가 무엇인가 찾아보니 표준 상태 값은 아니고 nginx에서 정의한 값입니다.

 

499 Client Closed Request — httpstatuses.com

 

httpstatuses.com

페이지로 가면 설명이 있습니다.

클라이언트가 nginx에 무언가 요청을 했는데 nginx에서 요청을 처리하고 있는 도중에 클라이언트가 접속을 끊어 버리면 nginx는 499 상태 값으로 오류 로그를 남기는 것입니다.

결국 찾아낸 원인은 요청하는 곳에서 WebFlux의 WebClient를 이용해서 비동기로 요청을 날렸는데 결과를 받기 전에 접속을 끊어 버렸기 때문이었습니다.

대충 어떻게 되어 있던 코드냐 하면 대충 다음과 같습니다.

@PostMapping("...")
public Mono<...> something(@RequestBody ...) {
  return ...
    .flatMap(data -> {
      Mono<...> result1 = ... // nginx 서버로 요청
      Mono<...> result2 = ... // 다른 서버로 요청
      return Mono.zip(result1, result2);
    })
    .flatMap(res -> Mono.just(ApiResponse.ok()))
    ;
}

어떤 요청을 받아서 다른 서버에 요청 보내고 끝나는 코드인데요.

result1, result2를 받아온 결과로 뭔가 처리할 거 같은 느낌이지만 실상은 결과를 따로 참조하고 있지 않기 때문에 결과를 받아오기도 전에 ApiResonse.ok() 응답을 날리고 종료해 버립니다.

그나마 499 오류 로그라도 찍혀 있으면 요청이 가기는 갔는데요. 너무 빨리 넘어가 버리면 요청 자체가 안 날아가는 문제가 생겼습니다. 요청이 가기도 전에 응답해 버리고 끝나 버리는 것이지요.

비동기로 코드를 작성할 때는 조심하는 것이 좋겠습니다. 저도 아직 어떻게 하는 것이 좋은 방법인지는 잘 모르겠지만 처리한 결과를 사용하도록 코드를 만들면 결국 다 실행되고 응답할 테니 그렇게 하는 것이 맞겠죠?

그게 이상하다면 차라리 순서대로 처리하도록 then 같은 것을 사용하도록 해야 되겠습니다.

 

반응형
Comments