Netty初步探索
简介
-
Netty 是一个 基于 NIO 的 client-server(客户端服务器)框架,使用它可以快速简单地开发网络应用程序。
-
它极大地简化并优化了 TCP 和 UDP 套接字服务器等网络编程,并且性能以及安全性等很多方面甚至都要更好。
-
支持多种协议 如 FTP,SMTP,HTTP 以及各种二进制和基于文本的传统协议
三层结构
-
最低层为支持零拷贝功能的自定义Byte buffer;
-
中间层为通用通信API;
-
上层为可扩展的事件模型。
核心组件
-
EventLoopGroup:Netty内部都是通过线程在处理各种数据,EventLoopGroup就是用来管理调度他们的,注册Channel。
-
EventLoop:
EventLoop
的主要作用实际就是负责监听网络事件并调用事件处理器进行相关 I/O 操作的处理。 -
ChannelPipleline:代表了处理业务逻辑的管线,netty中事务的处理是按照责任链中的机制来进行的,服务器端收到客户端的请求,然后决定是否发消息回给客户端,首先服务器或者客户端收到消息走继承channeinboundhandler接口的实现类,发出信息的时候走channeloutboundhandler实现类。
-
Channel:代表了一个客户端和服务器端的一条连接,服务器端可以维护多个连接,
Channel
接口是 Netty 对网络操作抽象类,它除了包括基本的 I/O 操作,如bind()
、connect()
、read()
、write()
等。 -
ChannelInitializer:初始化ChannelHandler的地方,确定channellhandler的执行顺序
-
ChannelFuture :任务执行的结果。
-
Bootstrap 和ServerBootstrap:都是客户端的启动引导类/辅助类,Netty中客户端和服务器端连接所使用的类,客户端连接的是远程服务器的ip,服务器端代表了绑定本地的ip,客户端使用的是单个的EventLoopGroup,服务器端使用的是两个EventLoopGroup,是因为server端需要绑定本地的ip端口,这个连接使用ServerChannel来代表,另外的Channel集合代表了客户端和服务器端的连接。
组件关联
1.Channel
和 EventLoop
Channel
为 Netty 网络操作(读写等操作)抽象类,EventLoop
负责处理注册到其上的Channel
处理 I/O 操作,两者配合参与 I/O 操作。
2.ChannelHandler 和 ChannelPipeline
ChannelHandler
是消息的具体处理器。他负责处理读写操作、客户端连接等事情。ChannelPipeline
为ChannelHandler
的链,提供了一个容器并定义了用于沿着链传播入站和出站事件流的 API 。当Channel
被创建时,它会被自动地分配到它专属的ChannelPipeline
。
3.EventloopGroup 和EventLoop
EventLoopGroup
包含多个 EventLoop
(每一个 EventLoop
通常内部包含一个线程),EventLoop
处理的 I/O 事件都将在它专有的 Thread
上被处理,即 Thread
和 EventLoop
属于 1 : 1 的关系,从而保证线程安全。
处理器
1.源码分析
SimpleChannelInboundHandler
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
boolean release = true;
try {
if (acceptInboundMessage(msg)) {
@SuppressWarnings("unchecked")
I imsg = (I) msg;
channelRead0(ctx, imsg);
} else {
release = false;
ctx.fireChannelRead(msg);
}
} finally {
if (autoRelease && release) {
ReferenceCountUtil.release(msg);
}
}
}
ChannelInboundHandlerAdapter
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.fireChannelRead(msg);
}
从源码上上面,我们可以看出,当方法返回时,SimpleChannelInboundHandler会负责释放指向保存该消息的ByteBuf的内存引用。而ChannelInboundHandlerAdapter在其时间节点上不会释放消息,而是将消息传递给下一个ChannelHandler处理。
2.从类定义看
SimpleChannelInboundHandler
public abstract class SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter
ChannelInboundHandlerAdapter
public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler
-
SimpleChannelInboundHandler<T>是抽象类,而ChannelInboundHandlerAdapter是普通类,
-
SimpleChannelInboundHandler支持泛型的消息处理,而ChannelInboundHandlerAdapter不支持泛型