美文网首页Netty
Netty组件和设计

Netty组件和设计

作者: Real_man | 来源:发表于2019-01-02 19:11 被阅读83次

    通过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》

    相关文章

      网友评论

        本文标题:Netty组件和设计

        本文链接:https://www.haomeiwen.com/subject/mcrtrqtx.html