Maison  >  Article  >  Java  >  Prise en charge du protocole HTTP2 de Java 9 et analyse de l'API HTTP non bloquante

Prise en charge du protocole HTTP2 de Java 9 et analyse de l'API HTTP non bloquante

王林
王林avant
2023-04-22 21:52:061017parcourir

1. Introduction à HTTP/2

HTTP/2 vise à atténuer les difficultés causées par la maintenance de l'infrastructure complexe de HTTP/1.1 et offre de bonnes performances. Bien que HTTP/2 soit toujours rétrocompatible avec HTTP/1.1, il ne s'agit plus d'un protocole textuel.

Le multiplexage HTTP/2 permet à une seule connexion de gérer plusieurs flux bidirectionnels, permettant aux clients de télécharger plusieurs ressources simultanément sur une seule connexion.

Le protocole HTTP 1.x est basé sur du texte, les messages sont donc très longs. Parfois, le même ensemble d’en-têtes HTTP est échangé encore et encore. HTTP/2 conserve les en-têtes HTTP dans toutes les requêtes, éliminant ainsi les échanges répétés de données et réduisant considérablement la bande passante requise pour l'interaction des données.

Push de données HTTP/2

Vous pensez peut-être que le push de données côté serveur HTTP/2 est une sorte de continuation ou de mise à niveau vers WebSockets, mais ce n'est pas le cas. Alors que les WebSockets sont une méthode de communication en duplex intégral entre un client et un serveur afin que le serveur envoie des données au client après l'établissement d'une connexion TCP, HTTP/2 offre une solution différente.

Le push HTTP/2 consiste à envoyer activement des ressources au client sans lancer de demandes de ressources du point de vue du client. Cela signifie que le serveur peut savoir, à partir d'une requête, de quelles autres ressources le site Web aura besoin et peut les envoyer toutes ensemble (à l'avance) bien avant que le client ne lance à nouveau une demande pour celles-ci.

Prend actuellement en charge le client HTTP Java HTTP/2

  • Jetty

  • Netty

  • OkHttp

  • Vert.x

  • Firefly

Mais dans cet article, nous ne présenterons pas ces logiciels clients Java, mais introduisons le support HTTP/2 fourni par Java9.

2. Client HTTP/2 de Java 9

Utilisez d'abord la syntaxe Java 9 pour importer le module. jdk.incubator.httpclient

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

La nouvelle API HTTP Cient de Java 9 suit le modèle du constructeur. HttpClient est le point d'entrée utilisé pour opérer les requêtes HTTP. Il est d'abord construit puis utilisé.

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

Envoi de requêtes en mode blocage

Une fois que nous avons une instance HttpClient, nous pouvons l'utiliser pour envoyer des instances HttpRequest. Les instances HttpRequest peuvent également être créées à l'aide du constructeur.

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

Une fois la requête envoyée, le thread se bloquera jusqu'à ce que les données de réponse soient obtenues. C'est la même chose que l'API HTTP dans JAVA 8 et avant. Cependant, Java 9 fournit une méthode d'envoi et de traitement asynchrone et non bloquant des requêtes, plus adaptée aux requêtes et au traitement HTTP hautement simultanés.

Envoi de requêtes en mode non bloquant (Java 9)

Dans l'exemple ci-dessous, 10 entiers aléatoires sont envoyés de manière asynchrone.

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

L'exemple ci-dessus utilise largement l'API de streaming Stream de Java 8. Si vous ne la connaissez pas, vous pouvez lire certains articles que j'ai déjà écrits.

La valeur de retour de la méthode sendAsync est CompletableFuture721c5bd4f0360fdcda122bb99928a389>, qui est ensuite traitée à l'aide de thenApply(HttpResponse::body), et la valeur de retour finale est CompleteableFuturef7e83be87db5cd2d9a8a0b8117b38cd4.

CompletableFuture est la connaissance de la programmation asynchrone Java, qui imprime les résultats du traitement asynchrone simultané.

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

Vous remarquerez que le journal d'impression final peut ne pas être traité dans l'ordre 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, car toutes les requêtes sont envoyées de manière asynchrone, le résultat renvoyé est le CompleteableFuture utilisé pour le traitement asynchrone.

3. Prise en charge des cadres de promesse push HTTP2

Tous les exemples ci-dessus peuvent être complétés sous le protocole HTTP/1.1, mais une nouvelle API asynchrone non bloquante est ajoutée et les fonctionnalités HTTP/2 ne sont pas impliquées. Ne vous inquiétez pas, l'API client Java 9 est la plus étroitement intégrée à HTTP/2 : vous pouvez utiliser HTTP2 pour envoyer une requête et obtenir plusieurs résultats de données asynchrones. (Certaines données sont poussées à l'avance, bien sûr, cela nécessite que le serveur prenne également en charge HTTP/2 pour la coopération)

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));
});

Du point de vue de Java 9, la nouvelle API client HTTP/2 a l'air bien. Cependant, l'auteur estime que l'utilisation actuelle des technologies connexes n'est pas encore très mature. Je pense que tout le monde peut l'essayer pour le moment.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer