JEP 110: HTTP Client (Incubator)

JEP 110: HTTP Client (Incubator)

Summary

HTTP / 2 및 WebSocket을 구현하는 새 HTTP 클라이언트 API를 정의하고 기존 HttpURLConnectionAPI를 대체 할 수 있습니다 . API는 JEP 11 , JDK 9에 정의 된 바와 같이 인큐베이터 모듈로 제공됩니다. 이는 다음을 의미합니다.

  • API와 구현은 Java SE에 포함되지 않습니다.
  • API는 jdk.incubtor 네임 스페이스 아래에 있습니다.
  • 모듈은 컴파일 또는 실행시 기본적으로 해석되지 않습니다.

Motivation

기존 HttpURLConnectionAPI 및 그 구현에는 많은 문제점이 있습니다.

  • 기본 URLConnectionAPI는 지금 소멸 (있는 거의 모두 염두에두고 여러 프로토콜로 설계되었다 ftp, gopher등).
  • API는 HTTP / 1.1보다 앞서서 너무 추상적입니다.
  • 많은 문서화되지 않은 행동으로 사용하기가 어렵습니다.
  • 블로킹 모드에서만 작동합니다 (요청 / 응답 당 하나의 스레드).
  • 유지하기가 매우 어렵습니다.

Goals

  • simple blocking mode를 포함하여 일반적인 경우에 사용하기 쉬워야합니다.

  • “headers received”, errors, and “response body received”과 같은 이벤트 알림을 제공해야합니다. 이 알림은 반드시 콜백을 기반으로하지는 않지만 CompletableFuture와 같은 비동기 메커니즘을 사용할 수 있습니다.

  • 애플리케이션 요구의 80-90 %를 충족시키는 간단하고 간결한 API입니다. 이것은 아마도 프로토콜의 모든 기능을 노출하지 않는 상대적으로 작은 API 풋 프린트를 의미합니다.

  • HTTP 프로토콜 요청의 모든 관련 측면을 서버에 노출하고 서버의 응답 (헤더, 본문, 상태 코드 등)을 노출해야합니다.

  • 표준 및 공통 인증 메커니즘을 지원해야합니다. 초기에는 기본 인증으로 만 제한됩니다.

  • WebSocket 핸드 셰이크를 쉽게 설정할 수 있어야합니다.

  • HTTP / 2를 지원해야합니다 . (HTTP / 2의 애플리케이션 레벨 의미는 1.1과 거의 동일하지만 와이어 프로토콜은 완전히 다릅니다.)

    • 1.1에서 2로 업그레이드를 협상 할 수 있어야하며, 그렇지 않으면 처음부터 2를 선택해야합니다.
    • 서버 푸시 (Server Push)를 지원해야합니다. 즉, 서버가 클라이언트의 명시 적 요청없이 클라이언트에 자원을 푸시하는 기능입니다.
  • 기존 네트워킹 API와 일치하는 보안 검사를 수행해야합니다.

  • 람다 식과 같은 새로운 언어 기능에 친숙해야합니다.

  • 임베디드 시스템 요구 사항에 맞춰야하며 특히 타이머 스레드를 영구적으로 실행하지 않아야합니다.

  • HTTPS / TLS를 지원해야합니다.

  • HTTP / 1.1의 성능 요구 사항 :

    • 성능은 기존 HttpURLConnection 구현 과 동등해야합니다.
    • 성능은 클라이언트 API로 사용될 때 Apache HttpClient 라이브러리 및 Netty 및 Jetty와 동등해야합니다.
    • 새 API의 메모리 소비 HttpURLConnection는 클라이언트 API로 사용되는 경우 Apache HttpClient 및 Netty 및 Jetty 보다 낮거나 같아야합니다 .
  • HTTP / 2의 성능 요구 사항 :

    • 플랫폼의 제한 사항 (예 : TCP 세그먼트 확인 창)에도 불구하고 성능은 새로운 프로토콜 (예 : 확장 성 및 대기 시간)에서 예상되는 방식으로 HTTP / 1.1보다 우수해야합니다.
    • 성능은 HTTP / 2 용 클라이언트 API로 사용될 때 Netty 및 Jetty와 동등해야합니다.
    • 새 API의 메모리 소비 HttpURLConnection는 클라이언트 API로 사용할 때 Apache HttpClient 및 Netty 및 Jetty를 사용할 때보 다 낮아야 합니다.
  • 성능 비교는 비교 가능한 운영 모드의 맥락에서만 가능할 것입니다. 새로운 API는 모든 가능한 유스 케이스를 다루는 것보다 단순하고 사용하기 쉬우므로,

  • 이 작업은 JDK 9를 대상으로합니다. 일부 코드는 Java EE가 Servlet 4.0 API에서 HTTP / 2를 구현할 때 다시 사용할 수 있으므로 JDK 8 언어 기능과 가능한 경우 API 만 사용됩니다.

  • JDK 9에서 API를 사용하여 얻은 경험을 활용하면 Java SE에서 JDK 10의 java.net 네임 스페이스 아래에서 API를 표준화 할 수 있습니다.이 경우 JEP 10의 일부로 API 더 이상 인큐베이터 모듈로 존재하지 않습니다.

Non-Goals

이 API는 결국 HttpURLConnection새 코드 용 API를 대체하기위한 것이지만 새 API를 사용하여 이전 API를 즉시 구현하지는 않습니다. 이것은 미래의 일이 될 수 있습니다.

JDK 8 용 JEP의 이전 버전에서는 몇 가지 요구 사항이 고려되었지만 가능한 한 간단하게 API를 유지하기 위해 제외되었습니다.

  • 요청 / 응답 필터링,
  • 플러그 가능한 연결 캐시 및
  • 일반적인 업그레이드 메커니즘.

이러한 요구 사항 중 일부 (예 : 연결 캐싱)는 점진적으로 HTTP / 2를 채택하면 덜 중요해질 것입니다.

Description

HTTP 클라이언트, 요청 및 응답에 대해 별도의 클래스가 정의 된 JDK 9의 프로토 타이핑 작업이 일부 수행되었습니다. 빌더 패턴은 변경 불가능한 엔티티를 변경 불가능한 제품에서 분리하는 데 사용되었습니다. 동기 블로킹 모드는 송수신을 위해 정의되고 java.util.concurrent.CompletableFuture를 기반으로하는 비동기 모드도 정의됩니다.

이 프로토 타입은 NIO SocketChannels에서 구현되었으며 Selectors 및 외부에서 제공되는 ExecutorServices로 구현 된 비동기 동작을 제공합니다.

프로토 타입 구현은 독립 실행 형이었습니다. 즉, 기존 스택이 변경되지 않아 호환성을 보장하고 처음부터 모든 기능을 지원해야하는 단계적 접근을 허용했습니다.

프로토 타입 API에는 다음이 포함됩니다.

  • 서블릿 및 HTTP 서버 API와 같은 별도의 요청 및 응답;
  • 다음 이벤트의 비동기 알림 :
    • 수신 된 응답 헤더,
    • 응답 오류,
    • 접수 된 응답 본문
    • 서버 푸시 (HTTP / 2 전용);
  • HTTPS, via SSLEngine;
  • Proxying;
  • Cookies; and Authentication

추가 작업이 필요한 API 부분은 HTTP / 2 다중 응답 (서버 푸시) 및 HTTP / 2 구성을 지원하는 것입니다. 프로토 타입 구현은 거의 모든 HTTP / 1.1을 지원하지만 아직 HTTP / 2는 지원하지 않습니다.

HTTP / 2 proxying은 다음 변경에서 구현됩니다.

Alternatives

Jetty 및 Apache HttpClient 와 같은 기존 HTTP 클라이언트 API 및 구현이 많이 존재합니다 . 이 두 가지 모두 패키지와 클래스 수 측면에서 다소 무겁고 람다 식과 같은 새로운 언어 기능을 이용하지 않습니다.

Testing

내부 HTTP 서버는 회귀 및 TCK 테스트에 적합한 기반을 제공합니다. 기능 테스트에서도이 기능을 사용할 수 있지만 실제 HTTP 서버를 테스트해야 할 수 있습니다.

참조