Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[SnowOne 2024] Григорий Кошелев: Undertow — анд...

jugnsk
April 30, 2024

[SnowOne 2024] Григорий Кошелев: Undertow — андер...что?

Undertow — веб-сервер, который находится под капотом у сервера приложений WildFly, а также один из трёх веб-серверов в Spring Boot.

Разберёмся, как устроен Undertow и нужно ли его тащить в свой проект.

jugnsk

April 30, 2024
Tweet

More Decks by jugnsk

Other Decks in Programming

Transcript

  1. План — Историческая справка — Архитектура Undertow — IO-intensive приложения

    — Undertow + XNIO — Производительность и оптимизации 2
  2. Историческая справка Undertow 1.0 — 10 февраля 2014 2009 5

    март 2013 наши дни Undertow 1.0 — 10.02.2014
  3. Историческая справка WildFly 8.0 — 12 февраля 2014 2009 наши

    дни https://www.wildfly.org/news/2014/02/12/WildFly8-Final-Released/ 6 Undertow 1.0 — 10.02.2014 WildFly 8.0 — 12.02.2014
  4. WildFly 8.0 Undertow, the new cutting-edge web server in WildFly

    8, is designed for maximum throughput and scalability, including environments with over a million connections. It supports non-blocking and blocking handlers, traditional and asynchronous servlets, and JSR-356 web socket handlers. It is highly customizable, with the ability for applications to implement nearly anything from dynamic request routing to custom protocols. It can also function as a very efficient, pure non-blocking reverse proxy, allowing WildFly to delegate to other web servers with minimal impact to running applications. This release adds numerous improvements including greater extensibility and enhanced security capabilities. https://www.wildfly.org/news/2014/02/12/WildFly8-Final-Released/ 7
  5. WildFly 8.0 Undertow, the new cutting-edge web server in WildFly

    8, is designed for maximum throughput and scalability, including environments with over a million connections. It supports non-blocking and blocking handlers, traditional and asynchronous servlets, and JSR-356 web socket handlers. It is highly customizable, with the ability for applications to implement nearly anything from dynamic request routing to custom protocols. It can also function as a very efficient, pure non-blocking reverse proxy, allowing WildFly to delegate to other web servers with minimal impact to running applications. This release adds numerous improvements including greater extensibility and enhanced security capabilities. https://www.wildfly.org/news/2014/02/12/WildFly8-Final-Released/ 8
  6. WildFly 8.0 Undertow, the new cutting-edge web server in WildFly

    8, is designed for maximum throughput and scalability, including environments with over a million connections. It supports non-blocking and blocking handlers, traditional and asynchronous servlets, and JSR-356 web socket handlers. It is highly customizable, with the ability for applications to implement nearly anything from dynamic request routing to custom protocols. It can also function as a very efficient, pure non-blocking reverse proxy, allowing WildFly to delegate to other web servers with minimal impact to running applications. This release adds numerous improvements including greater extensibility and enhanced security capabilities. https://www.wildfly.org/news/2014/02/12/WildFly8-Final-Released/ 9
  7. WildFly 8.0 Undertow, the new cutting-edge web server in WildFly

    8, is designed for maximum throughput and scalability, including environments with over a million connections. It supports non-blocking and blocking handlers, traditional and asynchronous servlets, and JSR-356 web socket handlers. It is highly customizable, with the ability for applications to implement nearly anything from dynamic request routing to custom protocols. It can also function as a very efficient, pure non-blocking reverse proxy, allowing WildFly to delegate to other web servers with minimal impact to running applications. This release adds numerous improvements including greater extensibility and enhanced security capabilities. https://www.wildfly.org/news/2014/02/12/WildFly8-Final-Released/ 10
  8. WildFly 8.0 Undertow, the new cutting-edge web server in WildFly

    8, is designed for maximum throughput and scalability, including environments with over a million connections. It supports non-blocking and blocking handlers, traditional and asynchronous servlets, and JSR-356 web socket handlers. It is highly customizable, with the ability for applications to implement nearly anything from dynamic request routing to custom protocols. It can also function as a very efficient, pure non-blocking reverse proxy, allowing WildFly to delegate to other web servers with minimal impact to running applications. This release adds numerous improvements including greater extensibility and enhanced security capabilities. https://www.wildfly.org/news/2014/02/12/WildFly8-Final-Released/ 11
  9. Историческая справка WildFly 8.0 — 12 февраля 2014 2009 наши

    дни 13 Undertow 1.0 — 10.02.2014 WildFly 8.0 — 12.02.2014
  10. Историческая справка Spring Boot 1.2.0 — 11 декабря 2014 Undertow

    1.0 — 10.02.2014 WildFly 8.0 — 12.02.2014 2009 наши дни https://spring.io/blog/2014/12/11/spring-boot-1-2-0-released/ 14 Spring Boot 1.2.0 — 11.12.2014
  11. Историческая справка Vostok Hercules — апрель 2018 Undertow 1.0 —

    10.02.2014 WildFly 8.0 — 12.02.2014 апрель 2018 2009 наши дни https://github.com/vostok/hercules 15 Spring Boot 1.2.0 — 11.12.2014
  12. Историческая справка Vostok Hercules — апрель 2018 Undertow 1.0 —

    10.02.2014 WildFly 8.0 — 12.02.2014 апрель 2018 2009 наши дни 30 Spring Boot 1.2.0 — 11.12.2014
  13. Историческая справка Анонс Undertow 3.0 — апрель 2019 Undertow 1.0

    — 10.02.2014 WildFly 8.0 — 12.02.2014 апрель 2018 2009 апрель 2019 наши дни https://undertow.io/blog/2019/04/15/Undertow-3.html 31 Spring Boot 1.2.0 — 11.12.2014
  14. Историческая справка Анонс Undertow 3.0 — апрель 2019 * XNIO

    –> Netty https://undertow.io/blog/2019/04/15/Undertow-3.html 32 Undertow 1.0 — 10.02.2014 WildFly 8.0 — 12.02.2014 апрель 2018 2009 апрель 2019 наши дни Spring Boot 1.2.0 — 11.12.2014
  15. Историческая справка Анонс Undertow 3.0 — апрель 2019 * XNIO

    –> Netty * Смена лидера проекта https://undertow.io/blog/2019/04/15/Undertow-3.html 33 Undertow 1.0 — 10.02.2014 WildFly 8.0 — 12.02.2014 апрель 2018 2009 апрель 2019 наши дни Spring Boot 1.2.0 — 11.12.2014
  16. Историческая справка Анонс Undertow 3.0 — апрель 2019 * XNIO

    –> Netty * Смена лидера проекта https://undertow.io/blog/2019/04/15/Undertow-3.html 34 Undertow 1.0 — 10.02.2014 WildFly 8.0 — 12.02.2014 апрель 2018 2009 апрель 2019 наши дни Spring Boot 1.2.0 — 11.12.2014 Stuart Douglas -> Flavia Rainone
  17. Историческая справка ??? 35 Undertow 1.0 — 10.02.2014 WildFly 8.0

    — 12.02.2014 апрель 2018 2009 март 2019 наши дни Spring Boot 1.2.0 — 11.12.2014
  18. Историческая справка Supersonic Subatomic Java 36 Undertow 1.0 — 10.02.2014

    WildFly 8.0 — 12.02.2014 апрель 2018 2009 март 2019 наши дни Spring Boot 1.2.0 — 11.12.2014
  19. Историческая справка Supersonic Subatomic Java — Quarkus Undertow 1.0 —

    10.02.2014 WildFly 8.0 — 12.02.2014 апрель 2018 2009 Quarkus — март 2019 наши дни https://developers.redhat.com/blog/2019/03/07/quarkus-next-generation-kubernetes-native-java-framework 37 Spring Boot 1.2.0 — 11.12.2014
  20. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  21. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  22. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  23. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  24. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  25. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  26. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  27. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  28. Архитектура Undertow undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API for

    websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  29. IO-intensive приложения Что это такое? — Много входящего трафика —

    Много исходящего трафика Количество HTTP-запросов 52
  30. IO-intensive приложения Что это такое? — Много входящего трафика —

    Много исходящего трафика Количество HTTP-запросов x размер запросов 53
  31. IO-intensive приложения HTTP API HTTP API Kafka 63 «Интересные» места?

    Эффективная работа с тысячами коннекций
  32. IO-intensive приложения HTTP API HTTP API Kafka 64 «Интересные» места?

    Обработка медленных клиентов Эффективная работа с тысячами коннекций
  33. IO-intensive приложения HTTP API HTTP API Kafka 65 «Интересные» места?

    Эффективная работа с тысячами коннекций Обработка медленных клиентов Снижение нагрузки на GC
  34. IO-intensive приложения HTTP API HTTP API Kafka 66 «Интересные» места?

    Эффективная работа с тысячами коннекций Снижение нагрузки на GC Обработка медленных клиентов Эффективная отправка
  35. Undertow + XNIO undertow-servlet Servlet 3.1+ undertow-websockets-jsr JSR-356 (Java API

    for websockets) undertow-core XNIO Java NIO EPoll (Linux) KQueue (Mac, BSD)
  36. Undertow + XNIO Undertow server = Undertow.builder() .addHttpListener(8080, "localhost") .setHandler(Handlers.routing()

    .get("/hello/{any}", new MyHelloAnyHandler()) .post("/echo", new MyEchoHandler()) ).build(); server.start(); 68
  37. Undertow + XNIO Undertow server = Undertow.builder() .addHttpListener(8080, "localhost") .setHandler(Handlers.routing()

    .get("/hello/{any}", new MyHelloAnyHandler()) .post("/echo", new MyEchoHandler()) ).build(); server.start(); 69
  38. Undertow + XNIO Undertow server = Undertow.builder() .addHttpListener(8080, "localhost") .setHandler(Handlers.routing()

    .get("/hello/{any}", new MyHelloAnyHandler()) .post("/echo", new MyEchoHandler()) ).build(); server.start(); 70 1
  39. Undertow + XNIO Undertow server = Undertow.builder() .addHttpListener(8080, "localhost") .setHandler(Handlers.routing()

    .get("/hello/{any}", new MyHelloAnyHandler()) .post("/echo", new MyEchoHandler()) ).build(); server.start(); 71 2 1
  40. Undertow + XNIO Undertow server = Undertow.builder() .addHttpListener(8080, "localhost") .setHandler(Handlers.routing()

    .get("/hello/{any}", new MyHelloAnyHandler()) .post("/echo", new MyEchoHandler()) ).build(); server.start(); 72 1 2 3
  41. Undertow + XNIO 78 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread sun.nio.ch.EPollSelectorProvider openSelector()
  42. Undertow + XNIO 79 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() sun.nio.ch.EPollSelectorProvider openSelector()
  43. Undertow + XNIO 80 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() sun.nio.ch.EPollSelectorProvider openSelector() openSelector()
  44. Undertow + XNIO 81 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() sun.nio.ch.EPollSelectorProvider openSelector() openSelector() acceptQueue
  45. Undertow + XNIO 82 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() java.nio.channels. ServerSocketChannel sun.nio.ch.EPollSelectorProvider openSelector() openSelector() acceptQueue
  46. Undertow + XNIO 83 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() java.nio.channels. ServerSocketChannel sun.nio.ch.EPollSelectorProvider openSelector() openSelector() open() acceptQueue
  47. Undertow + XNIO 84 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() java.nio.channels. ServerSocketChannel java.net. InetSocketAddress sun.nio.ch.EPollSelectorProvider openSelector() openSelector() open() acceptQueue
  48. Undertow + XNIO 85 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() java.nio.channels. ServerSocketChannel java.net. InetSocketAddress sun.nio.ch.EPollSelectorProvider openSelector() openSelector() socket().bind() open() acceptQueue
  49. Undertow + XNIO 86 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() java.nio.channels. ServerSocketChannel java.net. InetSocketAddress sun.nio.ch.EPollSelectorProvider openSelector() openSelector() registerChannel() socket().bind() open() acceptQueue
  50. Undertow + XNIO 87 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() java.nio.channels. ServerSocketChannel java.net. InetSocketAddress sun.nio.ch.EPollSelectorProvider openSelector() openSelector() registerChannel() socket().bind() open() acceptQueue SelectionKey
  51. Undertow + XNIO 88 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() org.xnio.nio. NioTcpServerHandle java.nio.channels. ServerSocketChannel java.net. InetSocketAddress sun.nio.ch.EPollSelectorProvider openSelector() openSelector() registerChannel() socket().bind() open() acceptQueue SelectionKey
  52. Undertow + XNIO 89 java.nio.channels.spi. SelectorProvider acceptThread org.xnio.nio.WorkerThread ioThreads []

    org.xnio.nio.WorkerThread Runtime.getRuntime().availableProcessors() org.xnio.nio. NioTcpServerHandle java.nio.channels. ServerSocketChannel java.net. InetSocketAddress sun.nio.ch.EPollSelectorProvider openSelector() openSelector() registerChannel() socket().bind() open() acceptQueue SelectionKey attach()
  53. Undertow + XNIO Undertow server = Undertow.builder() .addHttpListener(8080, "localhost") .setHandler(Handlers.routing()

    .get("/hello/{any}", new MyHelloAnyHandler()) .post("/echo", new MyEchoHandler()) ).build(); server.start(); 93 1 2 3
  54. Undertow + XNIO Undertow server = Undertow.builder() .addHttpListener(8080, "localhost") .setHandler(Handlers.routing()

    .get("/hello/{any}", new MyHelloAnyHandler()) .post("/echo", new MyEchoHandler()) ).build(); server.start(); 94 1 2 3
  55. Обработка запроса acceptThread ioThread taskThread 107 connection org.xnio.nio. NioSocketStreamConnection acceptQueue

    ioThread selectorWorkQueue java.nio.channels. SocketChannel registerChannel() task acceptListener
  56. Обработка запроса acceptThread ioThread taskThread 108 connection org.xnio.nio. NioSocketStreamConnection acceptQueue

    ioThread selectorWorkQueue java.nio.channels. SocketChannel registerChannel() task acceptListener io.undertow.server. protocol.http. HttpReadListener
  57. Обработка запроса acceptThread ioThread taskThread 109 connection org.xnio.nio. NioSocketStreamConnection acceptQueue

    ioThread selectorWorkQueue java.nio.channels. SocketChannel registerChannel() task acceptListener io.undertow.server. protocol.http. HttpReadListener parser
  58. Обработка запроса acceptThread ioThread taskThread 110 connection org.xnio.nio. NioSocketStreamConnection acceptQueue

    ioThread selectorWorkQueue java.nio.channels. SocketChannel registerChannel() task acceptListener io.undertow.server. protocol.http. HttpReadListener rootHandler parser
  59. HttpHandler public interface HttpHandler { /** * Handle the request.

    * * @param exchange the HTTP request/response exchange * */ void handleRequest(HttpServerExchange exchange) throws Exception; } 111
  60. HttpServerExchange public HttpServerExchange dispatch( final Runnable runnable) { /* ...

    */ } public HttpServerExchange dispatch( final Executor executor, final Runnable runnable) { /* ... */ } 113
  61. Обработка запроса acceptThread ioThread taskThread 114 connection org.xnio.nio. NioSocketStreamConnection acceptQueue

    ioThread selectorWorkQueue java.nio.channels. SocketChannel registerChannel() task acceptListener io.undertow.server. protocol.http. HttpReadListener rootHandler parser
  62. HttpServerExchange public Receiver getRequestReceiver() { /* ... */ return new

    AsyncReceiverImpl(this); } public Sender getResponseSender() { /* ... */ return new AsyncSenderImpl(this); } 115
  63. HttpServerExchange public Receiver getRequestReceiver() { /* ... */ return new

    AsyncReceiverImpl(this); } public Sender getResponseSender() { /* ... */ return new AsyncSenderImpl(this); } 116
  64. AsyncReceiverImpl public void receiveFullBytes( final FullBytesCallback callback, final ErrorCallback errorCallback)

    { /* ... */ } public void receivePartialBytes( final PartialBytesCallback callback, final ErrorCallback errorCallback) { /* ... */ } 118
  65. AsyncReceiverImpl public void receiveFullBytes( final FullBytesCallback callback, final ErrorCallback errorCallback)

    { /* ... */ } public void receivePartialBytes( final PartialBytesCallback callback, final ErrorCallback errorCallback) { /* ... */ } 119
  66. AsyncReceiverImpl exchange.getRequestReceiver().receiveFullBytes( (ex, bytes) -> { /* ioThread */ /*

    bytes -> runnable */ ex.dispatch(runnable); }, (ex, exception) -> { ex.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); ex.endExchange(); } ); 120
  67. AsyncReceiverImpl exchange.getRequestReceiver().receiveFullBytes( (ex, bytes) -> { /* ioThread */ /*

    bytes -> runnable */ ex.dispatch(runnable); }, (ex, exception) -> { ex.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); ex.endExchange(); } ); 121
  68. AsyncReceiverImpl exchange.getRequestReceiver().receiveFullBytes( (ex, bytes) -> { /* ioThread */ /*

    bytes -> runnable */ ex.dispatch(runnable); }, (ex, exception) -> { ex.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); ex.endExchange(); } ); 122
  69. AsyncReceiverImpl exchange.getRequestReceiver().receiveFullBytes( (ex, bytes) -> { /* ioThread */ /*

    bytes -> runnable */ ex.dispatch(runnable); }, (ex, exception) -> { ex.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); ex.endExchange(); } ); 123
  70. Производительность и оптимизации HTTP API Kafka HTTP API 124 Эффективная

    работа с тысячами коннекций Снижение нагрузки на GC Обработка медленных клиентов Эффективная отправка
  71. HttpServerExchange public Receiver getRequestReceiver() { /* ... */ return new

    AsyncReceiverImpl(this); } public Sender getResponseSender() { /* ... */ return new AsyncSenderImpl(this); } 125
  72. AsyncSenderImpl public void send( final ByteBuffer buffer, final IoCallback callback)

    { /* ... */ } public void send( final ByteBuffer[] buffer, final IoCallback callback) { /* ... */ } 127
  73. AsyncSenderImpl public void send( final ByteBuffer buffer, final IoCallback callback)

    { /* ... */ } public void send( final ByteBuffer[] buffer, final IoCallback callback) { /* ... */ } 128
  74. AsyncSenderImpl public void send( final ByteBuffer buffer, final IoCallback callback)

    { /* ... */ } public void send( final ByteBuffer[] buffer, final IoCallback callback) { /* ... */ } 129
  75. AsyncSenderImpl.send() do { long res = channel.write(buffer); written += res;

    if (res == 0) { this.buffer = buffer; this.callback = callback; /* ... */ channel.getWriteSetter().set(writeListener); channel.resumeWrites(); return; } } while (written < total); 130
  76. AsyncSenderImpl.send() do { long res = channel.write(buffer); written += res;

    if (res == 0) { this.buffer = buffer; this.callback = callback; /* ... */ channel.getWriteSetter().set(writeListener); channel.resumeWrites(); return; } } while (written < total); 131
  77. AsyncSenderImpl.send() do { long res = channel.write(buffer); written += res;

    if (res == 0) { this.buffer = buffer; this.callback = callback; /* ... */ channel.getWriteSetter().set(writeListener); channel.resumeWrites(); return; } } while (written < total); 132
  78. AsyncSenderImpl.send() do { long res = channel.write(buffer); written += res;

    if (res == 0) { this.buffer = buffer; this.callback = callback; /* ... */ channel.getWriteSetter().set(writeListener); channel.resumeWrites(); return; } } while (written < total); 133
  79. AsyncSenderImpl.writeListener public void handleEvent(final StreamSinkChannel ch) { try { long

    toWrite = Buffers.remaining(buffer); long written = 0; while (written < toWrite) { long res = ch.write(buffer, 0, buffer.length); written += res; if (res == 0) { return; } } /* ... */ } catch (IOException e) { /* ... */ } } 134
  80. AsyncSenderImpl.writeListener public void handleEvent(final StreamSinkChannel ch) { try { long

    toWrite = Buffers.remaining(buffer); long written = 0; while (written < toWrite) { long res = ch.write(buffer, 0, buffer.length); written += res; if (res == 0) { return; } } /* ... */ } catch (IOException e) { /* ... */ } } 135 ByteBuffer[]
  81. AsyncSenderImpl.writeListener public void handleEvent(final StreamSinkChannel ch) { try { long

    toWrite = Buffers.remaining(buffer); long written = 0; while (written < toWrite) { long res = ch.write(buffer, 0, buffer.length); written += res; if (res == 0) { return; } } /* ... */ } catch (IOException e) { /* ... */ } } 136
  82. AsyncSenderImpl.send() do { long res = channel.write(buffer); written += res;

    if (res == 0) { this.buffer = buffer; this.callback = callback; /* ... */ channel.getWriteSetter().set(writeListener); channel.resumeWrites(); return; } } while (written < total); 137
  83. AsyncSenderImpl.send() do { long res = channel.write(buffer); written += res;

    if (res == 0) { this.buffer = buffer; this.callback = callback; /* ... */ channel.getWriteSetter().set(writeListener); channel.resumeWrites(); return; } } while (written < total); 138
  84. Производительность и оптимизации 145 Эффективная работа с тысячами коннекций Снижение

    нагрузки на GC Обработка медленных клиентов Эффективная отправка HTTP API Kafka HTTP API
  85. Производительность и оптимизации HTTP API Kafka HTTP API 146 Эффективная

    работа с тысячами коннекций Снижение нагрузки на GC Обработка медленных клиентов Эффективная отправка
  86. sun.nio.ch.SocketChannelImpl public long write( ByteBuffer[] srcs, int offset, int length)

    { /* ... */ IOUtil.write(fd, srcs, offset, length, nd); /* ... */ } 147
  87. sun.nio.ch.IOUtil if (!(buf instanceof DirectBuffer)) { ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);

    shadow.put(buf); shadow.flip(); /* ... */ buf = shadow; /* ... */ } 148
  88. sun.nio.ch.IOUtil if (!(buf instanceof DirectBuffer)) { ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);

    shadow.put(buf); shadow.flip(); /* ... */ buf = shadow; /* ... */ } 149
  89. sun.nio.ch.IOUtil if (!(buf instanceof DirectBuffer)) { ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);

    shadow.put(buf); shadow.flip(); /* ... */ buf = shadow; /* ... */ } 150
  90. ru.kontur.vostok.hercules.util. ByteBufferPool exchange.getResponseSender().send( buffer, new io.undertow.io.IoCallback() { @Override public void

    onComplete( HttpServerExchange exchange, Sender sender) { ByteBufferPool.release(buffer); exchange.endExchange(); } /* ... */ }); 152
  91. ru.kontur.vostok.hercules.util. ByteBufferPool exchange.getResponseSender().send( buffer, new io.undertow.io.IoCallback() { @Override public void

    onComplete( HttpServerExchange exchange, Sender sender) { ByteBufferPool.release(buffer); exchange.endExchange(); } /* ... */ }); 153
  92. ru.kontur.vostok.hercules.util. ByteBufferPool exchange.getResponseSender().send( buffer, new io.undertow.io.IoCallback() { @Override public void

    onComplete( HttpServerExchange exchange, Sender sender) { ByteBufferPool.release(buffer); exchange.endExchange(); } /* ... */ }); 154
  93. io.undertow.util.HttpString /** * An HTTP case-insensitive Latin-1 string. */ public

    final class HttpString implements Comparable<HttpString>, Serializable { private final byte[] bytes; private final transient int hashCode; /** * For well known header to make comparison fast */ private final int orderInt; private transient String string; /* ... */ 160
  94. io.undertow.util.HttpString /** * An HTTP case-insensitive Latin-1 string. */ public

    final class HttpString implements Comparable<HttpString>, Serializable { private final byte[] bytes; private final transient int hashCode; /** * For well known header to make comparison fast */ private final int orderInt; private transient String string; /* ... */ 161
  95. io.undertow.util.HttpString /** * An HTTP case-insensitive Latin-1 string. */ public

    final class HttpString implements Comparable<HttpString>, Serializable { private final byte[] bytes; private final transient int hashCode; /** * For well known header to make comparison fast */ private final int orderInt; private transient String string; /* ... */ 162
  96. io.undertow.util.HttpString 0x41 A 0x42 B 0x43 C 0x44 D 0x45

    E 0x46 F ... 0x57 W 0x58 X 0x59 Y 0x5A Z 163
  97. io.undertow.util.HttpString 0x41 A 0x61 a 0x42 B 0x62 b 0x43

    C 0x63 c 0x44 D 0x64 d 0x45 E 0x65 e 0x46 F 0x66 f ... 0x57 W 0x77 w 0x58 X 0x78 x 0x59 Y 0x79 y 0x5A Z 0x7A z 164
  98. io.undertow.util.HttpString 0x41 A 0x61 a 0x42 B 0x62 b 0x43

    C 0x63 c 0x44 D 0x64 d 0x45 E 0x65 e 0x46 F 0x66 f ... 0x57 W 0x77 w 0x58 X 0x78 x 0x59 Y 0x79 y 0x5A Z 0x7A z 165 private static int higher(byte b) { return b & (b >= 'a' && b <= 'z' ? 0xDF : 0xFF); }
  99. io.undertow.util.HttpString 0x41 A 0x61 a 0x42 B 0x62 b 0x43

    C 0x63 c 0x44 D 0x64 d 0x45 E 0x65 e 0x46 F 0x66 f ... 0x57 W 0x77 w 0x58 X 0x78 x 0x59 Y 0x79 y 0x5A Z 0x7A z 166 private static int higher(byte b) { return b & (b >= 'a' && b <= 'z' ? 0xDF : 0xFF); }
  100. io.undertow.util.HttpString /** * An HTTP case-insensitive Latin-1 string. */ public

    final class HttpString implements Comparable<HttpString>, Serializable { private final byte[] bytes; private final transient int hashCode; /** * For well known header to make comparison fast */ private final int orderInt; private transient String string; /* ... */ 167
  101. io.undertow.util.HttpString /** * An HTTP case-insensitive Latin-1 string. */ public

    final class HttpString implements Comparable<HttpString>, Serializable { private final byte[] bytes; private final transient int hashCode; /** * For well known header to make comparison fast */ private final int orderInt; private transient String string; /* ... */ 168
  102. io.undertow.util.HttpString public static final HttpString ACCEPT = new HttpString(ACCEPT_STRING, 1);

    public static final HttpString ACCEPT_CHARSET = new HttpString(ACCEPT_CHARSET_STRING, 2); public static final HttpString ACCEPT_ENCODING = new HttpString(ACCEPT_ENCODING_STRING, 3); 169
  103. io.undertow.util.HttpString public static final HttpString ACCEPT = new HttpString(ACCEPT_STRING, 1);

    public static final HttpString ACCEPT_CHARSET = new HttpString(ACCEPT_CHARSET_STRING, 2); public static final HttpString ACCEPT_ENCODING = new HttpString(ACCEPT_ENCODING_STRING, 3); 170 HttpString.orderInt
  104. Коварный трединг acceptThread ioThread taskThread 172 connection org.xnio.nio. NioSocketStreamConnection acceptQueue

    ioThread selectorWorkQueue java.nio.channels. SocketChannel registerChannel() task acceptListener io.undertow.server. protocol.http. HttpReadListener rootHandler parser
  105. Коварный трединг acceptThread ioThread taskThread 173 connection org.xnio.nio. NioSocketStreamConnection acceptQueue

    ioThread selectorWorkQueue java.nio.channels. SocketChannel registerChannel() task acceptListener io.undertow.server. protocol.http. HttpReadListener rootHandler parser
  106. Коварный трединг acceptThread ioThread taskThread 174 connection org.xnio.nio. NioSocketStreamConnection acceptQueue

    ioThread selectorWorkQueue java.nio.channels. SocketChannel registerChannel() task acceptListener io.undertow.server. protocol.http. HttpReadListener rootHandler parser
  107. Выводы Kafka HTTP API HTTP API 176 Эффективная работа с

    тысячами коннекций Снижение нагрузки на GC Обработка медленных клиентов Эффективная отправка