Skip to content

슬랙 메세지 발송 실패 이슈 트러블 슈팅

Jungseok Sung edited this page May 15, 2024 · 1 revision

상황

예전부터 간헐적으로 슬랙 메세지 발송 중 Connection prematurely closed BEFORE response 에러가 발생했다.

log detail

로그를 보면 슬랙 서버와의 http 통신 중 찜꽁 서버에서 request 를 보냈지만, 모종의 이유로 인해 슬랙 서버로 부터 response를 받지 못하고 연결이 끊긴 상황으로 보였다. 관련해서 구글링 해보니 reactor netty docs 에 친절하게 트러블 슈팅 가이드가 있었다. 해당 가이드라인을 따라 트러블 슈팅을 진행해보았다.

액션

정확한 원인 파악을 위해서는 TCP dump 를 떠보아야 했다. 서버에 tcpdump 를 걸어놓고 에러가 재발생하기를 기다렸다. 그리고 동일한 에러가 재현되고 나서 곧바로 Wireshark 로 패킷을 분석해보았다.

tcpdump_keepalive

위 스크린샷은 에러와 관련된 패킷 통신들이다. 파란 영역을 보면 총 3번의 keep-alive check (interval 1분) 가 있었음을 확인할 수 있다. 그리고 마지막 keep-alive check 후 2초 정도 뒤 Request (Slack Message Web Hook API Request) 가 가게된다 (No. 4325). 하지만, 슬랙 서버 (35.74.58.174) 는 RST 패킷을 통해 connection 을 reset 하는 부분을 확인할 수 있다.

추정컨데 슬랙 서버는 총 3번정도의 keep-alive check 동안 idle 하다면 강제로 connection을 끊어버리는 것으로 보인다 (이와 관련해서 슬랙측이 공식적으로 명시한 부분은 찾지 못했지만 정황상 그렇게 추정된다). 하지만 찜꽁 서버는 connection idle timeout 관련 설정을 딱히 해주지 않았기 때문에 끝까지 connection 을 유지하고 있다 (reactor netty 의 maxIdleTime default 설정). 그러므로 찜꽁 서버는 connection을 아직 맺고있다고 생각해서 request 를 보냈지만, 슬랙 서버 입장에서는 모르는 (이미 끊어버린) 커넥션으로부터의 request 이므로 RST 패킷을 통해 connection reset 을 요구하게 되는 것이다.

관련 현상을 구글링 해보면 WebClient 사용 시 꽤나 흔하게 발생하는 상황으로 보였다. 여러 글들을 종합적으로 검토하여 적절한 WebClient config 를 세팅해주었다. 설정 세팅 중 핵심은 슬랙 서버측의 connection idle timeout (3분으로 추정) 보다 짧게 찜꽁측 connection idle timeout을 설정해주는 것이다.

결과

PR 적용 이후로 지속적으로 모니터링 중이다. 한달에 3 ~ 4번 꼴로 발생하던 Connection prematurely closed BEFORE response 가 더 이상 발생하지 않는 부분을 확인했다.

참고 자료

Clone this wiki locally