티스토리 뷰

최근 외부업체와의 통신 중에 아래와 같은 오류가 매우 자주 발생하는 것을 확인 할 수 있었습니다.

The target server failed to respond

먼저 본문 포스트를 작성 하기 전에 위의 오류에 대한 해결은 아직 하지 못하였으며 아래는 HTTP/1.0, HTTP/1.1 에 관한 간략한 내용을 담는 글이라고 먼저 말씀드립니다. 해당 오류가 해결이 된다면 바로 본문 게시글을 수정하도록 하겠습니다.

The target server failed to respond.

해당 오류는 HttpClient 방식을 통해 통신을 하는 중에 발생을 하였으며, 발견 당시 해당 오류에 대한 검색을 해보았습니다.

그러던 중 접한 정보가 HTTP 통신 규약인 HTTP/1.0 과 HTTP/1.1 입니다. 


아래 해당 내용에 대해 작성하기 전 가장 의심이 가는 부분으로 의심되는 부분을 아래의 사이트에서 발견하였으며 정리를 간략히 해보도록 하겠습니다. ( 출처 : http://www.yunsobi.com/blog/i/entry/660 )


* 이하 말을 좀 편하게 하겠습니다. (__)


1. HttpClient 통신은 Default 가 HTTP/1.1 방식이다.

2. HTTP/1.1 방식이기 때문에 어느정도 Keep-Alive 가 보장된다.

3. Keep-Alive 가 보장되는 상태에서는 아래와 같은 사유로 위의 오류를 발생할 수 있게 된다.

3-1. Client 가 Server 와 Connection 을 생성하여 Request 를 보냄

3-2. Server 에서는 Client 의 요청을 처리하여 응답 후 Close 함


문제는 3-2 의 상황 이후에 발생하게 된다. 

3-2 상태로 남아있는 Server 측의 Close 상태에 대한 의미는 소켓 단절이 아닌 `더 이상 보낼 데이터가 없습니다.` 라는 상태이며 Client 측에서는 Connection 을 단절하지 않는 이상 해당 Connection 을 통하여 Server 로 부터 계속해서 데이터를 인입시킬 수 있다는 것이다. 이 상황을 Half-closed connection 으로 표현하며 TCP 가 이렇게 동작하게끔 설계되어 있으며 버그가 아니다. 그리고 이런 상황이 발생하게 되면 Client 의 JVM 상의 Connection 객체는 살아 있지만 내부소켓은 CLOSE_WAIT 상태가 된다. 이 상황에서 HttpClient 가 CLOSE_WAIT 상태인 이 Connection 객체를 다시 사용하려고 하면 서버측은 이미 연결이 끊긴 상태이기 때문에 해당 오류가 발생되게 되는 것이다. 

출처에 있는 글을 그대로 담아오다 보니 말이 조금 어려워 진 듯 한데 간단히 정리하면 이렇지 않을 까 싶다.


1. CLIENT -> SERVER 로 통신을 위한 CONNECTION 생성

2. SERVER -> CLIENT 로 응답. SERVER 측은 CLOSE, CONNECTION 내부소켓은 CLOSE_WAIT 상태. CONNECTION 은 살아있음. (이해하기 쉽게 SERVER 측에서는 해당 연결을 끊었다고 보면 될 듯.)

3. CLIENT -> SERVER 로 요청보냄 (Keep-Alive 로 인해 동일host:port에 대해 이전과 동일한 CONNECTION 객체를 사용하려하기 때문에 1번에서 생성한 CONNECTION 을 사용하려 함)

4. CLOSE_WAIT 상태인 CONNECTION 객체를 사용하여 SERVER 와의 통신을 시도하지만 이미 서버에서는 연결을 끊은 상황이기에 오류 발생.



이렇기 때문에 해당 문제해결을 위해서는 통신완료된 CONNECTION 객체에 대해 쌓이지 않게 적절하게 제거해야 한다고 명시되어 있습니다. 해당 방법과 해결에 대해서는 본문 처음에 얘기한 대로 조치가 완료되면 업데이트 하도록 하겠습니다. 


다음으로 HTTP/1.0, HTTP/1.1 에 대해서 얘기해보도록 하겠습니다.

먼저, 위에서 계속해서 야기되고 뭔가 문제의 포인트라고 할 수 있는 Keep-Alive 란 HTTP/1.1 에 적용 된 


매 Connection 마다 open, close 를 하지않고 timeout 동안은 Connection 을 Close 하지 말자


​라는 것으로 HTTP/1.0 과의 다른 특징 중 하나이며 각각의 특징 및 장단점을 정리하자면 아래와 같습니다.

아래 내용들의 출처는 http://pchun.tistory.com/60 과 http://blog.naver.com/joebak/220442865840 이며 나름 이해할 수 있게 정리한 것입니다.


** HTTP/1.0 

- client - server 1:1 개념

- 무조건 연결하고 끊는다. (connection less - 매번 socker(port) 를 열고 끊음.) 

- throughput 이 제대로 안나옴.

- TIME_WAIT 발생 

 -> EX) A 회사에서 B 회사로 API 호출 시 A 회사 사이트에 같은 서버로 5명의 사용자가 붙어서 동일 API 호출 시

   5번째 사용자는 앞의 4번째 사용자들의 호출이 끝나야 호출 가능.

   A 회사가 client

   B 회사가 server 가 되는.

- 호출 시 마다 open 해야하고 접속, 재접속으로 인해 서버 과부하 및 TCP HandShake 비용이 많아짐


** HTTP/1.1

- client - server  n:1 개념 (같은 IP로 여러 요청이 동시에 들어 올 수 있는 점을 감안)

- keep-alive : 매 connection 마다 open, close 하는게 아니라 지정한 timeout 동안은 close 하지 않는 방식

- Keep-alive 를 사용하는 의미를 크게 만들기 위해선 NIO 방식인 Nginx 를 사용해야 한다고 함

- Apache 의 경우에는 매 커넥션마다 thread 를 생성하기 때문에 Persistent Connection 의미가 사라짐.


** 추가로 http://pchun.tistory.com/60 님의 블로그에서 본 The target server failed to respond 해결에 관한 방법 및 장단점을 옮겨 적어보도록 하겠습니다.


1. cilent 측에서 http/1.0 으로 연결

 -> keep-alive 를 하지 않기에 http/1.0 의 단점을 고스란히 안음

2. httpclient 를 제한적으로 사용

 -> httpclient warpping 하는 하나의 클래스를 만들어 그 클래스에서 싱글톤 패턴을 이용하여 필요한 곳에서 호출하도록.

 -> 스레드 환경에서 한번에 여러군데 접속하고 싶을 때 문제가 발생

 -> MultiThreadedHttpConnectionManager 를 사용

 -> MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

 HttpClient client = new HttpClient(connectionManager);

  

MultiThreadedHttpConnectionManager 에 따른 몇가지 옵션은 필요에 따라서 조절. 이렇게 하면 CLOSE_WAIT 상태가 계속해서 누적되지 않음.


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
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
글 보관함