1、netty是什么?
在使用netty之前,我们首先要知道netty的优势在哪,它能解决什么问题。
我们不妨直接引用netty官网上最顶部的内容:
翻译一下就是:netty是一款异步的事件驱动的网络程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端。
注意上方加粗的关键词:
- 支持异步是netty高效的重要支撑,在传统java API中,我们使用NIO需要较为繁琐的编码,而netty为我们封装了易于使用的API,我们甚至能够通过一行代码将整个服务由OIO转为NIO!
- 事件驱动指的是netty处理网络消息的方式,框架内部为我们提供了完善的接口/抽象类,其中的各个方法代表了在网络传输过程中发生的各种事件,在我们编码过程中只需要完善各个方法,就可以处理各种网络通信!
- 快速开发的快速不仅仅在于netty提供了恰当的处理网络通信的框架逻辑,更在于其内部提供了丰富的成熟的编解码器,我们只需要将它们加入我们的pipline,便可以轻易的处理如HTTP/HTTPS/Websocket/IMAP/ProtoBuf等等协议
- 高性能于netty有着许多原因,包括但不限于支持NIO、零拷贝、多线程优化等。而我们只需要使用netty框架,便能轻易的享受前人给予我们的强大性能。
我们将从以下几方面来介绍netty:
- netty的工作流程:大致了解netty是如何处理网络信息的
- ChannelHandler:netty中重要的网络信息处理组件
- 编解码器:作为特殊的ChannelHandler为使用者提供了方便的协议解析
- EventLoop:netty内部基于Reactor模型对事件进行分发
- ByteBuf:netty提供的高效且易用的字节容器
- ChannelFuture:netty自身定义的future模型,在执行异步操作时使用
- 引导客户端与服务器启动:最后一步,如何启动我们的网络服务
2、netty的工作流程
对于入门使用netty而言,一图便可以了解netty的工作流程:
接下来我们对这张图进行解释:
- channel:就如同JavaNIO中所做的那样,netty将对网络IO的操作抽象为channel,因此我们不再操作基础的socket,而是封装过后的channel。
- pipline:由管道流向netty的事件,需要经过重重的ChannelHandler加以处理,ChannelHandler便是netty提供给我们的、编码者大部分精力需要花费的框架结构。pipline则是将一个个ChannelHandler顺序连接起来的抽象。
- ChannelHandler:如上文所说,ChannelHandler是我们处理网络信息的主体,我们编码的ChannelHandler其本身继承于netty所定义ChannelHandler,而其各个方法本身就是为了响应一个个不同的事件,这也是netty事件驱动的主要体现。
- 需要指出的是,这里的进站事件可以理解为netty读取外界(如客户端)传入信息的行为;出站事件是指向客户端发送报文的行为,往往是作为入站事件的响应而出现的(当然也有主动发送如广播、定时消息等)。
3、ChannelHandler
概念
ChannelHandler从大类上分为两类:ChannelInboundHandler与ChannelOutboundHandler。分别对应处理了上图中的入站事件和出站事件,这也是很多作者会像下方这样描述pipline与ChannelHandler的关系的原因(图源网络):
而事实上这样的图很容易给读者造成误导,认为ChannelInboundHandler与ChannelOutboundHandler是在两条不同的线上。