O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

JJUG CCC 2018 Spring - I-7 (俺が)はじめての Netty

3.152 visualizações

Publicada em

JJUG CCC 2018 Spring I-7 (俺が)はじめての Netty
初心者向けに Netty を紹介したセッションの資料です

事前に公開していた資料に若干加筆してあります
事前公開していた資料(https://www.slideshare.net/mikeneck/nettyjjug-ccc-2018-spring-jjugccc-ccci7)

Publicada em: Tecnologia
  • Seja o primeiro a comentar

JJUG CCC 2018 Spring - I-7 (俺が)はじめての Netty

  1. 1. ( ) Netty JJUG CCC 2018 Spring #jjug #ccc_i7 @mike_neck
  2. 2. • •twitter: @mike_neck •https://github.com/mike-neck •L is B • Swift
  3. 3. Netty
  4. 4. Netty • •Netty •
  5. 5. 1.Netty 2.Java API Netty 1.OIO(Old Blocking I/O) 2.NIO(Non-blocking I/O) 3.Netty 3.Netty 4.Netty 5.
  6. 6. • I/O(Input/Output) I/O I/O • • Netty Netty • •Java : java version “10” 2018-03-20 •Netty : 4.1.24.Final
  7. 7. 1. Netty
  8. 8. Netty (1) •Netty / • • /CPU
  9. 9. Netty (2) • •Elasticsearch •Akka •Finagle •Gatling
  10. 10. Netty (3) •blocking I/O non- blocking I/O • •
  11. 11. Norman Maurer in Netty in Action 2016 Our primary goal has been to make Netty accessible to the broadest range of developers.
  12. 12. 2. Java API Netty Netty
  13. 13. Java API I/O(1) •JDK 1.0 java.net API •accept / read / write API • (block) • OIO (Old blocking I/O)
  14. 14. Java API I/O(2) •Java 1.4 java.nio.channels API •select( epoll/kqueue) API • • NIO(New Non-blocking I/O)
  15. 15. 2-1. OIO (Old blocking I/ O) Java API Netty
  16. 16. OIO Echo 1. 2. (accept) 3. (read) 4. 5. (write) 6.
  17. 17. OIO Echo class EchoServer { public static void main(String[] args) { var serverSocket = new ServerSocket(8000); //(1) while(true) { Socket socket = serverSocket.accept(); // (2) var reader = toBufferedReader(socket.getInputStream()); var writer = toPrintWriter(socket.getOutputStream()); String line = reader.readLine(); // (3) System.out.println(line); // (4) writer.println(line); // (5) socket.close(); // (6) } } }
  18. 18. OIO Echo ServerSocketaccept ServerSocket accept
  19. 19. OIO Echo ServerSocketaccept accept Socket Socket
  20. 20. OIO Echo ServerSocketaccept Socket read Socket read
  21. 21. OIO Echo ServerSocketaccept Socket read App
  22. 22. OIO Echo ServerSocketaccept Socket write write Socket read App write
  23. 23. OIO Echo ServerSocketaccept write Socket close close Socket read App write close
  24. 24. OIO Echo ServerSocketaccept Socket read App write 1 ServerSocket
  25. 25. OIO Echo (?) ServerSocketaccept Socket read App write accept 1
  26. 26. read/write ExecutorService exec = Executors.newFixedThreadPool(THREAD_NUM); var serverSocket = new ServerSocket(8000); //(1) while(true) { Socket socket = serverSocket.accept(); // (2) exec.submit(() -> { var reader = toBufferedReader(socket.getInputStream()); var writer = toPrintWriter(socket.getOutputStream()); String line = reader.readLine(); // (3) System.out.println(line); //(3) writer.println(line); // (4) socket.close(); }); }
  27. 27. OIO Echo (?) Thread Socket App Thread Socket App Thread Socket App
  28. 28. Thread … Thread Socket App Thread Socket App Thread Socket App
  29. 29. Thread … Thread Socket App Thread Socket App Executor Queue Socket App Socket App Socket App Executor =
  30. 30. Thread … Thread Socket App Thread Socket App Executor Queue Socket App Socket App Socket App read / write Thread Socket App
  31. 31. … Thread Socket App Thread Socket App Executor Queue Socket App Socket App Socket App Socket App
  32. 32. OIO • ( ) • read/write/close • read/write ( ) • /CPU
  33. 33. 2-2. NIO (Non-blocking I/ O) Java API Netty
  34. 34. OIO(blocking ) … • NIO (select ) • I/O ( I/O ) • I/O (accept /read /write ) ( )
  35. 35. NIO Echo 1. ( ) I/O (OP_ACCEPT/OP_READ/ OP_WRITE) 2. 3. OP_ACCEPT (OP_READ) 4. OP_READ (OP_WRITE) 5. OP_WRITE (OP_WRITE)
  36. 36. I/O •Selector 4 •OP_READ - Channel •OP_WRITE - Channel •OP_CONNECT - Channel ( ) •OP_ACCEPT - ServerSocketChannel ( ) ( listen )
  37. 37. class EchoServer { public static void main(String[] args) { var channel = ServerSocketChannel.open(); channel.setOption(SO_REUSEADDR, true); channel.bind(new InetSocketAddress(PORT)); channel.configureBlocking(false); var selector = Selector.open(); channel.register(selector, SelectionKey.OP_ACCEPT); runLoop(selector); }
  38. 38. void runLoop(Selector selector) { while(true) { selector.select(); Set<SelectionKey> selectionKeys = selector.selectedKeys(); for (var key: selectionKeys) { if (key.isAcceptable()) accept(key, selector); if (key.isReadable()) read(key); if (key.isWritable()) write(key); selectionKeys.remove(key); } }
  39. 39. OP_ACCEPT void access(SelectionKey key, Selector selector) { var serverSocketChannel = (ServerSocketChannel) key.channel(); SocketChannel channel = serverSocketChannel.accept(); channel.configureBlocking(false); channel.register( selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024)); } OP_READ
  40. 40. OP_READ void read(SelectionKey key) { SocketChannel channel = (SocketChannel) key.channel; var buf = (ByteBuffer) key.attachment(); int size = channel.read(buf); var bytes = new byte[size]; buf.flip().get(bytes); buf.clear(); buf.put(handleMessage(bytes)); // read 1 key.interestOps(SelectionKey.OP_WRITE); } OP_WRITE
  41. 41. OP_WRITE void write(SelectionKey key) { SocketChannel channel = (SocketChannel) key.channel; var buf = ((ByteBuffer) key.attachment()).flip(); channel.write(buf); buf.compact(); if (buf.position() > 0) { // NW 1 key.interestOps(SelectionKey.OP_WRITE); } else { buf.clear(); channel.close(); } }
  42. 42. NIO Echo Selector ServerSocketChannel OP_ACCEPT Selector ServerSocketChannel (OP_ACCEPT)
  43. 43. NIO Echo Selector ServerSocketChannel OP_ACCEPT Selector#select I/O select
  44. 44. NIO Echo Selector ServerSocketChannel ServerSocketChannel Selector OP_ACCEPT select
  45. 45. NIO Echo Selector ServerSocketChannel accept SocketChannel OP_READ Selector SocketChannel OP_ACCEPT OP_READ accept
  46. 46. NIO Echo Selector ServerSocketChannel Selector#select I/O SocketChannel OP_ACCEPT OP_READ select
  47. 47. NIO Echo Selector ServerSocketChannel OP_READ Selector SocketChannel OP_ACCEPT OP_READ select
  48. 48. NIO Echo Selector ServerSocketChannelSelectionKey SocketChannel OP_ACCEPT Application OP_READ ByteBuffer read
  49. 49. NIO Echo Selector ServerSocketChannel Socket Channel OP_WRITE Selector SocketChannel OP_ACCEPT Application OP_WRITE ByteBuffer
  50. 50. NIO Echo Selector ServerSocketChannel Selector#select Socket writability SocketChannel OP_ACCEPT Application OP_WRITE ByteBuffer select
  51. 51. NIO Echo Selector ServerSocketChannel Selector#select Socket SocketChannel OP_ACCEPT Application select OP_WRITE ByteBuffer
  52. 52. NIO Echo Selector ServerSocketChannel (write) SocketChannel OP_ACCEPT Application select OP_WRITE ByteBuffer
  53. 53. NIO Echo Selector ServerSocketChannel Selector writability SocketChannel OP_ACCEPT Application OP_WRITE ByteBuffer
  54. 54. NIO Selector read/write SocketChannel App select OP_WRITE SocketChannel App SocketChannel App OP_READ OP_READ
  55. 55. NIO • • 1 • ByteBuffer •OIO NIO
  56. 56. NIO • • •ByteBuffer •OIO NIO •
  57. 57. … API
  58. 58. NIO Netty Java API(NIO) Netty
  59. 59. 2-3. Netty Java API Netty
  60. 60. Netty Echo 1. ChannelInboundHandlerAdapter 2. 1. ChannelPipeline 3. 2. Bootstrap
  61. 61. 1. ChannelInboundHandlerAdapter class EchoHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead( ChannelContext ctx, Object msg) { var buf = (ByteBuf) msg; String message = buf.toString(UTF_8); ByteBuf res = ctx.alloc().buffer(); res.writeCharSequence(message, UTF_8); ctx.writeAndFlush(res); } } channelRead OP_READ byte[] String ByteBuf Netty
  62. 62. 2. EchoHandler ChannelPipeline class InitHandler extends ChannelInitializer<Channel> { @Override protected void initChannel(Channel ch) { ch.pipeline() .addLast(new EchoHandler()); } } ChannelPipeline 1
  63. 63. 3. ServerBootstrap class EchoServer { public static void main(String[] args) { var parent = new NioEventLoopGroup(); var child = new NioEventLoopGroup(); var bootstrap = new ServerBootstrap(); bootstrap.group(parent, child) .channel(NioServerSocketChannel.class) .localAddress(8000) .childHandler(new InitHandler()); ChannelFuture future = bootstrap.bind().sync(); future.channel().closeFuture().sync(); } } ServerBootstrap blocking I/O NIO
  64. 64. 3. ServerBootstrap class EchoServer { public static void main(String[] args) { var parent = new NioEventLoopGroup(); var child = new NioEventLoopGroup(); var bootstrap = new ServerBootstrap(); bootstrap.group(parent, child) .channel(NioServerSocketChannel.class) .localAddress(8000) .childHandler(new InitHandler()); ChannelFuture future = bootstrap.bind().sync(); future.channel().closeFuture().sync(); } } Netty …
  65. 65. 3. Netty
  66. 66. Netty •Channel •ChannelFuture •ChannelHandler & ChannelPipeline •EventLoop •ByteBuf •Bootstrap
  67. 67. Netty •Channel •ChannelFuture •ChannelHandler & ChannelPipeline •EventLoop •ByteBuf •Bootstrap
  68. 68. Channel • (SocketChannel) (ServerSocketChannel) • I/O (accept/bind/ connect/read/write)
  69. 69. Channel NioServerSocketChannel Channel ServerSocketChannel SocketChannel NioSocketChannel extends extends implements implements (accept) Channel Channel(read/write/close/connect)
  70. 70. Netty •Channel •ChannelFuture •ChannelHandler & ChannelPipeline •EventLoop •ByteBuf •Bootstrap
  71. 71. ChannelFuture •NIO non-blocking API I/O •Netty Future(ChannelFuture) • (write/close) ChannelFutureListener ChannelFuture
  72. 72. ChannelFuture Channel (1)1 
 write
  73. 73. ChannelFuture Channel (1)1 
 write ChannelFuture (2) return
  74. 74. ChannelFuture Channel (1)1 
 write ChannelFuture (2) return write write 1 2 (3) I/O write
  75. 75. ChannelFuture Channel (1)1 
 write ChannelFuture (2) return write write 1 2 (4) or (3) I/O write
  76. 76. ChannelFuture Channel (1)1 
 write ChannelFuture (2) return write write 1 2 (4) or (3) I/O write ChannelFutureListener (5)
  77. 77. Netty •Channel •ChannelFuture •ChannelHandler & ChannelPipeline •EventLoop •ByteBuf •Bootstrap
  78. 78. ChannelHandler •ChannelHandler SocketChannel (OP_READ/OP_WRITE) • TCP/UDP (HTTP/WebSocket/SSL) • ChannelHandler •ChannelHandler I/O •ChannelInboundHandler : I/O (read) •ChannelOutboundHandler : I/O (write)
  79. 79. ChannelPipeline •ChannelPipeline 1 Channel 1 •Channel •ChannelHandlerContext ChannelHandler •ChannelPipeline Channel ChannelHandler
  80. 80. Channel ChannelPipeline Channel ServerSocketChannel accept Channel ChannelPipeline
  81. 81. Channel ChannelPipeline Channel Inbound Inbound Outbound Outbound Inbound ChannelInitializer ChannelHandler
  82. 82. Channel ChannelPipeline Channel Inbound Outbound Channel EventLoopGroup 1 EventLoop Inbound Outbound Inbound EventLoop
  83. 83. Channel ChannelPipeline Channel Outbound Selector OP_READ Outbound EventLoop OP_READ Inbound Inbound Inbound
  84. 84. Channel ChannelPipeline Channel Inbound OP_WRITE EventLoop Inbound Inbound EventLoop OP_WRITE Outbound Outbound
  85. 85. ChannelInboundHandler channelRegistered accept Channel EventLoop channelRead OP_READ -> (1 ) channelReadComplete (channelRead) exceptionCaught
  86. 86. ChannelInboundHandler ChannelInboundHandler byte[] ChannelInboundHandler channelRead ChannelHandlerContext
  87. 87. ChannelInboundHandler ChannelInboundHandler byte[] ChannelInboundHandler channelRead channelRead byte[] ChannelHandlerContext
  88. 88. ChannelInboundHandler ChannelInboundHandler String byte[] ChannelInboundHandler channelRead channelRead channelReadComplete byte[] ChannelHandlerContext
  89. 89. ChannelInboundHandler ChannelInboundHandler String byte[] ChannelInboundHandler byte[] ChannelHandlerContext fireChannelRead String channelRead channelRead channelReadComplete
  90. 90. ChannelInboundHandler ChannelInboundHandler String byte[] ChannelInboundHandler byte[] ChannelHandlerContext fireChannelRead String String channelRead channelRead channelReadComplete channelRead
  91. 91. ChannelInboundHandler ChannelInboundHandler String byte[] ChannelInboundHandler byte[] ChannelHandlerContext fireChannelRead String channelRead Method: POST Path: /api/users Content-Type: x-www- form-urlencoded name=Tom String channelRead channelRead channelReadComplete
  92. 92. ChannelOutboundHandler ChannelOutboundHandler ChannelOutboundHandler ChannelHandlerContext class User id=100 name=Tom write JSON JSON write JSONwrite byte[]
  93. 93. ChannelPipeline ChannelHandler •ChannelHandler •ChannelInboundHandler head tail •ChannelOutboundHandler tail head •ChannelHandler ChannelHandlerContext ChannelHandler ChannelHandler
  94. 94. ChannelPipeline ChannelHandler ChannelPipeline (1) ChannelInboundHandler (3) ChannelInboundHandler (2) ChannelOutboundHandler (4) ChannelOutboundHandler H T ChannelInboundHandler (1) -> (3) ChannelOutboundHandler (2) <- (4)
  95. 95. ChannelHandlerContext ChannelPipeline Inbound Inbound Outbound Outbound H T Context Context Context Context fireRead Tail ChannelInboundHandler
  96. 96. ChannelHandlerContext ChannelPipeline Inbound Inbound Outbound Outbound H T Context Context Context Context write Head ChannelOutboundHandler
  97. 97. Netty •Channel •ChannelFuture •ChannelHandler & ChannelPipeline •EventLoop •ByteBuf •Bootstrap
  98. 98. EventLoop •EventLoop 1 Thread Channel •EventLoop EventLoopGroup • 2 EventLoopGroup • 1 EventLoopGroup • EventLoop Selector ChannelPipeline
  99. 99. EventLoop Channel EventLoopGroup ThreadEventLoop ThreadEventLoop ThreadEventLoop EventLoopGroup EventLoop
  100. 100. EventLoop Channel EventLoopGroup ThreadEventLoop Channel ThreadEventLoop ThreadEventLoop Channel EventLoop 1 ThreadEventLoop
  101. 101. EventLoop Channel EventLoopGroup ThreadEventLoop Channel ThreadEventLoop ThreadEventLoop 1 EventLoop Channel ThreadEventLoopChannel Channel
  102. 102. EventLoop •EventLoop 1 Channel •ChannelHandler EventLoop Channel Netty • 1 Thread Channel ThreadLocal
  103. 103. Netty •Channel •ChannelFuture •ChannelHandler & ChannelPipeline •EventLoop •ByteBuf •Bootstrap
  104. 104. ByteBuf •ByteBuf Java ByteBuffer byte •Java ByteBuffer 1 ByteBuf / • ByteBuffer 1 ByteBuffer ( ) CompositeByteBuf ByteBuf 1 ByteBuf
  105. 105. ByteBuffer position limit / byte / byte ( ) byte capacity
  106. 106. ByteBuf readerIndex writerIndex byte byte byte capacity
  107. 107. ByteBuffer ByteBuffer first = … ByteBuffer second = … var byteBuffer = ByteBuffer.allocate( first.remaining(), second.remaining()); byteBuffer.put(first); byteBuffer.put(second); byteBuffer.flip();
  108. 108. ByteBuffer ByteBuffer contents1 ByteBuffer contents2 ByteBuffer contents1 contents2 (1) 
 ByteBuffer (2) ByteBuffer
  109. 109. ByteBuf ByteBuf first = … ByteBuf second = … var byteBuf = Unpooled.compositeBuffer(); byteBuf.addComponents(true, first, second);
  110. 110. ByteBuf CompositeByteBuf ByteBuf contents1 ByteBuf contents2 1 ByteBuf
  111. 111. CompositeByteBuf ByteBuf or channelRead 1. channelRead 2. channelRead 3. channelRead channelReadComplete fireChannelRead
  112. 112. Netty •Channel •ChannelFuture •ChannelHandler & ChannelPipeline •EventLoop •ByteBuf •Bootstrap
  113. 113. Bootstrap • • or •Bootstrap • ( ) •Channel •EventLoopGroup • or
  114. 114. Bootstrap • or • ServerBootstrap • Bootstrap
  115. 115. ( ) • / Channel EventLoop • •TCP - •UDP - •SCTP - • •OIO - (Java I/O ) •NIO - (select epoll kqueue) •epoll - (edge trigger/ Linux OS ) •kqueue - BSD OS
  116. 116. ( ) •Channel • /TCP/NIO : NioServerSocketChannel • /TCP/NIO : NioSocketChannel • /TCP/epoll : EpollServerSocketChannel •EventLoop • /NIO : NioEventLoopGroup x 2 • /OIO : OioEventLoopGroup x 1 • /epoll : EpollEventLoopGroup x 2
  117. 117. ServerBootstrap ( ) class EchoServer { public static void main(String[] args) { var parent = new NioEventLoopGroup(); var child = new NioEventLoopGroup(); var bootstrap = new ServerBootstrap(); bootstrap.group(parent, child) .channel(NioServerSocketChannel.class) .localAddress(8000) .childHandler(new InitHandler()); ChannelFuture future = bootstrap.bind().sync(); future.channel().closeFuture().sync(); } }
  118. 118. 4. Netty
  119. 119. HTTP
  120. 120. SimpleChannelInboundHandler class HttpEchoHandler extends SimpleChannelInboundHandler<HttpRequest> { @Override protected void channelRead0( ChannelHandlerContext ctx, HttpRequest req) { // } }
  121. 121. HttpRequest •uri •method •protocolVersion •httpHeaders •(POST HttpPostRequestDecoder )
  122. 122. Initializer class HttpEchoInitializer extends ChannelInitializer<SocketChannel> { @Override public void initChannel(SocketChannel ch) { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpObjectAggregator(65535)); pipeline.addLast(new ChunkedWriteHandler()); pipeline.addLast(new HttpEchoHandler()); } }
  123. 123. • Netty •HTTP POST Body •HTTP Real World HTTP • 1 / •
  124. 124. 5.
  125. 125. • Netty OIO NIO • Netty NIO • Netty / / ( ) • Spring WebFlux/Play-Akka
  126. 126. •Netty In Action •Norman Maurer/Marvin Allen Wolfthal •Manning 2016 •Java •Scott Oaks •Acroquest Technology/ • • 2015
  127. 127. URL •Netty Project •http://netty.io/index.html •https://github.com/netty/ netty

×