搜索
您的当前位置:首页正文

Netty组件和设计

来源:二三娱乐

通过Netty入门,可以运行和启动一个简单的客户端和服务端的应用了,这里看下Netty每个组件的细节,以及组件之前是如何协作的。

实例

我们先看代码:注释中包含了使用Netty服务端的一些操作说明,刚学的时候不太明白这些东西的意思,但是看了Netty的组件设计,及其架构,就容易理解每个语句对应的意思。

 public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            // 服务端的BootStrap,一个需要接受连接,一个用来处理事件
            b.group(bossGroup, workerGroup)
                    // Channel理解为通道,网络传输的通道类型
                    .channel(NioServerSocketChannel.class)

                    // ChannerlHandler要被装进ChannelPipeline
                    // 而过程则是调用ChannelInitializer的iniChannel方法
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            // addLast,在PipeLine中的Handler是有顺序的,所以
                            // 有addLast,addFirst等方法
                            // 添加的同时,可以指定Encoder和Decoder
                            ch.pipeline().addLast(new RequestDecoder(),
                                    new ResponseDataEncoder(),
                                    new ProcessingHandler());
                        }
                    }).option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            
            // TODO 待细看,先当做固定的写法
            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

客户端与服务端基本一致,只是将绑定本地端口换成了连接远端的端口

EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap();
            b.group(workerGroup)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    // 配置ChannelHandler
                    .handler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            ch.pipeline().addLast(new RequestDataEncoder(),
                                    new ResponseDataDecoder(), new ClientHandler());
                        }
                    });

            ChannelFuture f = b.connect(host, port).sync();

            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }

下面是看Netty In Action一书中整理到的其组件设计的一些知识点。

Netty网络层

Channel,EventLoop,ChannelFuture可以看做Netty的网络抽象层

  • Channel - Socket
  • EventLoop - 控制流,多线程,并发
  • ChannelFuture - 异步通知
Channel接口

基础的IO操作,bind,connect,read,write. 在底层上,这些主要依赖Java的Socket,Netty的Channel封装了底层的复杂操作。使得用起来简化很多,它提供了很多预定义的特定场景下的实现。

image.png
EventLoop接口

EventLoop接口定义了连接的整个生命周期中的事件处理,下图解释了Channel,EventLoop,Threads和EventLoopGroup的关系

image.png
  • EventLoopGroup包含一个或多个EventLoop
  • EventLoop的整个生命周期与单个线程的生命周期一致
  • Channel注册它的生命周期到单个的EventLoop上
  • 单个EventLoop能分配一个或多个Channel
  • 所有的I/O事件被EventLoop处理
ChannelFuture

在Netty中,所有的IO操作都是异步的,因为操作不是立刻返回结果,我们需要一个方式在程序执行一会再获取结果。Netty提供了ChannelListener,它的addListner方法注册一个ChannelFutureListener,当操作完成的时候就会通知Listener。

ChannelHandler and ChannelPipeline

这两个组件用来管理数据流和执行应用的逻辑。

ChannelHandler

从开发者的角度来看,Netty最主要的组件就是ChannelHandler,它可以处理应用内输入和输出的数据流,基本上可以做任意类型的数据操作,例如数据格式转换,或者异常处理。

ChannelPipeline

ChannelPipeline提供了ChannelHandler的容器,其内部可以有多个ChannelHandler,定义了链式ChannelHandler传播输入数据和输出数据流的API。当Channel被创建的时候,它会自动的分配到ChannelPipeline。

  • ChannelInitializer的实现被注册到ServerBootstrap
  • 当ChannelInitializer.initChannel被调用,就将多个ChannelHandler安装到pipeline中
  • ChannelInitializer将自己从ChannelPipeline中移除

ChannelHandler可以看做是代码的容器,里面主要都是我们的程序逻辑,处理事件还有在ChannelPipeline中的数据,ChannelHandler主要被添加进ChannelPipeLine中,当它被添加的时候会被分配一个ChannelHandlerContext。

小结

这里主要介绍了Netty的一些基本组件。

参考

  • 《Netty in Action》
Top