Java 9中的HTTP / 2支持简介
1.簡介
IETF流媒體小組于2015年(即HTTP / 1.1發布后的16年) 批準了HTTP / 2協議。 HTTP / 2有望降低延遲,并且使許多替代方法變得過時,而這些替代方法是HTTP / 1.1所必需的,以便能夠滿足當今的響應時間要求。 在本文中,我將簡要介紹HTTP / 2以及它如何更新基于文本的HTTP / 1.1,然后研究Java 9中即將推出的HTTP / 2支持。
2. HTTP / 1.1的延遲優化技術
人們越來越多地在Internet上住院,但是他們不會注意到,如果響應時間低于100毫秒,那么他們在網絡上執行的操作并不是直接由他們自己執行的。
當響應時間達到1秒并引起注意,并且網站響應時間超過10秒時,就被認為是混亂的。 根據一些研究 ,平均注意力跨度已降至7-8秒,即使延遲1秒也可能導致7%的收入損失。
HTTP / 1.1需要(有時很繁重)的變通辦法來滿足當今的要求。
- 由于一個HTTP連接一次可以下載一個資源,因此瀏覽器會同時獲取它們,以便能夠更快地呈現頁面。 但是,每個域的并行連接數是有限的,并且使用域分片來解決該問題。
- 一種類似的優化技術是將多個資源(CSS,JavaScript)組合到一個包中,以便能夠通過單個請求獲取它們。 權衡使網絡往返的時間減少了,而根本沒有使用組裝好的資源束中某些部分的風險。 在某些情況下,復雜的服務器端邏輯會負責選擇相關的靜態資源并將其合并為特定的頁面請求
- 圖像精靈是一種類似于將CSS和JavaScript文件捆綁在一起以減少請求數量的技術。
- 另一種技術的存在是在襯里靜態資源HTML
3. HTTP / 2簡介
HTTP / 2旨在減輕因維護HTTP / 1.1的復雜基礎結構以使其正常運行而引起的痛苦。 盡管HTTP / 2仍與HTTP / 1.1向后兼容,但它不再是基于文本的協議。 客戶端將連接建立為HTTP / 1.1請求,然后請求并升級。 從那以后,HTTP / 2在二進制數據幀中對話。
HTTP / 2復用
HTTP / 2復用使上述所有HTTP / 1.1解決方法都已過時,因為單個連接可以處理多個雙向流,因此允許客戶端同時通過單個連接下載多個資源。
HTTP 1.x協議基于文本,因此很冗長。 有時,一次又一次地交換同一組HTTP標頭。 HTTP / 2通過在請求之間維護HTTP標頭表,大大減少了所需的帶寬。 本質上,這是重復數據刪除,而不是傳統意義上的壓縮。
HTTP / 2推送
您可能會認為HTTP / 2推送是WebSocket的延續或某種升級,但事實并非如此。 WebSocket是在客戶端和服務器之間進行全雙工通信的一種方法,以便在建立TCP連接后允許服務器將數據發送到客戶端,而HTTP / 2則解決了另一個問題。
HTTP / 2推送是關于主動向客戶端發送資源,而不必從客戶端的角度要求它。 實際上,這意味著服務器端知道一個網站需要一些圖像,并且在客戶端請求它們之前很長一段時間(一次)將它們全部發送出去。
4.支持HTTP / 2的Java HTTP客戶端
根據HTTP / 2的Wiki頁面之一,在編寫本文時,以下Java客戶端庫可用于建立HTTP / 2連接。
- 碼頭
- 凈額
- OkHttp
- Vert.x
- 螢火蟲
但是,在本文中,我們重點關注Java 9提供的HTTP / 2支持。JEP110指定了要求,并且還指出該項目仍處于孵化狀態,這實際上意味著該項目將不會取代現有的UrlConnection。 Java 9中的API
僅在Java 10中,標準Java HTTP / 2客戶端才會移動到包java.net下 。 但是,與此同時,它將位于jdk.incubtor命名空間下。
5.探索Java 9的HTTP / 2客戶端
JEP 110設置了對新的內置HTTP / 2客戶端的要求,以便它提供高級,易于使用的API,并且與現有的替代產品相比具有可比的(或更高的)性能(請參見上文)。
第一步是導入模塊jdk.incubator.httpclient 。
module com.springui.echo.client {requires jdk.incubator.httpclient; }為了這個示例,我們將使用Undertow作為HTTP / 2兼容的Web服務器。 它只是回顯該客戶發送給它的消息。
public class EchoServer {private static final Logger LOGGER = Logger.getLogger(EchoServer.class.getSimpleName());private static final int PORT = 8888;private static final String HOST = "localhost";public static void main(final String[] args) {Undertow server = Undertow.builder().setServerOption(UndertowOptions.ENABLE_HTTP2, true).addHttpListener(PORT, HOST).setHandler(exchange -> {LOGGER.info("Client address is: " + exchange.getConnection().getPeerAddress().toString());exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");exchange.getRequestReceiver().receiveFullString((e, m) -> e.getResponseSender().send(m));}).build();server.start();}}新的API隨處都遵循構建器模式,而HttpClient是發起HTTP請求的入口,也不例外。
HttpClient client = HttpClient.newBuilder().version(Version.HTTP_2).build();以阻止模式發送請求
一旦有了HttpClient實例,也可以使用構建器構造HttpRequest實例。
HttpResponse<String> response = client.send(HttpRequest.newBuilder(TEST_URI).POST(BodyProcessor.fromString("Hello world")).build(),BodyHandler.asString() );只要請求得到處理,方法send塊就會發送 ,但是也有一種異步交換HTTP消息的方法。
以非阻塞模式發送請求
在下面的示例中,將10個隨機整數異步發送到我們的HTTP回顯服務器,并且在所有請求都已發起后,主線程等待它們完成。
List<CompletableFuture<String>> responseFutures = new Random().ints(10).mapToObj(String::valueOf).map(message -> client.sendAsync(HttpRequest.newBuilder(TEST_URI).POST(BodyProcessor.fromString(message)).build(),BodyHandler.asString()).thenApply(r -> r.body())).collect(Collectors.toList());CompletableFuture.allOf(responseFutures.toArray(new CompletableFuture<?>[0])).join();responseFutures.stream().forEach(future -> {LOGGER.info("Async response: " + future.getNow(null)); });處理承諾框架
上面所有示例都可能是常規的老式HTTP / 1.1請求。 除了創建HttpClient之外 ,無法觀察到任何特定于HTTP / 2的內容。
客戶端API最相關的HTTP / 2功能可能是使用HTTP / 2推送時它處理多個響應的方式。
Map<HttpRequest, CompletableFuture<HttpResponse<String>>> responses =client.sendAsync(HttpRequest.newBuilder(TEST_URI).POST(BodyProcessor.fromString(TEST_MESSAGE)).build(),MultiProcessor.asMap(request -> Optional.of(BodyHandler.asString()))).join();responses.forEach((request, responseFuture) -> {LOGGER.info("Async response: " + responseFuture.getNow(null)); });六,結論
HTTP / 2對舊的基于文本的協議進行了改進,需要進行很多改進,并使許多令人討厭的HTTP / 1.1解決方法過時,但它并不能解決所有已知問題。
從Java 9的角度來看,新的HTTP / 2客戶端看起來不錯,但是,只有在下一個發行版中它才能投入生產。 同時,如果需要HTTP / 2支持,則可以使用上述上述庫。
更新: HTTP客戶端JEP 312提議對HTTP客戶端API進行標準化,該HTTP客戶端API是在Java 9中作為孵化API引入的,并在Java 10中進行了更新。從Java 11開始,它是java.net模塊的完整功能。
如果您想了解有關Java 9的更多信息,還可以從Java Code Geeks中查看這些Java 9教程 。
翻譯自: https://www.javacodegeeks.com/2020/01/introduction-to-http-2-support-in-java-9.html
總結
以上是生活随笔為你收集整理的Java 9中的HTTP / 2支持简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux文件查找内容(linux 文件
- 下一篇: java 8 lambda_玩Java