본문 바로가기
Software Architect/SWA 이야기

ClientAbortException, Broken pipe가 발생하는 이유

by romainefabula 2026. 1. 7.

시스템 로그를 보다 보면 ClientAbortException이나 Broken pipe 같은 오류가 찍혀 있는 경우가 있다. 이것이 왜 발생하고 어떻게 대응해야 하는지 알아보려고 한다.

 

클라이언트와 서버 사이의 연결, 요청, 응답 수행 과정

 

클라이언트와 서버는 위 그림과 같은 과정을 통해 연결을 수립하고, 요청을 보내고 응답을 받는다.

1. 클라이언트에서 서버에 연결을 요청한다.

2. 서버가 연결요청을 받고 그에 대한 수락 응답을 보낸다.

3. 클라이언트가 서버에 요청 데이터를 보낸다.

4. 서버가 요청 데이터를 분석하고, 그에 대한 처리(DB에 대한 CRUD, 외부 인터페이스 호출 등)를 수행한다.

5. 2번에서 수립된 연결을 통해서 서버가 클라이언트에게 처리결과를 전송한다.

 

ClientAbortException이나 Broken pipe가 발생하는 시점

이렇게 1번부터 5번까지 잘 처리되면 좋은데, 클라이언트가 서버에 요청전송을 완료(3번이 끝나고)한 후와 서버의 처리결과를 클라이언트로 전달하기 시작하기 직전(5번 전) 사이에 2번에서 수립된 연결이 끊어지면 ClientAbortException이나 Broken pipe가 발생한다.

즉, 클라이언트의 요청을 모두 받고 그에 대한 처리가 끝나서 클라이언트에 결과를 보내야 하는데, 이 응답을 실어보낼 연결이 사라져 버려서 ClientAbortException(클라이언트가 연결을 중지했다)이나 Broken pipe(결과를 부어 넣을 파이프가 깨졌다)가 발생한다.

 

클라이언트가 연결을 끊는 일은 어떻게 발생할까?

1. 클라이언트가 웹브라우저라면 버튼 등을 눌러 서버에 요청을 보낸 후에, 응답이 오기 전에 다른 화면으로 이동하거나 리프레쉬 등을 수행해서 페이지가 바뀌면 웹브라우저는 자동으로 이전에 요청을 보냈던 연결을 끊는다.

2. 클라이언트에 연결생성시 Read Timeout 값이 설정되어 있으면, 클라이언트가 요청을 보내고 Read Timeout 시간까지 응답이 오지 않으면 ReadTimeout이 발생하면서 연결이 끊긴다.

 

막는 방법은 없을까?

1. 서버의 요청처리시간을 최소화한다.

결국은 클라이언트에선 어느 정도 기다리다가 응답이 늦어져서 연결을 끊었을 가능성이 높다. 그러니까, 서버의 처리시간(DB처리, 인터페이스 호출 등)을 최소화하면 클라이언트에서 연결을 끊을 확률이 줄어든다.

2. 클라이언트가 화면이라면 버튼을 누르기 전이나 후에 응답이 오래 걸린다고 알린다.

서버의 처리에 시간이 오래 걸리고 더 이상 줄일 수 없는 경우라면 서버의 요청처리가 오래 걸린다고 화면에 보여 준다. 사용자가 다른 화면으로 이동하지 않기를 바라면서...

3. 클라이언트가 소스코드라면 Read Timeout 값을 늘린다.

클라이언트의 Read Timeout 값을 서버에서 처리에 필요한 최대시간보다 크게 늘린다.

4. 위의 1,2,3까지 해도 발생하는 ClientAbortException이나 Broken pipe는 무시할 수밖에 없다. 이렇게 해도 클라이언트가 연결을 끊으면 막을 방법은 없다.

 

(문제가 없는 거라고) 관리자를 설득하는 방법

더이상 서버처리시간을 줄일 수 없는데 사용자가 자꾸 ClientAbortException이나 Broken pipe를 발생시키고 관리자는 이게 문제가 아니냐고 계속 물을 수 있다. 이럴 때는 똑같은 상황을 재현해야 한다.

서버 로그파일을 tail로 열어 놓은 상태에서 화면에서 요청 후 페이지를 이동하거나 리프레쉬해서 연결을 끊는다. 이때 로그가 찍히진 않는다. 서버에서 요청을 모두 처리하고 결과를 클라이언트로 보내기 시작하려는 시점에 연결이 이미 끊어져 있기 때문에ClientAbortException이나 Broken pipe 로그가 찍힌다. 이 로그가 찍히는 것을 같이 확인하면 된다.

 

마지막으로 알아 두어야 하는 할 것(모두 알고 있겠지만)

클라이언트가 요청하고 연결을 끊더라도 서버에서 요청을 받으면 그에 대한 처리는 모두 수행한다. 연결이 끊겨서 클라이언트로 응답을 못 보내 줄 뿐이다. 그러므로, 연결을 끊었던 요청이 CUD라면 다시 요청하기 전에 이전의 요청결과를 먼저 확인해야 한다.