ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RestTemplate & URLConnection
    Back-end Developer/Server, Spring 2020. 10. 30. 18:57

    이번 공모전을 진행하며 사용한 URLConnectionRestTemplate에 대해 정리합니다.

    위의 두 가지 클래스를 살펴보기 전에 우선 HTTP 특징에 대해 알고 가는 것이 좋습니다.

     


    HTTP

    HTTP(HyperText Transfer Protocol)는 W3 상에서 정보를 주고받을 수 있는 프로토콜이다. 주로 HTML 문서를 주고받는 데에 쓰인다. 주로 TCP를 사용하고 HTTP/3 부터는 UDP를 사용하며, 80번 포트를 사용한다. 1996년 버전 1.0, 그리고 1999년 1.1이 각각 발표되었다.

    HTTP는 클라이언트와 서버 사이에 이루어지는 요청/응답(request/response) 프로토콜이다. 예를 들면, 클라이언트인 웹 브라우저가 HTTP를 통하여 서버로부터 웹페이지(HTML)나 그림 정보를 요청하면, 서버는 이 요청에 응답하여 필요한 정보를 해당 사용자에게 전달하게 된다. 이 정보가 모니터와 같은 출력 장치를 통해 사용자에게 나타나는 것이다.

    HTTP를 통해 전달되는 자료는 http:로 시작하는 URL(인터넷 주소)로 조회할 수 있다.

     

    (출처 wiki)

     

    특징

    • HTTP 메시지는 HTTP 서버와 HTTP 클라이언트에 의해 해석이 된다.
    • TCP/ IP를 이용하는 응용 프로토콜이다.
    • HTTP는 연결 상태를 유지하지 않는 비연결성 프로토콜이며 요청/응답 방식으로 작동한다.

     

    우리가 주목해야할 점은 HTTP의 비연결성입니다.

    HTTP는 불특정 다수의 통신 환경을 기반으로 설계되었습니다.

    자주 사용하지 않는 서버에서 다수의 클라이언트와 계속 연결을 유지하는 것은 낭비가 되겠죠.

    따라서, 연결을 매번 끊어주어 더 많은 연결을 할 수 있도록 의도합니다.

     

    하지만, 지속적으로 접근해야하는 리소스는 어떨까요?

    매번 새로운 연결을 시도/해제의 과정을 거쳐야하므로 연결/해제에 대한 오버헤드가 발생합니다.

     

    이를 보완하기 위해 HTTP에서는 Keep-alive 방식을 도입합니다.

     

     


    HTTP Keep-alive

    HTTP 지속적 연결 상태, HTTP 영구 접속(HTTP persistent connection) 또는 HTTP 킵얼라이브(HTTP keep-alive), HTTP 연결 재사용(HTTP connection reuse)은 하나의 TCP 연결을 사용하여 복수의 HTTP 요청/응답을 주고받는다는 개념으로, 매 요청/응답 쌍마다 새로운 요청을 여는 것과는 반대되는 개념이다. 더 새로운 HTTP/2 프로토콜은 동일한 개념을 사용하며 더 나아가 하나의 연결 복수의 동시 요청/응답을 다중화하는 것이 가능하다.

     

    (출처 wiki)

     

    저희 팀이 개발한 서비스는 고정된 Open-API에 지속적으로 접근해야 했습니다.

    따라서 URLConnection을 통해 통신을 구성하고, Keep-alive 설정을 고려했습니다.

     


    URLConnection

    jdk1.0 이후 Java Object 하위 net 패키지에 포함되어있다. 일반적으로 URL 주소에 GET, POST로 데이터를 전달 할 때 사용한다. 즉, 하위 클래스가 사용자 애플리케이션과 웹의 모든 리소스 사이의 링크를 형성하는 추상 클래스다. URL 객체에 참조된 모든 리소스를 읽고 쓰는 데 사용할 수 있다.

     

    (출처 java docs, geeksforgeeks)

     

    특징

    1. JAVA에서 기본적으로 제공하는 URLConnection은 Connection pool을 사용하지 않습니다.
    2. 대상이 헤더에 “Connection : keep-alive”를 포함하면, connection을 살려두고 재사용합니다. (단, 이 경우 명시적으로 connection을 닫아야함)
    3. URLConnection 객체를 재사용 할 수 없습니다.
    4. 응답코드가 4xx 거나 5xx 면 IOException이 발생합니다.
    5. 타임아웃을 설정할 수 없습니다.
    6. 쿠키 제어가 불가능합니다.

    이렇게 URLConnection을 통해 Keep-alive 설정하는 방법도 가능했습니다.

    하지만, 서비스 특성 상 connection pool을 통해 관리할 수 있고, 좀 더 간결하고 REST하게 구성할 수 있는 RestTemplate을 사용하기로 결정했습니다.

     

    RestTemplate도 관련해서 간단하게 살펴보겠습니다.

     


    RestTemplate

    Spring 3.0 이후 http(web).client 패키지에 포함. HTTP 요청을 Json, xml, String 과 같은 응답으로 받을 수 있는 동기식 템플릿 메소드 API. 일반적인 HTTP 메소드 시나리오에 필요한 템플릿 및 부가적인 덜 사용되는 부분에 대한 템플릿도 제공.

     

    (출처 Spring docs)

     

    RestTemplate 동작 방식

    RestTemplate flow

     

    1. Application: RestTemplate 생성 및 URI, HTTP메소드 등의 헤더 설정 후 요청.
    2. RestTemplate: requestEntity 변환 -> Request Message [start line + header + body] (by. HttpMessageConverter)
    3. RestTemplate:  ClientHttpRequest(from. ClientHttpRequestFactory)를 통한 요청
    4. ClientHttpRequest: Request Message 생성 및 HTTP 프로토콜을 통한 서버와 통신.
    5. RestTemplate: ResponseErrorHandler를 통한 오류 확인 및 처리 로직 적용.
    6. 오류 존재시 -> ResponseErrorHandler: 응답데이터(from. ClientHttpResponse)를 가져와 처리.
    7. RestTemplate: Request Message 변환 -> Java Object [class response type] (by. HttpMessageConverter)
    8. Application에 반환

    (출처 빨간색코딩님의 블로그)

     

     

     

    특징

    1. RestTemplate 또한 Connection pool을 사용하지 않습니다. (custom Connection pool 구현)
    2. 추상화된 HttpClient를 이용해 구현합니다. (Http Request 지원)
    3. ResponseEntity와 Server to Server 통신을 하거나 외부 API 호출시에 사용합니다.
    4. 비동기는 AsyncRestTemplate로 제공합니다.

     

    Connection Pool을 사용하는 이유는 지속적인 연결/해제 과정을 최소화 하고 성능상의 이점을 가져오기 위함입니다.

    (위의 http의 단점을 보완하기 위한 것이라 생각하시면 됩니다.)

     

    연결 설정을 한번 한 후 지속적으로 같은 연결을 가져다 쓰기만 하면 되니 상당히 빠르겠죠.

    String Pool 개념과 유사하게 보시면 되겠습니다.

     

    실제로 초기엔 URLConnection을 이용해 데이터를 가져왔고, 이후 RestTemplate을 사용했습니다.

    바꾸게된 원인은 stackoverflow를 보고 고민해본 결과가 가장 영향이 컸습니다.

     

    물론 개인적으론 코드의 비즈니스 로직이 상당히 간결해 졌고, 관심사가 조금씩 분리가 되어 정리 되는 느낌이 들었습니다.

    특히, Open-API 연결 코드의 try-with-resources/try-catch 구문이 상당히 간소화되었습니다.

    (성능상으론 조금 더 느려지긴 했는데 실제로 조금 느리다는 의견이 있네요.)

     

    실시간으로 빠르게 요청/응답이 필요하시다면, URLConnection을 통해 구성해 보시는 것도 좋은 방법일 것이라 생각합니다.

     

    참고 자료

    빨간색 코딩님의 블로그 (https://sjh836.tistory.com/141)

    Stack Overflow (stackoverflow.com/questions/53795268/should-i-use-httpurlconnection-or-resttemplate)

     

     

    반응형

    'Back-end Developer > Server, Spring' 카테고리의 다른 글

    Spring Web MVC  (0) 2021.04.07
    MSA  (0) 2021.03.24
    RPC (Remote Procedure Call)  (0) 2020.10.29
    REST API (2)  (0) 2020.07.19
    REST API (1)  (0) 2020.07.17

    댓글

Designed by minchoba.