摘要:是一個倡議,它提倡提供一種帶有非阻塞背壓的異步流處理的標準。是標準的實現之一。的實現細節請求響應的與請求響應的暴露為是請求的的消費者是響應的的生產者內部的內部
北京時間 9 月 26 日,Oracle 官方宣布 Java 11 正式發布 一、JDK HTTP Client介紹 JDK11中的17個新特性 JDK11中引入HTTP Client的動機
既有的HttpURLConnection存在許多問題
其基類URLConnection當初是設計為支持多協議,但其中大多已經成為非主流(ftp, gopher…)
API的設計早于HTTP/1.1,過度抽象
難以使用,存在許多沒有文檔化的行為
它只支持阻塞模式(每個請求/響應占用一個線程)
HTTP Client發展史 在JDK11 HTTP Client出現之前在此之前,可以使用以下工具作為Http客戶端
JDK HttpURLConnection
Apache HttpClient
Okhttp
Spring Rest Template
Spring Cloud Feign
將Jetty用作客戶端
使用Netty庫。還
初探JDK HTTP Client我們來看一段HTTP Client的常規用法的樣例 ——
執行GET請求,然后輸出響應體(Response Body)。
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://openjdk.java.net/")) .build(); client.sendAsync(request, asString()) .thenApply(HttpResponse::body) .thenAccept(System.out::println) .join();第一步:創建HttpClient
一般使用JDK 11中的HttpClient的第一步是創建HttpClient對象并進行配置。
指定協議(http/1.1或者http/2)
轉發(redirect)
代理(proxy)
認證(authenticator)
HttpClient client = HttpClient.newBuilder() .version(Version.HTTP_2) .followRedirects(Redirect.SAME_PROTOCOL) .proxy(ProxySelector.of(new InetSocketAddress("www-proxy.com", 8080))) .authenticator(Authenticator.getDefault()) .build();第二步:創建HttpRequest
從HttpRequest的builder組建request
請求URI
請求method(GET, PUT, POST)
請求體(request body)
Timeout
請求頭(request header)
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://openjdk.java.net/")) .timeout(Duration.ofMinutes(1)) .header("Content-Type", "application/json") .POST(BodyPublisher.fromFile(Paths.get("file.json"))) .build()第三步:send
http client可以用來發送多個http request
請求可以被以同步或異步方式發送
1. 同步發送同步發送API阻塞直到HttpResponse返回
HttpResponse2. 異步發送response = client.send(request, BodyHandler.asString()); System.out.println(response.statusCode()); System.out.println(response.body());
異步發送API立即返回一個CompletableFuture
當它完成的時候會獲得一個HttpResponse
client.sendAsync(request, BodyHandler.asString()) .thenApply(response -> { System.out.println(response.statusCode()); return response; } ) .thenApply(HttpResponse::body) .thenAccept(System.out::println);
※CompletableFuture是在java8中加入的,支持組合式異步編程
二、從提升單機并發處理能力的技術來看HttpClient的實現細節 提升單機并發處理能力的技術多CPU/多核
多線程
非阻塞(non-blocking)
Java NIOJava NIO為Java帶來了非阻塞模型。
Lambda表達式可以方便地利用多CPU。
Lambda表達式讓代碼更加具有可讀性
回調假設以下代碼是一個聊天應用服務器的一部分,該應用以Vert.x框架實現。
(Eclipse Vert.x is a tool-kit for building reactive applications on the JVM.)
向connectHandler方法輸入一個Lambda表達式,每當有用戶連接到聊天應用時,都會調用該Lambda表達式。這就是一個回調。
這種方式的好處是,應用不必控制線程模型——Vert.x框架為我們管理線程,打理好一切相關復雜性,程序員只考慮和回調就夠了。
vertx.createServer() .connectHandler(socket -> { socket.dataHandler(new User(socket, this)); }).listen(10_000);
注意,這種設計里,不共享任何狀態。對象之間通過向事件總線發送消息通信,根本不需要在代碼中添加鎖或使用synchronized關鍵字。并發編程變得更加簡單。
Future大量的回調會怎樣?請看以下偽代碼
(1)->{ (2)->{ (3)->{ (4)->{} } } }
大量回調會形成“末日金字塔”。
如何破解? 使用Future
Future1=(1)->{} Future2=(Future1.get())->{} Future3=(Future2.get())->{} Future4=(Future3.get())->{}
但這會造成原本期望的并行處理,變成了串行處理,帶來了性能問題。
我們真正需要的是將Future和回調聯合起來使用。下面將要講的CompletableFuture就是結合了Future和回調,其要點是組合不同實例而無需擔心末日金字塔問題。
(new CompletableFuture()).thenCompose((1)->{}) .thenCompose((2)->{}) .thenCompose((3)->{}) .thenCompose((4)->{}) .join()Reactive Streams
Reactive Streams是一個倡議,它提倡提供一種帶有非阻塞背壓的異步流處理的標準(Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure)。
JDK 9中的java.util.concurrent.Flow中的概念,與Reactive Streams是一對一對等的。java.util.concurrent.Flow是Reactive Streams標準的實現之一。
多CPU的并行機制讓處理海量數據的速度更快,消息傳遞和響應式編程讓有限的并行運行的線程執行更多的I/O操作。 HttpClient的實現細節 請求響應的body與reactive streams請求響應的body暴露為reactive streams
http client是請求的body的消費者
http client是響應的body的生產者
HttpRequest內部public abstract class HttpRequest { ... public interface BodyPublisher extends Flow.PublisherHttpResponse的內部{ ... } }
public abstract class HttpResponse{ ... public interface BodyHandler { BodySubscriber apply(int statusCode, HttpHeaders responseHeaders); } public interface BodySubscriber extends Flow.Subscriber > { ... } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/71991.html
摘要:在中也可以直接使用返回的是,然后通過來獲取結果阻塞線程,從中獲取結果四一點嘮叨非常的年輕,網絡資料不多,且代碼非常精細和復雜,目前來看底層應該是使用了線程池搭配進行異步通訊。 零 前期準備 0 版本 JDK 版本 : OpenJDK 11.0.1 IDE : idea 2018.3 1 HttpClient 簡介 java.net.http.HttpClient 是 jdk11 中正式...
摘要:主要是為了實現系統之間的雙向解耦而實現的。問題及優化隊列過長問題使用上述方案的異步非阻塞可能會依賴于的任務隊列長度,若隊列中的任務過多,則可能導致長時間等待,降低效率。 Tornado和Celery介紹 1.Tornado Tornado是一個用python編寫的一個強大的、可擴展的異步HTTP服務器,同時也是一個web開發框架。tornado是一個非阻塞式web服務器,其速度相當快。...
序 本文主要研究一下Java11的HttpClient的基本使用。 變化 從java9的jdk.incubator.httpclient模塊遷移到java.net.http模塊,包名由jdk.incubator.http改為java.net.http 原來的諸如HttpResponse.BodyHandler.asString()方法變更為HttpResponse.BodyHandlers.of...
摘要:從版本開始,不再單獨發布或者版本了,有需要的可以自己通過去定制官方解讀官方細項解讀穩步推進系列六的小試牛刀一文讀懂的為何如此高效棄用引擎 Java語言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的新特性 Java10的新特性 Java11的新特性 Java12的新特性 Java13的新特性 序 本文主要講述一下Java11的新...
摘要:展示如下場景再現經過分析,最后我們定位到是使用產生的內存泄露問題。下面通過一個,來簡單講下具體內存泄露的原因。這一次的內存泄露問題算是解決了。總結關于內存泄露問題在第一次排查時,往往是有點不知所措的。 記一次 JAVA 的內存泄露分析 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog 當前環境 jdk == 1.8 ...
閱讀 691·2023-04-25 22:50
閱讀 1529·2021-10-08 10:05
閱讀 984·2021-09-30 09:47
閱讀 1917·2021-09-28 09:35
閱讀 821·2021-09-26 09:55
閱讀 3412·2021-09-10 10:51
閱讀 3428·2021-09-02 15:15
閱讀 3293·2021-08-05 09:57