nettty

58326 ワード

https://www.jianshu.com/p/e58674eb4c7a

1.Netty-非同期およびイベント駆動


1.Nettyは、システムが150,000人の同時ユーザーをサポートできるようにする構築を支援します.
2.Netty設計キー:非同期+イベント駆動

1.1 Javaネットワークプログラミング(BIO)


典型的なBIOサービス:
1.プライマリ・スレッドがportで傍受され、クライアント接続を待機します.
2.クライアントが開始した接続を受信すると、クライアント要求を処理するための新しいスレッドが作成されます.
3.プライマリ・スレッドはportリスニングに戻り、次のクライアント接続を待機します.
欠点:
1.各新しいクライアントSocketは新しいThread処理を作成する必要があり、大量のスレッドがスリープ状態になる.
2.各スレッドには呼び出しスタックのメモリ割り当てがあり、接続数が非常に多い場合、メモリが多く消費されます.
3.接続数が多い場合、大量のスレッドが作成され、コンテキスト切り替えによるオーバーヘッドが大きい.
コード:

   
   
   
   
  1. public void serve(int port) throws IOException {
  2. // Socket
  3. ServerSocket serverSocket = new ServerSocket(port);
  4. //
  5. Socket clientSocket = serverSocket.accept();
  6. //
  7. BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));
  8. PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
  9. String request, response;
  10. while((request = in.readLine()) != null) {
  11. if( "Done".equals(request)) {
  12. break;
  13. }
  14. response = processRequest(request);
  15. out.println(response);
  16. }
  17. }

1.2 Java NIO

1. Selector Java I/O 。 Socket Selector , / 。

2. 。

1.3 Nettyのコアコンポーネント

Netty :

1. Channel

2.

3. Future

4. ChannelHandler

1.3.1 Channel

Channel ( ) ( ) ( 、 Socket )。 , 。

1.3.2コールバック

: , 。Netty , : ChannelHandler channelActive() , , 。

1.3.3 Future

。 , 。

JDK Future ChannelFuture :

1. JDK Future ,

2. ChannelFuture Listener , operationComplete() 。

:


   
   
   
   
  1. public static void connect() {
  2. Channel channel = CHANNEL_FROM_SOMEWHERE;
  3. ChannelFuture future = channel.connect( new InetSocketAddress( "127.0.0.1", 9080));
  4. future.addListener( new ChannelFutureListener() {
  5. @Override
  6. public void operationComplete(ChannelFuture future) throws Exception {
  7. if(future.isSuccess()) {
  8. ByteBuf buf = Unpooled.copiedBuffer( "hello", Charset.defaultCharset());
  9. ChannelFuture wf = future.channel().writeAndFlush(buf);
  10. // ...
  11. } else {
  12. // /
  13. future.cause().printStackTrace();
  14. }
  15. }
  16. })
  17. }

1.3.4イベントとChannelHandler

1. : 。 : (channelActive)/ (channelRead)/ (exceptionCaught)/...

2. Channelhandler: 。 :ChannelInboundHanderAdapter.java

1.3.5 ChannelとEventLoopの :

Channel EventLoop Netty , , :

1. Channel EventLoop

2. EventLoop Channel(1:n )

3. EventLoop 4. Channel I/O , ChannelPipeline ChannelHandler

2. のNettyアプリケーション

1. ChannelHandler 。

2. Netty , : , 。 , 。

2.3 Echoサーバの

Netty : ChannelHandler + (Bootstrap)

2.3.1 ChannelHandlerとビジネスロジック

ChannelInboundHandlerAdapter , :

1. channelRead() -

2. channelReadComplete() -

3. exceptionCaught() - ,

:


   
   
   
   
  1. @ChannelHandler.Sharable
  2. public class EchoServerHandler extends ChannelInboundHandlerAdapter{
  3. /**
  4. *
  5. */
  6. @Override
  7. public void channelRead(ChannelHandlerContext ctx, Object msg) {
  8. ByteBuf in = (ByteBuf) msg;
  9. System.out.println(
  10. "Server received: " + in.toString(CharsetUtil.UTF_8));
  11. ctx.write(in);
  12. }
  13. /**
  14. * , channelReadComplete(...)
  15. */
  16. @Override
  17. public void channelReadComplete(ChannelHandlerContext ctx)
  18. throws Exception {
  19. ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
  20. .addListener(ChannelFutureListener.CLOSE);
  21. }
  22. /**
  23. *
  24. */
  25. @Override
  26. public void exceptionCaught(ChannelHandlerContext ctx,
  27. Throwable cause) {
  28. cause.printStackTrace();
  29. ctx.close();
  30. }
  31. }

:

1. channelRead channelReadComplete : channelRead(...) channelReadComplete 。

2. ctx.write(...) ChannelOutboundBuffer , flush(...)

3. @Sharable : ChannelHandler 。 Channel 。 @Sharable ChannelHandler

4. 

2.3.2ブートサーバ

1. Netty Channel。 EventLoop ChannelPipeline。

2. Channel ChannelPipeline。ChannelPipeline ChannelHandler 。

:


   
   
   
   
  1. EventLoopGroup group = new NioEventLoopGroup();
  2. try {
  3. ServerBootstrap b = new ServerBootstrap();
  4. b.group(group)
  5. .channel(NioServerSocketChannel.class)
  6. .localAddress( new InetSocketAddress(port))
  7. .childHandler( new ChannelInitializer() {
  8. @Override
  9. public void initChannel(SocketChannel ch) throws Exception {
  10. ch.pipeline().addLast( new EchoServerHandler());
  11. }
  12. });
  13. } finally {
  14. group.shutdownGracefully().sync();
  15. }

2.4 Echoクライアントの

:

1.

2.

3.

2.4.1 ChannelHandlerクライアントロジック

1. Java GC 。 Netty ByteBuf, 。 : Netty, 。 ,

2. SimpleChannelInboundHandler Handler, 。SimpleChannelInboundHandler.java channelRead() 。

3. 。 TCP 。

:


   
   
   
   
  1. // SimpleChannelInboundHandler channelRead msg
  2. public abstract class SimpleChannelInboundHandler<I> ...{
  3. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  4. boolean release = true;
  5. try {
  6. // ...
  7. } finally {
  8. if (autoRelease && release) {
  9. // msg
  10. ReferenceCountUtil.release(msg);
  11. }
  12. }
  13. }
  14. }

:ChannelHandler ?

1. : SimpleChannelInboundHandler, msg ChannelHandler

2. : SimpleChannelInboundHandler, msg ctx.write(...)

2.4.2ブートクライアント

:


   
   
   
   
  1. EventLoopGroup group = new NioEventLoopGroup();
  2. try {
  3. Bootstrap b = new Bootstrap();
  4. b.group(group)
  5. .channel(NioSocketChannel.class)
  6. .remoteAddress( new InetSocketAddress(host, port))
  7. .handler( new ChannelInitializer() {
  8. @Override
  9. public void initChannel(SocketChannel ch)
  10. throws Exception {
  11. ch.pipeline().addLast(
  12. new EchoClientHandler());
  13. }
  14. });
  15. //
  16. ChannelFuture f = b.connect().sync();
  17. f.channel().closeFuture().sync();
  18. } finally {
  19. group.shutdownGracefully().sync();
  20. }

ふろく

1.

2.netty-in-action