netty使用介绍
- 2016-04-30 22:08:00
- admin
- 原创 3016
一、netty使用介绍
1、示例文档:https://netty.io/wiki/index.html
2、帮助文档:https://netty.io/wiki/user-guide-for-4.x.html
3、ServerBootstrap用于初始化服务端,Bootstrap用于初始化客户端;
4、NioServerSocketChannel实现了ServerSocketChannel,用于服务端通道;
5、NioSocketChannel实现了SocketChannel,用于客户端通道,用于已建立通道;
channel实现:
1、AbstractChannel包含一个pipeline,默认实现是DefaultChannelPipeline;
2、DefaultChannelPipeline包含一个双向链表,链表成员是DefaultChannelHandlerContext;
3、DefaultChannelHandlerContext包含一个handler,ChannelHandler各种实现类;
4、DefaultChannelHandlerContext包含一个executionMask,标识handler实现了哪些方法;
5、executionMask对应标识存在时,handler对应方法才会被调用,避免了不相关的handler调用;
6、接收消息时,按照双向链表正向调用所有handler,发送消息时,按照双向链表反向调用所有handler;
channel注册:
1、MultiThreadIoEventLoopGroup包含一个数组,数组成员是SingleThreadIoEventLoop,默认个数CPU核数*2;
2、SingleThreadIoEventLoop包含一个ioHandler,默认实现是NioIoHandler;
3、NioIoHandler包含一个selector,默认实现是Selector;
4、MultiThreadIoEventLoopGroup.register(channel),分配给channel一个SingleThreadIoEventLoop;
5、SingleThreadIoEventLoop.register(channel),生成一个注册任务,提交任务时自动启动线程;
6、AbstractChannel.AbstractUnsafe.register(eventLoop,promise),生成一个注册任务,提交任务时自动启动线程;
7、AbstractChannel.AbstractUnsafe.register0(promise),Channel关联的SelectableChannel注册到Selector;
8、SingleThreadIoEventLoop.register(handle),Channel关联的SelectableChannel注册到Selector;
9、NioIoHandler.register(handle),Channel关联的SelectableChannel注册到Selector;
10、ChannelInitializer.initChannel(channel),服务端和客户端通道注册成功后调用;
IO事件处理:
1、SingleThreadIoEventLoop.run(),其中一个步骤是IO事件处理;
2、SingleThreadIoEventLoop.runIo(),IO事件处理;
3、NioIoHandler.run(context),IO事件处理;
4、AbstractNioChannel.AbstractNioUnsafe.handle(registration,event),IO事件处理;
代码示例:
1、DiscardServer.java、DiscardServerHandler.java
2、TimeServer.java、TimeServerHandler.java
3、TimeClient.java、TimeClientHandler.java
二、ByteBuf使用介绍
ByteBuf使用介绍:
1、ByteBuf.readableBytes(),可读字节数量;
2、ByteBuf.markReaderIndex(),标记读位置;
3、ByteBuf.resetReaderIndex(),恢复读位置;
4、ByteBuf.skipBytes(length),丢弃指定数量字节;
5、ByteBuf.writableBytes(),可写字节数量,等于capacity-writerIndex;
6、ByteBuf.maxWritableBytes(),最大可写字节数量,等于maxCapacity-writerIndex;
7、ByteBuf.discardReadBytes(),前移缓存数据,重新利用已读空间,readerIndex等于零;
8、ByteBuf包含读位置和写位置,所以不需要flip操作,ridx和widx之间就是有效数据;
ByteBuf复制以及组合:
1、ByteBuf.copy(),底层数据深度复制;
2、ByteBuf.duplicate(),底层数据共享,读写位置相互独立,maxCapacity一致;
3、ByteBuf.retainedDuplicate(),功能跟duplicate一致,但会增加原始缓存引用计数;
4、ByteBuf.slice(index,length),底层数据共享,读写位置相互独立,maxCapacity等于length;
5、ByteBuf.retainedSlice(index,length),功能跟slice一致,但会增加原始缓存引用计数;
6、Unpooled.wrappedBuffer(buffers),组合多个缓存,buffers引用计数转移到组合缓存;
ByteBufUtil使用介绍:
1、ByteBufUtil.hexDump(array),字节数组转换为16进制字符串;
2、ByteBufUtil.hexDump(buffer),字节数组转换为16进制字符串;
3、ByteBufUtil.indexOf(needle,haystack),needle在haystack的位置,如果不存在则返回-1;
4、ByteBufUtil.encodeString(alloc,src,charset),转换字符串为缓存,src=CharBuffer.wrap(str);
三、ByteBuf分配器介绍
ByteBuf分配器介绍:
1、UnpooledByteBufAllocator,不具备缓存功能的内存分配器,内存回收时直接释放;
2、PooledByteBufAllocator,具备缓存功能的内存分配器,内存回收时放回内部缓存;
3、AdaptiveByteBufAllocator,自适应内存分配器,只有部分内存会缓存,默认分配器;
4、ByteBufUtil.DEFAULT_ALLOCATOR,ByteBufAllocator.DEFAULT,默认分配器;
5、Unpooled,内存分配工具类,包含多个内存分配工具方法;
PooledByteBufAllocator实现详解:
1、pageSize默认8K,chunkSize默认4M;
2、每个线程包含一个PoolThreadCache,每个Cache包含一个PoolArena;
3、不同线程有可能复用PoolArena,每个PoolArena包含若干PoolChunk;
4、分配内存小于pageSize*4,PoolChunk分配PoolSubpage,包含若干小型对象,然后从中取出一个;
5、分配内存大于等于pageSize*4,小于等于chunkSize,PoolChunk直接分配;
6、分配内存大于chunkSize,PoolArena分配一个特殊的不缓存的PoolChunk;
7、内存释放时,小型对象被放回PoolSubpage,多个PoolSubpage只能保留一个;
8、内存释放时,普通对象直接被回收,大型对象直接被回收;
PooledByteBufAllocator缓存介绍:
1、useCacheForAllThreads,是否所有线程使用缓存,默认false;
2、smallCacheSize,每个线程的每种小型对象最大缓存数量,默认256个;
3、normalCacheSize,每个线程的每种普通对象最大缓存数量,默认64个;
4、maxCachedBufferCapacity,允许缓存的最大普通对象,默认32K;
5、cacheTrimInterval,每个线程回收不常用缓存间隔,默认8192次缓存分配;
PooledByteBufAllocator接口介绍:
1、ByteBuf heapBuffer(initialCapacity),分配堆内存;
2、ByteBuf directBuffer(initialCapacity),分配直接内存;
3、long pinnedHeapMemory(),已经分配的堆内存;
4、long pinnedDirectMemory(),已经分配的直接内存;
5、boolean trimCurrentThreadCache(),当前线程回收不常用缓存;
6、String dumpStats(),显示分配器状态;
四、handler使用介绍
handler使用介绍:
1、ChannelInboundHandler用于处理数据接收,默认实现是ChannelInboundHandlerAdapter;
2、ChannelOutboundHandler用于处理数据发送,默认实现是ChannelOutboundHandlerAdapter;
3、ChannelDuplexHandler用于处理数据接收和数据发送,同时实现了Inbound和Outbound;
4、SimpleChannelInboundHandler继承了ChannelInboundHandlerAdapter,处理指定类型的消息;
5、LoggingHandler继承了ChannelDuplexHandler,支持设置日志级别,用在服务端可以监控新连接;
6、handler需要释放传递给他的ReferenceCounted对象,ByteBuf是引用计数对象;
7、codec也是handler,用于处理数据编码和数据解码,不用于处理具体业务逻辑;
codec使用介绍:
1、MessageToByteEncoder用于编码对象,encode(ctx,msg,out)子类需要实现的编码方法;
2、ByteToMessageDecoder帮助解码,他会一直缓存数据,直到数据可以成功解码一个消息;
3、ByteToMessageDecoder.decode需要判断数据长度是否足够解码,每次仅需解码一个消息;
4、ByteToMessageDecoder.decode成功解码一个消息可能被调用多次,编码时需要考虑重入情况;
5、ReplayingDecoder帮助文档:https://netty.io/4.1/api/io/netty/handler/codec/ReplayingDecoder.html
6、ReplayingDecoder继承ByteToMessageDecoder,具备父类功能,且在解码时不用判断数据长度是否足够;
7、ReplayingDecoder包含ReplayingDecoderByteBuf,该类在读取数据且长度不够时,抛出异常并恢复读位置;
8、ReplayingDecoder.checkpoint更新解码状态,避免重复解码时,执行所有步骤;
codec使用介绍:
1、LineBasedFrameDecoder按行解析消息,maxLength消息最大长度;
2、DelimiterBasedFrameDecoder按分隔符解析消息,单个分隔符可以包含多个字符;
3、帮助文档:https://netty.io/4.1/api/io/netty/handler/codec/DelimiterBasedFrameDecoder.html
4、FixedLengthFrameDecoder解析定长消息,frameLength定长消息大小;
5、LengthFieldBasedFrameDecoder解析带长度字段的消息,maxFrameLength消息最大长度;
6、帮助文档:https://netty.io/4.1/api/io/netty/handler/codec/LengthFieldBasedFrameDecoder.html
codec使用介绍:
1、MessageToMessageEncoder继承了ChannelOutboundHandlerAdapter,编码一种类型到另一种类型;
2、MessageToMessageDecoder继承了ChannelInboundHandlerAdapter,解码一种类型到另一种类型;
3、StringEncoder继承了MessageToMessageEncoder,用于编码字符串,可以设置字符编码charset;
4、StringDecoder继承了MessageToMessageDecoder,用于解码字符串,需要先使用DelimiterBasedFrameDecoder;