总体概述
Netty作为一款网络通信框架,底层封装了NIO。我们在使用Netty时,无需再关注NIO细节。下图为Netty处理流程图:
应用程序中使用Netty作为网络通信框架后,会形成一条PipeLine链,PipeLine链上有一个一个的事件处理器。当应用程序接收到网络数据,或者发送网络数据时,数据会经过PipeLine上的事件处理器,对数据进行处理,然后再将处理后的数据进行发送或者业务处理。
事件处理器可细分为入站处理器和出站处理器。入站表示接收网络数据到业务处理的过程。出站表示发送数据到网络的过程。当接收网络数据时,数据会经过入站处理器到达业务处理,当发送数据时,数据经过出站处理器进行处理。所以,入站处理器要进行一定的排序,出站处理器也需要一定的排序。而入站和出站之间的顺序,没有任何关系。
以上就是Netty的大体介绍。我们使用Netty,本质就是定义处理器以及数据的处理业务即可。而无需再关心NIO中注册连接,读写事件等操作。
Netty核心组件
Channel、EventLoop、EventLoopGroup
EventLoopGroup可以理解成线程池的作用,生产EventLoop实例。
EventLoop可以理解成一个线程,用于执行任务。
Channel可以理解成一个Socket。一个Channel对应一个EventLoop,而一个EventLoop可以对应多个Channel。Channel中的网络事件,由EventLoop这个线程来执行。
EventLoop是对Channel中数据的业务处理。而NIO中的Selector是对Channel中I/O事件的处理。EventLoop中维护了Channel的PileLine,来对Channel中数据执行一遍事件处理器链,进行数据业务操作。而Selector是对应用程序中所有channel,进行I/O事件的选择。比如Channel中数据通过EventLoop进行完成业务处理 后,能发送数据了,则Selector选择这个Channel,进行write操作发送数据。一个EventLoop对应一个selector。即一个线程对应一个selector。
Channel生命周期:
当Channel与远端建立连接后,状态就是Active状态,当断开连接后,切换为Inactive状态,然后与EventLoop解绑,切换为Unregistered状态。每个状体切换,都会触发一个事件,我们可以在Handler里定义事件处理器,去进行一些业务操作。
ChannelHandler、ChannelPileLine
从应用程序开发而言,Netty的主要组件是ChannelHandler。它充当了所有入站和出站数据的应用程序逻辑的地方。
ChannelHandler是一个接口,其下面分为InboundHandler入站处理器和OutBoundHandler出站处理器。netty使用适配器模式,可以继承Adapter类,来实现我们自己感兴趣的方法,而不是全部方法。
SimpleChannelInboundHandler研究:自动释放Buffer资源,避免内存泄漏。避免内存泄漏的法则是在ChannelHandler链中,要么数据向后传递,后面还有Handler处理数据,要么就在最后一个处理的Handler上释放内存。
一个channel在创建时,就会创建一个ChannelPileLine对象。在ChannelPileLine中,存放ChannelHandler链。一个ChannelHandler对象,允许放在不同的Channel中的ChannelPileLIne中。但是需要加上@sharable注解,告诉netty要共用这个ChannelHandler对象。这样的话会产生线程安全问题。
ByteBuf
Netty封装了NIO的ByteBuffer,定义了ByteBuf类。
编码器解码器
Netty提供了http协议编码器,解码器,https协议编码器,解码器。websocket编码器,解码器。
有了解码器以后,我们的服务就可以接收这些协议的数据了,netty解码器自己去解析协议数据,供我们拿到业务数据。例如,如果我们的服务想接收mqtt协议,完全可以用netty的mqtt解码器去接收数据,然后解析,就无需引入第三方mqtt服务器了。