Netty 系列文章之基本组件概览

·  阅读 1464

前言

在之前的文章Netty 入门初体验简单介绍了 Netty 服务端和客户端的例子,下面依旧以Netty 服务端 demo 为例,来简单阐述下 Netty 的基本组件。

基本组件概览

以Netty服务端的一个例子来阐述其中用到的基本组件,代码如下:

public class EchoServer {
    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws InterruptedException {
        new EchoServer(8888).start();
    }

    public void start() throws InterruptedException {
        final EchoServerHandler serverHandler = new EchoServerHandler();
        //创建EventLoopGroup,处理事件
        EventLoopGroup group = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group,worker)
                    //指定所使用的NIO传输 Channel
                    .channel(NioServerSocketChannel.class)
                    //使用指定的端口设置套接字地址
                    .localAddress(new InetSocketAddress(port))
                    //添加一个EchoServerHandler到子Channel的ChannelPipeline
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //EchoServerHandler别标志为@Shareable,所以我们可以总是使用同样的实例
                            socketChannel.pipeline().addLast(serverHandler);
                        }
                    });
            //异步的绑定服务器,调用sync()方法阻塞等待直到绑定完成
            ChannelFuture future = b.bind().sync();
            future.channel().closeFuture().sync();
        } finally {
            //关闭EventLoopGroup,释放所有的资源
            group.shutdownGracefully().sync();
            worker.shutdownGracefully().sync();
        }
    }
}

复制代码

服务端创建流程:

  • 创建 ServerBootStrap实例
  • 设置并绑定 NioEventLoopGroup线程池
  • 通过 ServerBootStrapchannel方法设置并绑定服务端 Channel
  • 创建并初始化 ChannelPipeline
  • 添加并设置 ChannelHandler
  • 绑定并启动监听端口

上面简述了服务端的创建流程,其中包含了 Netty的基本组件的使用,下面这张导图也简单的叙述了Netty各大组件的概念与作用

netty

Channel

Channel是 Netty中的网络操作抽象类,对应JDK底层的Socket,它除了包含基本的I/O操作,如 bind(),connect(),read(),write()之外,还包括了Netty框架相关的一些功能,如获取 Channel的EventLoop。

EventLoop

EventLoop定义了Netty的核心抽象,用于处理连接的生命周期中所发生的事件。EventLoop 为Channel处理I/O操作,下图是 Channel,EventLoop,Thread以及EventLoopGroup之间的关系(摘自《Netty In Action》):

eventloop

这些关系是:

  • 一个EventLoopGroup 包含一个或者多个EventLoop
  • 一个 EventLoop 在它的生命周期内只和一个Thread绑定
  • 所有由 EventLoop处理的 I/O事件都将在它专有的Thread上被处理
  • 一个 Channel 在它的生命周期内只注册一个EventLoop
  • 一个 EventLoop 可能会被分配给一个或多个 Channel

EventLoopGroup实际上就是处理I/O操作的线程池,负责为每个新注册的Channel分配一个EventLoop,Channel在整个生命周期都有其绑定的 EventLoop来服务。

而上面服务端用的 NioEventLoop 就是 EventLoop的一个重要实现类,NioEventLoop 是Netty内部的I/O线程,而 NioEventLoopGroup是拥有 NioEventLoop的线程池,在Netty服务端中一般存在两个这样的NioEventLoopGroup线程池,一个 "Boss" 线程池,用于接收客户端连接,实际上该线程池中只有一个线程,一个 "Worker"线程池用于处理每个连接的读写。而Netty客户端只需一个线程池即可,主要用于处理连接中的读写操作。

ChannelHandler

ChannelHandler是Netty的主要组件,它主要用于对出站和入站数据进行处理,它有两个重要的子接口:

  • ChannelInboundHandler——处理入站数据以及各种状态变化
  • ChannelOutboundHandler——处理出站数据并且允许拦截所有的操作

ChannelPipeline

ChannelPipeline提供了 ChannelHandler链的容器,换句话说,就是一个逻辑处理链,用于拦截流经Channel的入站和出站事件的ChannelHandler。还是就是当 Channel被创建时,它会被自动地分配到它的专属的 ChannelPipeline。

channelpipline

当一个消息或者任何其他的入站事件被读取时,那么它会从 ChannelPipeline的头部开始流动,并被传递给第一个 ChannelInboundHandler,第一个处理完成之后传递给下一个 ChannelInboundHandler,一直到ChannelPipeline的尾端,与之对应的是,当数据被写出时,数据从 ChannelOutboundHandler 链的尾端开始流动,直到它到达链的头部为止。

ChannelFuture

Netty中所有I/O操作都是异步的,使用ChannelFuture可以获取操作完成的结果,其 addListener()方法注册了一个 ChannelFutureListener,以便在某个操作完成时(无论是否成功)得到通知。

ByteBuf

ByteBuf是Netty中的字节缓冲区,相比于Java NIO中的 ByeBuffer,ByteBuf做了很多改进,ByteBuf的功能性和灵活性更好。

BootStrap

Netty提供的启动辅助类,帮助Netty客户端或服务端的Netty初始化,服务端对应的是 ServerBootStrap引导类。

小结

上面简单的介绍了Netty的一些基本组件,后续文章会详细对每个组件进行分析

参考资料 & 鸣谢

分类:
后端
分类:
后端
收藏成功!
已添加到「」, 点击更改