Oracleã®Sergey Kuksenkoã¯ããJEP 110ïŒHTTP / 2ã¯ã©ã€ã¢ã³ããïŒå°æ¥JDKã«ç»å ŽããŸãïŒã®äŸã䜿çšããŠãããŒã ãã©ã®ããã«éå§ããããã©ããèŠãŠãã©ã®ããã«é«éåãããã瀺ããŸãã
JPoint 2017ããã®åœŒã®ã¬ããŒãã®ãã©ã³ã¹ã¯ãªãããæäŸããŸããäžè¬ã«ãããã§ã¯HTTP / 2ã«ã€ããŠã¯èª¬æããŸããã ãã¡ãããå€ãã®è©³çŽ°ããªããã°ç®¡çããããšã¯ã§ããŸããã
HTTP / 2ïŒå¥åRFC 7540ïŒ
HTTP 2ã¯ãã¬ã¬ã·ãŒHTTP 1.1ã眮ãæããããã«èšèšãããæ°ããæšæºã§ãã HTTP 2ã®å®è£
ãšããã©ãŒãã³ã¹ã®é¢ã§ã®ä»¥åã®ããŒãžã§ã³ãšã®éãã¯äœã§ããïŒ
HTTP 2ã®éèŠãªç¹ã¯ãåäžã®TCPæ¥ç¶ãããããšã§ãã ããŒã¿ã¹ããªãŒã ã¯ãã¬ãŒã ã«åå²ãããããããã¹ãŠã®ãã¬ãŒã ã¯ãã®æ¥ç¶ãä»ããŠéä¿¡ãããŸãã
å¥ã®ããããŒå§çž®æšæºã§ããRFC 7541ïŒHPACKïŒãæäŸãããŸãã ããã¯éåžžã«ããŸãæ©èœããŸãã1ãããã€ãçšåºŠã®ãµã€ãºã®HTTPããããŒãæ倧20ãã€ãå§çž®ã§ããŸãã æé©åã®äžéšã§ã¯ãããã¯éèŠã§ãã
äžè¬ã«ãæ°ããããŒãžã§ã³ã«ã¯å€ãã®èå³æ·±ããã®ããããŸã-èŠæ±ã®åªå
é äœä»ãããµãŒããŒããã·ã¥ïŒãµãŒããŒèªäœãã¯ã©ã€ã¢ã³ãã«ããŒã¿ãéä¿¡ãããšãïŒãªã©ã ãã ãããã®ç©èªã®æèã§ã¯ïŒããã©ãŒãã³ã¹ã®èŠ³ç¹ããïŒãããã¯éèŠã§ã¯ãããŸããã ããã«ãå€ãã®ãã®ãåããŸãŸã§ãã ããšãã°ãäžèšã®HTTPãããã³ã«ã¯æ¬¡ã®ããã«ãªããŸããåãGETã¡ãœãããšPOSTã¡ãœãããåãHTTPããããŒãã£ãŒã«ãå€ãã¹ããŒã¿ã¹ã³ãŒããããã³ããªã¯ãšã¹ã->ã¬ã¹ãã³ã¹->æçµã¬ã¹ãã³ã¹ãã®æ§é ããããŸãã å®éã詳ããèŠãŠã¿ããšãHTTP 2ã¯HTTP 1.1ã®äœã¬ãã«ã®ãã©ã³ã¹ããŒããµãã¹ãã¬ãŒãã«ãããããã®æ¬ ç¹ãåãé€ãããŠããŸãã
HTTP APIïŒå¥åJEP 110ãHttpClientïŒ
JEP 110ãšåŒã°ããHttpClientãããžã§ã¯ãããããŸããããã¯ã»ãšãã©JDK 9ã«å«ãŸããŠããŸããåœåããã®ã¯ã©ã€ã¢ã³ããJDK 9æšæºã®äžéšã«ãããã£ãã®ã§ãããAPIå®è£
ã¬ãã«ã§ããã€ãã®è«äºããããŸããã ãŸããJDK 9ã®ãªãªãŒã¹ãŸã§ã«HTTP APIãå®æãããæéããªãã®ã§ãã³ãã¥ããã£ã«èŠããŠè°è«ã§ããããã«HTTP APIãäœæããããšã«ããŸããã
JDK 9ã§ã¯ãæ°ããã€ã³ãã¥ããŒã¿ãŒã¢ãžã¥ãŒã«ïŒIncubator Modules aka JEP-11ïŒãå°å
¥ãããŠããŸãã ããã¯ãã³ãã¥ããã£ããã®ãã£ãŒãããã¯ãåãåãããã«ããŸã æšæºåãããŠããªãæ°ããAPIãè¿œå ããããµã³ãããã¯ã¹ã§ãããã€ã³ãã¥ããŒã¿ãŒã®å®çŸ©ã«ããã次ã®ããŒãžã§ã³ã«æšæºåãããããå®å
šã«åé€ãããŸãïŒãAPIã®ã€ã³ãã¥ããŒã·ã§ã³å¯¿åœã¯å¶éãããŠããŸãïŒ APIã¯æšæºåãããããããã§ãªããã°æ¬¡ã®ãªãªãŒã¹ã§æçµçã«ãããããåé€ãããŸãã èå³ã®ãã人ã¯èª°ã§ãAPIã«æ
£ãããã£ãŒãããã¯ãéä¿¡ã§ããŸãã ãããã次ã®ããŒãžã§ã³-JDK 10-ãæšæºã«ãªããšããã¹ãŠãä¿®æ£ãããŸãã
- ã¢ãžã¥ãŒã«ïŒjdk.incubator.httpclient
- ããã±ãŒãžïŒjdk.incubator.http
HttpClientã¯ãã€ã³ãã¥ããŒã¿ãŒã®æåã®ã¢ãžã¥ãŒã«ã§ãã ãã®åŸãã¯ã©ã€ã¢ã³ãã«é¢é£ããä»ã®ãã®ãã€ã³ãã¥ããŒã¿ãŒã«è¡šç€ºãããŸãã
APIã®äŸãããã€ã玹ä»ããŸãïŒããã¯ã¯ã©ã€ã¢ã³ãAPIã§ããããªã¯ãšã¹ããè¡ãããšãã§ããŸãïŒã äž»ãªã¯ã©ã¹ïŒ
- HttpClientïŒãã®ãã«ããŒïŒ;
- HttpRequestïŒãã®ãã«ããŒïŒ;
- HttpResponseã¯ãç§ãã¡ãæ§ç¯ããŠããã®ã§ã¯ãªãããã æ»ã£ãŠããŠããŸãã
ã¯ãšãªãäœæããç°¡åãªæ¹æ³ã次ã«ç€ºããŸãã
HttpRequest getRequest = HttpRequest .newBuilder(URI.create("https://jpoint.ru/")) .header("X-header", "value") .GET() .build();
HttpRequest postRequest = HttpRequest .newBuilder(URI.create("https://jpoint.ru/")) .POST(fromFile(Paths.get("/abstract.txt"))) .build();
ããã§ãURLã®æå®ãããããŒã®èšå®ãªã©ãè¡ããŸãã -ãªã¯ãšã¹ããåãåããŸãã
ã©ãããã°ãªã¯ãšã¹ããéä¿¡ã§ããŸããïŒ ã¯ã©ã€ã¢ã³ãã«ã¯2çš®é¡ã®APIããããŸãã 1ã€ç®ã¯ããã®åŒã³åºãã®å Žæã§ãããã¯ãããšãã®åæèŠæ±ã§ãã
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = ...; HttpResponse response =
ãªã¯ãšã¹ãã¯ãªããªããçããåãåããããã
string
ãšããŠè§£éãïŒããã®ãã³ãã©ã¯ç°ãªãå ŽåããããŸã
string
ã
byte
ãç¬èªã®ãã®ãæžãããšãã§ããŸãïŒãåŠçããŸããã
2ã€ç®ã¯éåæAPIã§ãããã®å Žæã§ãããã¯ããããªãå ŽåãéåæèŠæ±ãéä¿¡ããŠå®è¡ãç¶è¡ããçµæã®CompletableFutureã䜿çšããŠå¿
èŠãªåŠçãå®è¡ã§ããŸãã
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = ...; CompletableFuture> responseFuture =
ã¯ã©ã€ã¢ã³ãã«ã¯ã1000åã®æ§æãã©ã¡ãŒã¿ãŒãèšå®ã§ããããŸããŸãªæ¹æ³ã§æ§æã§ããŸãã
HttpClient client = HttpClient.newBuilder() .authenticator(someAuthenticator) .sslContext(someSSLContext) .sslParameters(someSSLParameters) .proxy(someProxySelector) .executor(someExecutorService) .followRedirects(HttpClient.Redirect.ALWAYS) .cookieManager(someCookieManager) .version(HttpClient.Version.HTTP_2)</b> .build();
ããã§ã®äž»ãªããªãã¯ã¯ãã¯ã©ã€ã¢ã³ãAPIããŠãããŒãµã«ã§ããããšã§ãã 詳现ãåºå¥ããããšãªããå€ãHTTP 1.1ãšHTTP 2ã®äž¡æ¹ã§åäœããŸãã ã¯ã©ã€ã¢ã³ãã®å Žåãæšæºã®HTTP 2ã§ããã©ã«ãã®æäœãæå®ã§ããŸããåã
ã®ãªã¯ãšã¹ãããšã«åããã©ã¡ãŒã¿ãŒãæå®ã§ããŸãã
åé¡ã®å£°æ
ãã®ãããJavaã©ã€ãã©ãªããããŸããããã¯ãæšæºã®JDKã¯ã©ã¹ã«åºã¥ããŠãããæé©åããå¿
èŠãããïŒäœããã®ããã©ãŒãã³ã¹äœæ¥ãè¡ãããã«ïŒå¥ã®ã¢ãžã¥ãŒã«ã§ãã æ£åŒã«ã¯ãããã©ãŒãã³ã¹ã®ã¿ã¹ã¯ã¯æ¬¡ã®ãšããã§ãã蚱容ã§ãããšã³ãžãã¢ã®æéå
ã«åççãªã¯ã©ã€ã¢ã³ãã®çç£æ§ãååŸããå¿
èŠããããŸãã
ã¢ãããŒããéžæããŸã
ãã®äœæ¥ã¯ã©ãããå§ããããŸããïŒ
- 座ã£ãŠHTTP 2ä»æ§ãèªãããšãã§ããŸããããã¯äŸ¿å©ã§ãã
- ã¯ã©ã€ã¢ã³ãèªäœã®èª¿æ»ãéå§ããèŠã€ãã£ãããããšãæžãæããããšãã§ããŸãã
- ãã®ã¯ã©ã€ã¢ã³ããèŠãŠãå
šäœãæžãçŽãããšãã§ããŸãã
- ãã³ãããŒã¯ã§ããŸãã
ãã³ãããŒã¯ããå§ããŸãããã çªç¶ããã¹ãŠããããŸã§è¯ããªããŸãããä»æ§ãèªãå¿
èŠã¯ãããŸããã
ãã³ãããŒã¯
圌ãã¯ãã³ãããŒã¯ãæžããã æ¯èŒã®ããã«ç«¶åä»ç€Ÿãããã°ããã§ãã Jetty Clientãã©ã€ãã«ãšããŠæ¡çšããŸããã ãµãŒããŒãJavaã«ãããã£ããããšãã£ãŠãJettyãµãŒããŒã暪ã«ãã蟌ã¿ãŸããã ããŸããŸãªãµã€ãºã®GETããã³POSTãªã¯ãšã¹ããäœæããŸããã

åœç¶ãåé¡ãçºçããŸã-ã¹ã«ãŒããããé
延ïŒæå°ãå¹³åïŒã枬å®ããŸãã è°è«ã®äžã§ãããã¯ãµãŒããŒã§ã¯ãªãã¯ã©ã€ã¢ã³ãã§ãããšå€æããŸããã ã€ãŸãããã®ã³ã³ããã¹ãã§æå°ã¬ã€ãã³ã·ãgcããŒãºããã®ä»ãã¹ãŠãèæ
®ããããšã¯éèŠã§ã¯ãããŸããã ãããã£ãŠãç¹ã«ãã®äœæ¥ã®ããã«ãã·ã¹ãã å
šäœã®ã¹ã«ãŒãããã®æž¬å®ã«éå®ããããšã«ããŸããã ç§ãã¡ã®ä»äºã¯ãããå¢ããããšã§ãã
ã·ã¹ãã ã®å
šäœçãªã¹ã«ãŒãããã¯ãå¹³åã¬ã€ãã³ã·ã®éæ°ã§ãã ã€ãŸããå¹³åã¬ã€ãã³ã·ã«åãçµã¿ãŸããããåæã«åã
ã®ãªã¯ãšã¹ãã«ç
©ããããŸããã§ããã ã¯ã©ã€ã¢ã³ãããµãŒããŒãšåãèŠä»¶ãæããªããšããçç±ã ãã§ã
å€æŽ1. TCPæ§æ
1ãã€ãã§GETãéå§ããŸãã éãæžãããŠããŸãã ååŸãããã®ïŒ

HTTPClientã«ã€ããŠãåããã³ãããŒã¯ãåããä»ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãšããŒããŠã§ã¢ïŒãããã¯å€ããå°ãªãããµãŒããŒãã·ã³ã§ãïŒã§å®è¡ããŸãã ç§ã¯åŸãïŒ

Win64ã§ã¯ããã¹ãŠãããè¯ãèŠããŸãã ããããMacOSã§ããäºæ
ã¯Linuxã»ã©æªãã¯ãããŸããã
åé¡ã¯ããã«ãããŸãïŒ
SocketChannel chan; ... try { chan = SocketChannel.open(); int bufsize = client.getReceiveBufferSize(); chan.setOption(StandardSocketOptions.SO_RCVBUF, bufsize); } catch (IOException e) { throw new InternalError(e); }
ããã¯ããµãŒããŒã«æ¥ç¶ããããã«SocketChannelãéããŠããŸãã åé¡ã¯ã1è¡ããªãããšã§ãïŒä»¥äžã®ã³ãŒãã§åŒ·èª¿ããŸããïŒã
SocketChannel chan; ... try { chan = SocketChannel.open(); int bufsize = client.getReceiveBufferSize(); chan.setOption(StandardSocketOptions.SO_RCVBUF, bufsize); chan.setOption(StandardSocketOptions.TCP_NODELAY, true); <-- !!! } catch (IOException e) { throw new InternalError(e); }
TCP_NODELAY
ã¯ãåäžçŽã®ããããŒãã§ãã ããŸããŸãªTCPã¹ã¿ãã¯ã¢ã«ãŽãªãºã ããããŸãã ãã®ã³ã³ããã¹ãã«ã¯ãNagleã®ã¢ã«ãŽãªãºã ãšé
延ACKã®2ã€ããããŸãã ç¹å®ã®æ¡ä»¶äžã§ã¯ããã¬ã¢ãçºçããããŒã¿è»¢éãæ¥æ¿ã«é
ããªãå¯èœæ§ããããŸãã ããã¯TCPã¹ã¿ãã¯ã®æ¢ç¥ã®åé¡ã§ãããããã©ã«ãã§Nagleã®ã¢ã«ãŽãªãºã ããªãã«ãã
TCP_NODELAY
æå¹ã«ããŸãã ãã ãããšãã¹ããŒãïŒããã³å®éã®TCPãšãã¹ããŒãããã®ã³ãŒããæžããïŒã§ããããã®ã³ãã³ãã©ã€ã³ãå
¥åããã«ãåã«ãããå¿ããŠããŸãããšããããŸãã
ååãšããŠããããã®2ã€ã®ã¢ã«ãŽãªãºã ãã©ã®ããã«ç«¶åããã®ãããªããã®ãããªåé¡ãçºçããã®ãã«ã€ããŠãã€ã³ã¿ãŒãããäžã§å€ãã®èª¬æããããŸãã æ°ã«å
¥ã£ãèšäºãžã®ãªã³ã¯ãæäŸããŸã
ãNagleã®ã¢ã«ãŽãªãºã ãšDelayed ACKã®çžäºäœçšã«ãã£ãŠåŒãèµ·ããããTCPããã©ãŒãã³ã¹ã®åé¡ãã®åé¡ã®è©³çŽ°ãªèª¬æã¯ãäŒè©±ã®ç¯å²ãè¶
ããŠããŸãã
TCP_NODELAY
å«ããŠ1è¡ã ãè¿œå ããåŸã次ã®ããã©ãŒãã³ã¹åäžãåŸãããŸããã

ããŒã»ã³ããŒãžã¯ãããã§ãæ°ããŸããã
é埳ïŒããã¯Javaã®åé¡ã§ã¯ãªããTCPã¹ã¿ãã¯ãšãã®æ§æã®åé¡ã§ãã å€ãã®å°åã§ãæåãªåŠæ ¡ããããŸãã ããç¥ãããŠããã®ã§ã人ã
ã¯ããããå¿ããŠããŸãã ãããã«ã€ããŠç¥ãããšããå§ãããŸãã ãã®åéã«æ
£ããŠããªãå Žåã¯ãååšããäž»èŠãªæµ
ç¬ãç°¡åã«ã°ãŒã°ã«æ€çŽ¢ã§ããŸãã éåžžã«è¿
éã«åé¡ãªããã§ãã¯ã§ããŸãã
ããªãã¯ããªãã®äž»é¡é åã®æåãªæšªæ£ã®ãªã¹ããç¥ãå¿
èŠããããŸãïŒãããŠå¿ããªãã§ãã ããïŒãå€æŽ2.ãããŒå¶åŸ¡ãŠã£ã³ããŠ
æåã®å€æŽããããä»æ§ãèªãå¿
èŠãããããŸããã§ããã 1ç§ããã9600ã®èŠæ±ãå€æããŸããããJettyã11,000ãäžããããšãæãåºããŠãã ããã次ã«ãä»»æã®ãããã¡ã€ã©ãŒã䜿çšããŠãããã¡ã€ãªã³ã°ããŸãã
ããã«ç§ãåŸããã®ããããŸãïŒ

ãããŠãããã¯ãã£ã«ã¿ãŒããããªãã·ã§ã³ã§ãïŒ

ç§ã®ãã³ãããŒã¯ã¯CPUæéã®93ïŒ
ããããŸãã
ãµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ããã«ã¯37ïŒ
ããããŸãã 次ã«ããã¹ãŠã®å
éšè©³çŽ°ããã¬ãŒã ã®æäœãããã³19ïŒ
ã®çµããã«æ¥ãŸã-ããã¯SocketChannelã®ãšã³ããªã§ãã ãªã¯ãšã¹ãã®ããŒã¿ãšããããŒã¯ãHTTPã«ããã¯ããªã®ã§ã転éããŸãã ãããŠã
readBody()
ãèªã¿åããŸãã
次ã«ããµãŒããŒããéãããŠããããŒã¿ãèªã¿åãå¿
èŠããããŸãã ããã§ã¯äœã§ããïŒ

ãšã³ãžãã¢ãã¡ãœããã«æ£ããååãä»ããããããä¿¡é Œããå Žåãããã§ãµãŒããŒã«äœããéä¿¡ããŸããããã«ã¯ããªã¯ãšã¹ããéä¿¡ããã®ãšåããããæéãããããŸãã ãµãŒããŒå¿çãèªã¿åããšãã«äœããéä¿¡ããã®ã¯ãªãã§ããïŒ
ãã®è³ªåã«çããã«ã¯ãä»æ§ãèªãå¿
èŠããããŸããã
äžè¬ã«ãããã©ãŒãã³ã¹ã«é¢ããå€ãã®åé¡ã¯ãä»æ§ãç¥ããªããŠã解決ãããŸãã
ArrayList
ã
LinkedList
ãŸãã¯ãã®éã«ããŸãã¯
Integer
ã
int
ãªã©ã«çœ®ãæããå¿
èŠãããå Žæã ãã®æå³ã§ããã³ãããŒã¯ãããã°éåžžã«è¯ãã§ãã 枬å®-æ£ãã-åäœããŸãã ãŸããä»æ§ã«åŸã£ãŠã©ã®ããã«æ©èœãããã«ã€ããŠã¯è©³ãã説æããŸããã
ããããç§ãã¡ã®å Žåãåé¡ã¯ä»æ§ã§å®éã«æããã«ãããŸãããHTTP2æšæºã«ã¯ããããããããŒå¶åŸ¡ããããŸãã 次ã®ããã«æ©èœããŸãã 2ã€ã®ãã¢ããããŸãã1ã€ã¯ããŒã¿ãéä¿¡ãããã1ã€ã¯åä¿¡ããŸãã éä¿¡è
ïŒéä¿¡è
ïŒã«ã¯ãŠã£ã³ããŠããããŸã-ç¹å®ã®ãã€ãæ°ïŒ16 KBãšä»®å®ïŒã®ãµã€ãºã®ãããŒå¶åŸ¡ãŠã£ã³ããŠã

8 KBãéä¿¡ãããšããŸãã ãããŒå¶åŸ¡ãŠã£ã³ããŠã¯ããããã®8 KBåæžãããŸãã

ããã«8 KBãéä¿¡ããåŸããããŒå¶åŸ¡ãŠã£ã³ããŠã¯0 KBã«ãªããŸããã

æšæºã§ã¯ããã®ç¶æ³ã§ã¯ãç§ãã¡ã«ã¯äœãéä¿¡ããæš©å©ããããŸããã ããŒã¿ãéä¿¡ããããšãããšãåä¿¡è
ã¯ãã®ç¶æ³ããããã³ã«ãšã©ãŒãšããŠè§£éããæ¥ç¶ãéããå¿
èŠããããŸãã ããã¯å€ãã®å ŽåãDDOSã«å¯Ÿããäžçš®ã®ä¿è·ã§ãããããäœåãªãã®ã¯éä¿¡ããããã¡ãã»ã³ãžã£ãŒã¯åä¿¡è
ã®åž¯åå¹
ã«åãããŠèª¿æŽãããŸãã

åä¿¡è
ãåä¿¡ããŒã¿ãåŠçãããšãããããŒå¶åŸ¡ãŠã£ã³ããŠãå¢ãããã€ãæ°ã瀺ãWindowUpdateãšåŒã°ããç¹å¥ãªå°çšä¿¡å·ãéä¿¡ããå¿
èŠããããŸããã

WindowUpdateãéä¿¡è
ã«å°çãããšããã®ãããŒå¶åŸ¡ãŠã£ã³ããŠãå¢å ããããŒã¿ãããã«éä¿¡ã§ããŸãã
ã¯ã©ã€ã¢ã³ãã§äœãèµ·ãã£ãŠããŸããïŒ
ãµãŒããŒããããŒã¿ãååŸããŸãã-ãããå®éã®åŠçã§ãã
ç¹å®ã®
dataFrame
-ããŒã¿ãã¬ãŒã ã ããŒã¿éã調ã¹ãŠåŠçããWindowUpdateãè¿éããŠããããŒå¶åŸ¡ãŠã£ã³ããŠãç®çã®å€ã ãå¢ãããŸããã
å®éãããããã®å Žæã§2ã€ã®ãããŒå¶åŸ¡ãŠã£ã³ããŠãæ©èœããŸãã ãã®ããŒã¿ã¹ããªãŒã ïŒèŠæ±ïŒå°çšã®ãããŒå¶åŸ¡ãŠã£ã³ããŠããããæ¥ç¶å
šäœã«å
±éã®ãããŒå¶åŸ¡ãŠã£ã³ããŠããããŸãã ãããã£ãŠã2ã€ã®WindowUpdateãªã¯ãšã¹ããéä¿¡ããå¿
èŠããããŸãã
ãã®ç¶æ³ãæé©åããæ¹æ³ã¯ïŒ
æåã®ãã®ã
while
ã®æåŸã«ãæåŸã®ããŒã¿ãã¬ãŒã ãéä¿¡ãããããšã瀺ããã©ã°ããããŸãã æšæºã§ã¯ãããã¯ããŒã¿ããã以äžæ¥ãªãããšãæå³ããŸãã ãããŠãããè¡ããŸãïŒ
ããã¯å°ããªæé©åã§ããã¹ããªãŒã çµäºãã©ã°ããã£ããããå Žåããã®ã¹ããªãŒã ã«å¯ŸããŠWindowUpdateã¯éä¿¡ã§ããªããªããŸããããŒã¿ãåŸ
æ©ããªããªãããµãŒããŒã¯äœãéä¿¡ããŸããã
äºçªç®ã WindowUpdateãæ¯åéä¿¡ããå¿
èŠããããšèšãã®ã¯èª°ã§ããïŒ å€æ°ã®ãªã¯ãšã¹ããåä¿¡ããã®ã«ãåä¿¡ããããŒã¿ãåŠçããŠãããåä¿¡ãããã¹ãŠã®ãªã¯ãšã¹ãã«WindowUpdateãéä¿¡ã§ããªãã®ã¯ãªãã§ããïŒ
ç¹å®ã®ãããŒå¶åŸ¡ãŠã£ã³ããŠã§åäœãã
WindowUpdater
ã¯æ¬¡ã®
WindowUpdater
ã§ãã
final AtomicInteger received; final int threshold; ... void update(int delta) { if (received.addAndGet(delta) > threshold) { synchronized (this) { int tosend = received.get(); if( tosend > threshold) { received.getAndAdd(-tosend); sendWindowUpdate(tosend); } } } }
äžå®ã®
threshold
ãŸãã ããŒã¿ãåä¿¡ããŸãããäœãéä¿¡ããŸããã ãã®
threshold
åã«ããŒã¿ãåéãããšããã«ããã¹ãŠã®WindowUpdateãéä¿¡ããŸãã
threshold
ããããŒå¶åŸ¡ãŠã£ã³ããŠã®ååã«è¿ã
threshold
ããŸãæ©èœããç¹å®ã®ãã¥ãŒãªã¹ãã£ãã¯ããããŸãã æåã«ãã®ãŠã£ã³ããŠã64 KBã«ããŠããããã8 KBãååŸããå Žåãåèš32 KBã®ããŒã¿ãã¬ãŒã ãããã€ãåä¿¡ãããšããã«ããŠã£ã³ããŠã¢ããããŒã¿ãŒãããã«32 KBã«éä¿¡ããŸãã éåžžã®ãããåŠçã è¯å¥œãªåæã®ããã«ãå®å
šã«éåžžã®äºéãã§ãã¯ãè¡ããŸãã
1ãã€ãã®ãªã¯ãšã¹ãã®å ŽåïŒ

å¹æã¯ãå€ãã®ãã¬ãŒã ãããã¡ã¬ãã€ããªã¯ãšã¹ãã§ãçºçããŸãã ãããããã¡ããã圌ã¯ããã»ã©ç®ç«ã¡ãŸããã å®éã«ã¯ãããŸããŸãªãã³ãããŒã¯ãããŸããŸãªãµã€ãºã®èŠæ±ããããŸããã ããããããã§ã¯ããããã®å Žåã«ã°ã©ãã£ãã¯ãæç»ããŸããã§ããããç°¡åãªäŸãåãäžããŸããã ãã詳现ãªããŒã¿ã®çµã蟌ã¿ã¯å°ãåŸã§è¡ãããŸãã
+ 23ïŒ
ããåŸãããŸããã§ããããJettyã¯ãã§ã«è¿œãè¶ããŠããŸãã
é埳ïŒ
ä»æ§ã泚ææ·±ãèªãã§ãããžãã¯ã¯ããªãã®åéã§ããä»æ§ã«ã¯ããã€ãã®ãã¥ã¢ã³ã¹ããããŸãã äžæ¹ã§ã¯ãããŒã¿ãã¬ãŒã ãåä¿¡ããããWindowUpdateãéä¿¡ããå¿
èŠããããŸãã ããããä»æ§ã泚ææ·±ãèªãã§ã次ã®ããšãããããŸããåä¿¡ããåãã€ãã«WindowUpdateãéä¿¡ããå¿
èŠã¯ãããŸããã ãããã£ãŠãä»æ§ã§ã¯ããããŒå¶åŸ¡ãŠã£ã³ããŠã®ãã®ãããªãããæŽæ°ãèš±å¯ãããŠããŸãã
å€æŽ3.ããã¯
ã¹ã±ãŒãªã³ã°ïŒã¹ã±ãŒãªã³ã°ïŒã®æ¹æ³ãåŠã³ãŸãããã
ãã®ã©ãããããã¯ãã¹ã±ãŒãªã³ã°ã«ã¯ããŸãé©ããŠããŸãããå®ã«ãŒãã«ãšåœã®ã«ãŒãã«ã¯2ã€ãããããŸããã 48åã®ããŒããŠã§ã¢ã¹ã¬ããããããµãŒããŒãã·ã³ã䜿çšããŠããã³ãããŒã¯ãå®è¡ããŸãã
ããã§ãæ°Žå¹³æ¹å-ã¹ã¬ããæ°ãããã³åçŽæ¹åã¯åèšã¹ã«ãŒãããã瀺ããŸãã

ããã§ã¯ãæ倧4ã€ã®ã¹ã¬ãããéåžžã«ããŸãã¹ã±ãŒãªã³ã°ãããŠããããšãããããŸãã ããããããã«ãã¹ã±ãŒã©ããªãã£ã¯éåžžã«æªããªããŸãã
ã©ãããŠãããå¿
èŠãªã®ã§ããããïŒ ã¯ã©ã€ã¢ã³ãã¯1人ã§ãã 1ã€ã®ã¹ã¬ãããããµãŒããŒããå¿
èŠãªããŒã¿ãååŸãããããå¿ããŸãã ããããæåã«ãéåæããŒãžã§ã³ã®APIããããŸãã ç§ãã¡ã¯åã³åœŒå¥³ã«æ¥ãŸãã ããããããã€ãã®ã¹ã¬ããããããŸãã 第äºã«ãç§ãã¡ã®äžçã®ãã¹ãŠããã«ãã³ã¢ã«ãªããã©ã€ãã©ãªå
ã®å€ãã®ã¹ã¬ããã§ããŸãåäœã§ããããšã¯ã誰ããã·ã³ã°ã«ã¹ã¬ããããŒãžã§ã³ã®ããã©ãŒãã³ã¹ã«ã€ããŠäžå¹³ãèšãå§ãããšãã«ããã«ãã¹ã¬ããã«åãæ¿ããããšãå§ããããå Žåã«ã®ã¿æçšã§ããããŠå©çãåŸãã ãããã£ãŠãã¹ã±ãŒã©ããªãã£ãäœãå 害è
ãæ¢ããŸãããã ç§ã¯éåžžãã®ããã«ããŸãïŒ
#!/bin/bash (java -jar benchmarks.jar BenchHttpGet.get -t 4 -f 0 &> log.log) & JPID=$! sleep 5 while kill -3 $JPID; do : done
ã¹ã¿ãã¯ãã¬ãŒã¹ããã¡ã€ã«ã«æžã蟌ãã ãã§ãã å®éã«ã¯ããããã¡ã€ã©ãŒã䜿çšããã«ããã¯ãæäœããå Žåã®90ïŒ
ã®å Žåãããã§ååã§ãã ããã€ãã®è€éãªããªãã¯ã®å Žåã«ã®ã¿ãããã·ã§ã³ã³ã³ãããŒã«ãŸãã¯ä»ã®äœããèµ·åããããã¯ã®ååžãç£èŠããŸãã
ãã°ã§ã¯ãããŸããŸãªã¹ã¬ãããããç¶æ
ã確èªã§ããŸãã

ããã§ã¯ãã€ãã³ããçºçããã®ãåŸ
ã€ã®ã§ã¯ãªãããŸãã«ããã¯ã«é¢å¿ããããŸãã ããã¯ã¯3äžä»¶ãããããã¯20äžä»¶ã®å®è¡å¯èœãã¡ã€ã«ã«å¯ŸããŠããªãã®éã§ãã
ãããããã®ãããªã³ãã³ãã©ã€ã³ã¯åã«ç¯äººã衚瀺ããŸãïŒäœåãªãã®ã¯å¿
èŠãããŸãã-ã³ãã³ãã©ã€ã³ã ãã§ãïŒã

ç¯äººã¯æãŸã£ãã ããã¯ãããŒã¿ãã¬ãŒã ããµãŒããŒã«éä¿¡ããã©ã€ãã©ãªå
ã®ã¡ãœããã§ãã æ£ããããŸãããã
void sendFrame(Http2Frame frame) { synchronized (sendlock) { try { if (frame instanceof OutgoingHeaders) { OutgoingHeaders oh = (OutgoingHeaders) frame; Stream stream = registerNewStream(oh); List frames = encodeHeaders(oh, stream); writeBuffers(encodeFrames(frames)); } else { writeBuffers(encodeFrame(frame)); } } catch (IOException e) { ... } } }
ããã«ã°ããŒãã«ã¢ãã¿ãŒããããŸãã

ãããããã®ãã©ã³ã-

-ãªã¯ãšã¹ãã®éå§ã®éå§ã ããã«ãããæåã®ããããŒããµãŒããŒã«éä¿¡ãããŸãïŒããã§ã¯è¿œå ã®ã¢ã¯ã·ã§ã³ãããã€ãå¿
èŠã§ããä»ãã説æããŸãïŒã
ããã«ãããä»ã®ãã¹ãŠã®ãã¬ãŒã ããµãŒããŒã«éä¿¡ãããŸãã

ããã¯ãã¹ãŠã°ããŒãã«ããã¯äžã§ãïŒ
sendFrame
èªäœã¯ãå¹³åã§55ïŒ
ã®æéãããããŸãã

ãã ãããã®æ¹æ³ã§ã¯1ïŒ
ããããŸãã

ã°ããŒãã«ããã¯ããäœãåãåºãããšãã§ããããç解ããŠã¿ãŸãããã
æ°ããããã¯ã¹ããªãŒã ã®ç»é²ã¯ååŸã§ããŸããã HTTPæšæºã¯ãã¹ããªãŒã ã®çªå·ä»ãã«å¶éã課ããŠããŸãã
registerNewStream
æ°ããã¹ããªãŒã ãçªå·ãååŸããŸãã ããŒã¿ã®è»¢éã®ããã«ã15ã17ã19ã21ã®çªå·ã§ã¹ããªãŒã ãéå§ãã21ã15ãéä¿¡ããå Žåãããã¯ãããã³ã«ãšã©ãŒã«ãªããŸãã çªå·ã®æé ã§éä¿¡ããå¿
èŠããããŸãã ããã¯ã®äžããããããåãåºããå Žåããããã¯ç§ãåŸ
ã€é çªã§éä¿¡ãããªãå ŽåããããŸãã
ããã¯ã®äžããé€å»ã§ããªã2çªç®ã®åé¡ïŒ

ããã¯ãããããŒãå§çž®ãããå Žæã§ãã
éåžžã®åœ¢åŒã§ã¯ãèŠåºãã«ã¯éåžžã®ããã-key-valueïŒstring to stringïŒãæ·»ä»ãããŸãã
encodeHeaders
ã¯ããããŒãå§çž®ããŸãã ãããŠãããã§HTTP 2æšæºã®2çªç®ã®ã¬ãŒãã¯ãã¹ããŒããã«å§çž®ã§æ©èœããHPACKã¢ã«ãŽãªãºã ã§ãã ã€ãŸã ç¶æ
ããããŸãïŒãããã£ãŠãéåžžã«ããå§çž®ãããŸãïŒã 2ã€ã®ãªã¯ãšã¹ããéä¿¡ãããå ŽåïŒ2ã€ã®ããããŒïŒãæåã«1ã€ãå§çž®ãã次ã«2ã€ç®ãå§çž®ããŠããããµãŒããŒã¯åãé åºã§ããããåä¿¡ããå¿
èŠããããŸãã å¥ã®é åºã§åãåã£ãå Žåããã³ãŒãã§ããŸããã ãã®åé¡ãã·ãªã¢ã«åãã€ã³ãã§ãã ãã¹ãŠã®HTTPãªã¯ãšã¹ãã®ãã¹ãŠã®ãšã³ã³ãŒãã£ã³ã°ã¯åäžã®ã·ãªã¢ã«åãã€ã³ããééããå¿
èŠãããããããã¯äžŠè¡ããŠåäœã§ããããã®åŸã§ããšã³ã³ãŒãããããã¬ãŒã ãéä¿¡ããå¿
èŠããããŸãã
encodeFrame
ã¡ãœããã¯6ïŒ
ã®æéãèŠããçè«çã«ã¯ããã¯ç¶æ
ããåé€ã§ããŸãã

encodeFrames
ã¯ãä»æ§ã§å®çŸ©ãããŠãã圢åŒã§ãã¬ãŒã ããã€ããããã¡ãŒã«ããããããŸãïŒãã¬ãŒã ã®å
éšæ§é ãæºåããåã«ïŒã 6ïŒ
ã®æéãããããŸãã
ãœã±ãããžã®å®éã®èšé²ãè¡ãããã¡ãœãããé€ããããã¯ã®äžãã
encodeFrames
ã
encodeFrames
劚ãããã®ã¯ãããŸããã

å®è£
ã«ã¯ããã€ãã®åŸ®åŠãªéãããããŸãã
encodeFrames
ã¯ããã¬ãŒã ã1ã€ã§ã¯ãªããããã€ãã®ãã€ããããã¡ãŒã«ãšã³ã³ãŒãã§ããããšã
encodeFrames
ã ããã¯ãäž»ã«å¹çæ§ã«ãããã®ã§ãïŒã³ããŒãå€ãããªãããã«ããããïŒã
writeBuffers
ããã¯ãã
writeBuffers
ããããšããŠã2ã€ã®ãã¬ãŒã ã®
writeBuffers
ãæ··åšããŠããå Žåããã¬ãŒã ããã³ãŒãã§ããŸããã ã€ãŸã ããçš®ã®ååæ§ãæäŸããå¿
èŠããããŸãã åæã«ã
writeBuffers
ã¯
writeBuffers
å
ã§å®è¡ããããœã±ãããžã®æžã蟌ã¿ã«ã¯ç¬èªã®ã°ããŒãã«ããã¯ããããŸãã
æåã«é ã«æµ®ãã¶ã®ã¯ããã¥ãŒã®é çªã§ãã ãã®ãã¥ãŒã«ãã€ããããã¡ãŒãæ£ããé åºã§é
眮ããå¥ã®ã¹ã¬ããã«èªã¿åãããŸãã
ãã®å Žåã
writeBuffers
ã¡ãœããã¯éåžžããã®ã¹ã¬ãããæ®ããŸãã ãã®ããã¯ã®äžã«ä¿æããå¿
èŠã¯ãããŸããïŒç¬èªã®ã°ããŒãã«ããã¯ããããŸãïŒã ç§ãã¡ã«ãšã£ãŠã®äž»ãªããšã¯ãããã«æ¥ããã€ããããã¡ã®é åºãä¿èšŒããããšã§ãã
ããã§ãæãå°é£ãªæäœã®1ã€ãå€éšã§åé€ããè¿œå ã®ã¹ã¬ãããèµ·åããŸããã ã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã®ãµã€ãºã60ïŒ
å°ãããªããŸããã
ããããå®è£
ã«ã¯æ¬ ç¹ããããŸãã
- HTTP 2æšæºã®äžéšã®ãã¬ãŒã ã§ã¯ãé åºã«å¶éããããŸãã ãã ããä»ã®ä»æ§ãã¬ãŒã ã¯ããæ©ãéä¿¡ã§ããŸãã ä»ã®åã«éä¿¡ã§ããåãWindowUpdateã ãããŠããµãŒããŒãç«ã£ãŠããã®ã§ãããããããããšæããŸã-ããã¯åŸ
ã£ãŠããŸãïŒãããŒå¶åŸ¡ãŠã£ã³ããŠ= 0ãæã£ãŠããŸãïŒã ãã ããå®è£
ã§ã¯ãããèš±å¯ãããŠããŸããã
- 2çªç®ã®åé¡ã¯ããã¥ãŒã空ã®å Žåãéä¿¡ã¹ããªãŒã ãã¹ãªãŒãç¶æ
ã«ãªããé·æéèµ·åããããšã§ãã
ãã¬ãŒã ã®é åºã«é¢ããæåã®åé¡ã解決ããŸãããã
æçœãªã¢ã€ãã¢ã¯
Deque<ByteBuffer[]>
ã§ãã
äœãšãæ··åã§ããªããã€ããããã¡ã®åã£ãŠãåããªãã¹ã©ã€ã¹ããããŸãã é
åã«å
¥ããé
åèªäœããã¥ãŒã«å
¥ããŸãã 次ã«ããããã®é
åãäžç·ã«æ··åšãããããšãã§ããåºå®ãããé åºãå¿
èŠãªå Žåã¯ããããæäŸããŸãã
- ByteBuffer []-ãããã¡ã®ã¢ãããã¯ã·ãŒã±ã³ã¹ã
- WindowUpdateFrame-ãã¥ãŒã®äžçªäžã«é
眮ããããããã³ã°ããå®å
šã«åé€ã§ããŸãïŒãããã³ã«ãšã³ã³ãŒãã£ã³ã°ãçªå·ä»ãããããŸããïŒã
- DataFrame-ããã¯ããåãåºããŠãã¥ãŒã®æåŸã«çœ®ãããšãã§ããŸãã ãã®çµæãããã¯ã¯ã©ãã©ãå°ãããªã£ãŠããŸãã
é·æïŒ
- ããå°ãªãããã¯ã
- Window Updateãæ©æã«éä¿¡ãããšããµãŒããŒã¯ããŒã¿ãæ©æã«éä¿¡ã§ããŸãã
ããããããã«ã¯ãã1ã€ãã€ãã¹ããããŸããã åãšåæ§ã«ãéä¿¡ã¹ããªãŒã ã¯ãã°ãã°ã¹ãªãŒãç¶æ
ã«ãªããé·æéèµ·åããŸãã
ããããã£ãŠã¿ãŸãããïŒ

å°ãåããŸãã ãã®äžã«ãåä¿¡ãããã€ããããã¡ãŒã®é
åãè¿œå ããŸãã ãã®åŸãããã¯å€ã®ãã¹ãŠã®ã¹ã¬ããéã®ç«¶åãæé
ããŸãã åã£ã人ã¯èª°ã§ããœã±ããã«æžã蟌ã¿ãŸãããã ãããŠãæ®ãã®äœæ¥ãããŸãããã
flush()
ã¡ãœããã«ã¯ãå¹æãããããå¥ã®æé©åãè¡ãããŠããããšã«æ³šæããŠãã ããïŒå€§éã®å°ããªããŒã¿ïŒããšãã°ã3ãã4ãããã¡ãŒã®10é
åïŒãšæå·åãããSSLæ¥ç¶ãããå Žåããã¥ãŒããè€æ°ã®é
åãååŸã§ããŸãããã倧ããªæçã§ãããããSSLEngineã«éä¿¡ããŸãã ãã®å Žåãã³ãŒãã£ã³ã°ã®ã³ã¹ãã¯å€§å¹
ã«åæžãããŸãã
æ瀺ããã3ã€ã®æé©åã®ããããã«ãããã¹ã±ãŒãªã³ã°ã®åé¡ãéåžžã«ããŸã解決ã§ããŸããã ãã®ãããªãã®ïŒå
šäœçãªå¹æãåæ ïŒïŒ

é埳ïŒ
ããã¯ã¯æªã§ãïŒããã¯ã解é€ããå¿
èŠãããããšã¯èª°ããç¥ã£ãŠããŸãã ããã«ã䞊è¡ã©ã€ãã©ãªãŒã¯ãŸããŸãé«åºŠã§èå³æ·±ããã®ã«ãªã£ãŠããŸãã
å€æŽ4.ããŒã«ãGCãïŒ
HTTP Client, 100% ByteBufferPool. ⊠, â - , â ⊠ByteBuffer , ⊠. , . ( ):
- 20% ;
- ByteBufferPool.getBuffer() 12% .
, â . . : , ByteBuffer , , public API.
? :
- , ! eg Dr. Cliff Click, Brian Goetz, Sergey Kuksenko, Aleksey Shipilšev,âŠ
- , â . ! eg Netty (blog.twitter.com/2013/netty-4-at-twitter-reduced-gc-overhead),âŠ
DirectByteBuffer HeapByteBuffer
, â HTTPClient: DirectByteBuffer HeapByteBuffer?
:
- DirectByteBuffer I/O.
sun.nio.* HeapByteBuffer DirectByteBuffer;
- HeapByteBuffer SSL.
SSLEngine byte[] HeapByteBuffer.
, DirectByteBuffer . Write- nio, , HeapByteBuffer DirectByteBuffer-. DirectByteBuffer, .
â SSL-. HTTP 2 plain connection, SSL connection, , SSL - . , OpenJDK, , SSLEngine HeapByteBuffer, byte[] . DirectByteBuffer , .
, HeapByteBuffer :
- PlainConnection â HeapByteBuffer «» 0%-1% â , 0 â 1% â . DirectByteBuffer , ;
- SSLConnection â HeapByteBuffer 2%-3%
ã€ãŸã HeapByteBuffer â !
, DirectByteBuffer , . , unsafe. HeapByteBuffer â intrinsic ( ). .
HeapByteBuffer 2-3% , DirectByteBuffer, , DirectByteBuffer. .
.
1:
- . , .
- ( ConcurrentLinkedQueue).
- ( ). , . , Jetty ByteBufferPool, - 1 . ByteBufferPool, . , :
- SSL (SSLSession.getPacketBufferSize());
- (MAX_FRAME_SIZE);
- .
1:
çæïŒ
- . ? , ByteBuffer -, , , . , -. . , ;
- « »;
- ( );
- , :
ByteBuffer.slice()
ByteBuffer.wrap()
. ByteBuffer, - , , slice(). slice() . , . , . , - . , 128 , -, 128 , . , . â -. - . , . , .
2: â GC
GC , DirectByteBuffer, HeapByteBuffer.
- , Public API, , - .
- , , GC, â
ByteBuffer.slice()
/ wrap()
â .
é·æïŒ
- ;
- «public API»;
- « »;
- , ;
- .
:
- -, â «allocation pressure»
- , , . , I/O, , 32 , 16 . 12 . ? . ( ) â 12 16 .
3:
. . .
:
- . , HPACK, â . â GC .
- HTTP- â , - .
- â (GC )
:
- â - â 16 32 ;
- (DataFrame) â
slice()
(GC );
- â .
HTTP 2 . (, ), - , - . , slice, , â GC.
SSL-, .
:
- ( -, , , );
- «public API»;
- « »;
- ;
- ;
- .
â : «allocation pressure».
, , , . . . 32 , 32 . . baseline â ( 100%). allocation rate baseline .

, , . , , , . allocation rate? GC-:

GC- allocation rate .
, ( ) 25% . 27% , 36% . .
10% , , .
: , public API .
å°èš
, . , .
HttpClient JettyClient . â ; â .

GET- Jetty. . . , , - , Java 9 Java 10 HttpClient .
POST- . PLAIN- Jetty - . SSL- .

post-? : SSL- lock â SocketChannel. . JDK, nio â , . , bottleneck.
SSL ( encryption) . SSLEngine encryption / decryption. . encryption , . SSL-. . , - OpenSSL-.
5. API
.
API?
public <T> HttpResponse<T> send(HttpRequest req, HttpResponse.BodyHandler<T> responseHandler) { ... } public <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest req, HttpResponse.BodyHandler<T> responseHandler) { return CompletableFuture.supplyAsync(() -> send(req, responseHandler), executor); }
executor â (executor ; executor, , , executor).
, API:

, - .
. â , ⊠.

1 â CompletableFuture
, wait condition. API, Async executor, executor .
, . â API, API executor. fixed thread pool ( executor, ).
, executor- . , , - . - , executor- . ããã ãã§ã å°çããŸããã
, CompletableFuture. ãã®ãããªãã®ïŒ

. . thenCompose, future, future. C , thread- SelectorManager. , . , complete.
thenCompose , future, , , ( CompletableFuture), . executor, - , executor-, . CompletableFuture, . . . .
condition wait, CompletableFuture. CompletableFuture , . +40% .
2 â
. , . , CompletableFuture. â thenSomething. «Something» Compose, Combine, Apply â CompletableFuture. CompletableFuture.
foo â , â ?

â .
â .. thenSomething â CompletableFuture , foo . CompletableFuture , complete , .. . .
, . , sendAsync. ã€ãŸã , sendAsync, CompletableFuture . executor , , .
Java- . : , CompletableFuture :

( ), . â 3% . , , , , . , , .. . , executor-.
, , Compose Async. thenCompose
thenComposeAsync()
, , , .
:
çæïŒ
- executor' executor' (). ,
thenComposeAsync
, thenApplyAsync
Async CompletableFuture executor-, executor- ( Async), fork-join executor. CompletableFuture , ? - â .
:
CompletableFuture<Void> start = new CompletableFuture<>(); start.thenCompose(v -> sendHeader()) .thenCompose(() -> sendBody()) .thenCompose(() -> getResponseHeader()) .thenCompose(() -> getResponseBody()) ...; start.completeAsync( () -> null, executor);
CompletableFuture, , , . CompletableFuture â
completeAsync
â executor. 10% .
3 â complete()
, CompletableFuture:

CompletableFuture SelectorManager CompletableFuture .
future.complete
. , SelectorManager â , . CompletableFuture. . response.complete SelectorManager , SelectorManager, , . - â executor, .
.

completeAsync
.

completeAsync
, .
executor executor . SelectorManager executor - executor. executor- , . .
CompleteAsync
. Async.

. , , â .
é·æïŒ
çæïŒ
: , CompletableFuture ? CompletableFuture â Async. â , CompletableFuture , executor .

, .
16% .
CompletableFuture 80%.
:
.CompletableFuture (
since 1.8)
6
HTTP Client , Public API. . .

, , executor. HTTP Client executor, ,
CachedThreadPool()
.
,
CachedThreadPool()
. , :

CachedThreadPool()
. . ,
CachedThreadPool()
, . , â , , . , , .
, ( ), , ,
CachedThreadPool()
20 â . 100 out of memory exception. â , .
, , « ». , , .
CachedThreadPool()
12 . 100 800 . , .
CachedThreadPool()
executor . , ,
CachedThreadPool()
executor . â . , .
ThreadPool executor. . ,
CachedThreadPool()
:

â , â bottleneck, , SSLEngine . .
:
ThreadPool' .HTTP 2 Client .
, , Java API. -, . , . JDK â , API.
Norman Maurer , . â , :
Writing Highly Performant Network Frameworks on the JVM â A Love-Hate Relationship .
API JDK , API . , JDK, Netty. , , .
Java , ,
JPoint 2018 :