Heim  >  Artikel  >  Java  >  Unterstützung des HTTP2-Protokolls von Java 9 und nicht blockierende HTTP-API-Analyse

Unterstützung des HTTP2-Protokolls von Java 9 und nicht blockierende HTTP-API-Analyse

王林
王林nach vorne
2023-04-22 21:52:061017Durchsuche

1. Einführung in HTTP/2

HTTP/2 zielt darauf ab, die durch die Aufrechterhaltung der komplexen Infrastruktur von HTTP/1.1 verursachten Probleme zu lindern und bietet eine gute Leistung. Obwohl HTTP/2 immer noch abwärtskompatibel mit HTTP/1.1 ist, handelt es sich nicht mehr um ein textbasiertes Protokoll.

HTTP/2-Multiplexing ermöglicht es einer einzelnen Verbindung, mehrere bidirektionale Streams zu verarbeiten, sodass Clients mehrere Ressourcen gleichzeitig über eine einzige Verbindung herunterladen können.

Das HTTP 1.x-Protokoll ist textbasiert, daher sind die Nachrichten sehr lang. Manchmal werden dieselben HTTP-Header immer wieder ausgetauscht. HTTP/2 verwaltet HTTP-Header über alle Anforderungen hinweg, wodurch ein wiederholter Datenaustausch vermieden und die für die Dateninteraktion erforderliche Bandbreite erheblich reduziert wird.

HTTP/2-Datenpush

Sie denken vielleicht, dass der serverseitige Datenpush von HTTP/2 eine Art Fortsetzung oder Upgrade auf WebSockets ist, aber das ist nicht der Fall. Während WebSockets eine Methode der Vollduplex-Kommunikation zwischen einem Client und einem Server sind, sodass der Server Daten an den Client sendet, nachdem eine TCP-Verbindung hergestellt wurde, bietet HTTP/2 eine andere Lösung.

HTTP/2-Push besteht darin, aktiv Ressourcen an den Client zu senden, ohne Ressourcenanforderungen aus der Sicht des Clients zu initiieren. Dies bedeutet, dass der Server möglicherweise anhand einer Anfrage weiß, welche anderen Ressourcen die Website weiterhin benötigt, und sie alle zusammen (im Voraus) senden kann, lange bevor der Client erneut eine Anfrage für sie initiiert.

Unterstützt derzeit den HTTP/2-Java-HTTP-Client

  • Jetty

  • Netty

  • OkHttp

  • Vert.x

  • Firefly.

Aber in diesem Artikel werden wir nicht vorstellen diese Java-Client-Software, führen aber die von Java9 bereitgestellte HTTP/2-Unterstützung ein.

2. HTTP/2-Client von Java 9

Verwenden Sie zunächst die Java 9-Syntax, um das Modul zu importieren. jdk.incubator.httpclient

module com.springui.echo.client {
    requires jdk.incubator.httpclient;
}

Die neue HTTP-Client-API von Java 9 folgt dem Builder-Muster. HttpClient ist der Einstiegspunkt für die Ausführung von HTTP-Anfragen. Er wird zuerst erstellt und dann verwendet.

HttpClient client = HttpClient
    .newBuilder()
    .version(Version.HTTP_2)  //支持HTTP2
    .build();

Senden von Anfragen im Blockierungsmodus

Sobald wir eine HttpClient-Instanz haben, können wir diese zum Senden von HttpRequest-Instanzen verwenden. HttpRequest-Instanzen können auch mit dem Konstruktor erstellt werden.

HttpResponse<String> response = client.send(
    HttpRequest
        .newBuilder(TEST_URI)  //请求地址
        .POST(BodyProcessor.fromString("Hello world")) //POST报文数据
        .build(),
    BodyHandler.asString()  //请求响应数据处理,接收字符串
);

Nachdem die Anfrage gesendet wurde, wird der Thread blockiert, bis die Antwortdaten abgerufen werden. Dies ist dasselbe wie die HTTP-API in JAVA 8 und früher. Java 9 bietet jedoch eine Methode zum asynchronen, nicht blockierenden Senden und Verarbeiten von Anforderungen, die sich besser für hochgradig gleichzeitige HTTP-Anforderungen und -Verarbeitung eignet.

Senden von Anfragen im nicht blockierenden Modus (Java 9)

Im folgenden Beispiel werden 10 zufällige Ganzzahlen asynchron gesendet.

List<CompletableFuture<String>> responseFutures = 
        IntStream.of(1,2,3,4,5,6,7,8,9,10)  //10个整数形成IntStream,Java 8的语法
        .mapToObj(String::valueOf) //10个整数转换成字符串,Java 8的语法
        .map(message -> client.sendAsync( //将10个整数字符串作为内容,发送10个异步请求
                HttpRequest.newBuilder(TEST_URI)
                        .POST(HttpRequest.BodyProcessor.fromString(message))
                        .build(),
                HttpResponse.BodyHandler.asString()
             ).thenApply(HttpResponse::body)  //以CompletableFuture<HttpResponse.body()>作为流处理的返回值
        )
        .collect(Collectors.toList());  //将Stream转成List

Das obige Beispiel nutzt in großem Umfang die Stream-Streaming-API von Java 8. Wenn Sie damit nicht vertraut sind, können Sie einige Artikel lesen, die ich zuvor geschrieben habe.

Der Rückgabewert der sendAsync-Methode ist CompletableFuture721c5bd4f0360fdcda122bb99928a389>, der mit thenApply(HttpResponse::body) weiterverarbeitet wird, und der endgültige Rückgabewert ist CompletableFuturef7e83be87db5cd2d9a8a0b8117b38cd4.

CompletableFuture ist das Wissen der asynchronen Java-Programmierung, das die Ergebnisse der gleichzeitigen asynchronen Verarbeitung druckt.

responseFutures.stream().forEach(future -> {
    LOGGER.info("Async response: " + future.getNow(null));
});

Sie werden feststellen, dass das endgültige Druckprotokoll möglicherweise nicht in der Reihenfolge 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 verarbeitet wird, da alle Anforderungen asynchron gesendet werden. Das zurückgegebene Ergebnis ist das CompletableFuture wird für die asynchrone Verarbeitung verwendet.

3. Unterstützung von HTTP2-Push-Promise-Frames

Alle oben genannten Beispiele können unter dem HTTP/1.1-Protokoll ausgeführt werden, es wird jedoch eine neue nicht blockierende asynchrone API hinzugefügt und HTTP/2-Funktionen sind nicht beteiligt. Keine Sorge, die Java 9-Client-API ist am engsten mit HTTP/2 integriert: Sie können HTTP2 verwenden, um eine Anfrage zu senden und mehrere asynchrone Datenergebnisse zu erhalten. (Einige Daten werden im Voraus übertragen. Dies setzt natürlich voraus, dass der Server für die Zusammenarbeit auch HTTP/2 unterstützt.)

Map<HttpRequest,CompletableFuture<HttpResponse<String>>> responses =
        client.sendAsync(    //注意这里只发送一次请求
          HttpRequest.newBuilder(TEST_URI)
                  .POST(HttpRequest.BodyProcessor.fromString(TEST_MESSAGE))
                  .build(),
          HttpResponse.MultiProcessor.asMap(    //多个资源的响应结果
                  request -> Optional.of(HttpResponse.BodyHandler.asString())
          )
).join();
responses.forEach((request, responseFuture) -> {
  LOGGER.info("Async response: " + responseFuture.getNow(null));
});

Aus der Sicht von Java 9 sieht die neue HTTP/2-Client-API gut aus. Der Autor ist jedoch der Meinung, dass der aktuelle Einsatz verwandter Technologien noch nicht sehr ausgereift ist. Ich denke, jeder kann es vorerst einfach mal ausprobieren.

Das obige ist der detaillierte Inhalt vonUnterstützung des HTTP2-Protokolls von Java 9 und nicht blockierende HTTP-API-Analyse. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen