国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從JDK11新增HttpClient談談非阻塞模型

pingan8787 / 958人閱讀

摘要:是一個倡議,它提倡提供一種帶有非阻塞背壓的異步流處理的標準。是標準的實現之一。的實現細節請求響應的與請求響應的暴露為是請求的的消費者是響應的的生產者內部的內部

北京時間 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返回

HttpResponse response =
      client.send(request, BodyHandler.asString());
System.out.println(response.statusCode());
System.out.println(response.body());
2. 異步發送

異步發送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 NIO

Java NIO為Java帶來了非阻塞模型。

Lambda表達式

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和回調,其要點是組合不同實例而無需擔心末日金字塔問題。

CompletableFuture
(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.Publisher { ... }
}
HttpResponse的內部
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

相關文章

  • 淺析 jdk11HttpClient 的使用

    摘要:在中也可以直接使用返回的是,然后通過來獲取結果阻塞線程,從中獲取結果四一點嘮叨非常的年輕,網絡資料不多,且代碼非常精細和復雜,目前來看底層應該是使用了線程池搭配進行異步通訊。 零 前期準備 0 版本 JDK 版本 : OpenJDK 11.0.1 IDE : idea 2018.3 1 HttpClient 簡介 java.net.http.HttpClient 是 jdk11 中正式...

    Eminjannn 評論0 收藏0
  • tornado配合celery及rabbitmq實現web request異步阻塞

    摘要:主要是為了實現系統之間的雙向解耦而實現的。問題及優化隊列過長問題使用上述方案的異步非阻塞可能會依賴于的任務隊列長度,若隊列中的任務過多,則可能導致長時間等待,降低效率。 Tornado和Celery介紹 1.Tornado Tornado是一個用python編寫的一個強大的、可擴展的異步HTTP服務器,同時也是一個web開發框架。tornado是一個非阻塞式web服務器,其速度相當快。...

    番茄西紅柿 評論0 收藏0
  • Java11 HttpClient小試牛刀

    序 本文主要研究一下Java11的HttpClient的基本使用。 變化 從java9的jdk.incubator.httpclient模塊遷移到java.net.http模塊,包名由jdk.incubator.http改為java.net.http 原來的諸如HttpResponse.BodyHandler.asString()方法變更為HttpResponse.BodyHandlers.of...

    Bmob 評論0 收藏0
  • Java11的新特性

    摘要:從版本開始,不再單獨發布或者版本了,有需要的可以自己通過去定制官方解讀官方細項解讀穩步推進系列六的小試牛刀一文讀懂的為何如此高效棄用引擎 Java語言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的新特性 Java10的新特性 Java11的新特性 Java12的新特性 Java13的新特性 序 本文主要講述一下Java11的新...

    April 評論0 收藏0
  • 記一次 JAVA 的內存泄露分析

    摘要:展示如下場景再現經過分析,最后我們定位到是使用產生的內存泄露問題。下面通過一個,來簡單講下具體內存泄露的原因。這一次的內存泄露問題算是解決了。總結關于內存泄露問題在第一次排查時,往往是有點不知所措的。 記一次 JAVA 的內存泄露分析 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog 當前環境 jdk == 1.8 ...

    Tecode 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<