您的位置:首页 > 其它

Netty初探-基本概念和相关类介绍

2016-10-23 23:52 656 查看

基本概念

概念

Netty是由JBOSS提供的一个Java NIO开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。可实现的功能见下图:



Netty vs Mina vs Grizzly

Mina的设计理念最为优雅,Netty和Mina的主导作者是同一人。

Mina出自于Apache,Netty出身于商业开源大亨Jboss,而Grizzly则出身于土鳖Sun公司。

Netty作为NIO框架的优势

API使用简单

功能强大,预置了多种编解码功能,支持多种主流协议

定制能力强,可以通过ChannelHandler对通信框架进行灵活扩展

性能高

社区活跃

相关类

ByteBuf

使用数据传输,需要使用到缓冲区。ByteBuf是个Byte数组的缓冲区,基本功能和JDK的ByteBuffer一致。

两个指针维持缓冲区的读写操作:readerIndex标识读索引,writerIndex标识写索引。

顺序读操作(read)

顺序写操作(write)

Discardable bytes,重用缓冲区,因为缓冲区的分配和释放是个耗时的操作。

clear操作,并不是清空缓冲区内容本身,而是将readerIndex和writerIndex还原为初始分配值。

Mark和Rest,回滚操作实现,备份readerIndex、WriterIndex

查找操作

Derived buffers,类似于数据库的视图。duplicate、copy、slice

转换为标准的ByteBuffer

随机读写(set和get)

ByteBuf类图



堆内存:内存的分配和回收速度快,被JVM自动回收。

直接内存:与Socket Channel通信,少了一次内存复制,速度比堆快。

基于对象池的ByteBuf和普通ByteBuf

ByteBuf相关辅助类

ByteBufHolder,是ByteBuf的容器,对ByteBuf进行包装和抽象。

ByteBufAllocator,字节缓冲区分配器:基于内存池和普通的。

CompositeByteBuf,将多个ByteBuf的实例组装到一起,形成一个统一的视图。

ByteBufUtil,提供了一些静态方法用于操作ByteBuf对象。例如字符串的编码和解码。

Channel 和 Unsafe

Channel用于异步I/O操作,Unsafe是个内部接口,聚合在Channel中协助进行网络读写相关的操作。

ChannelPipeline和ChannelHandler

类似于Servlet和Filter过滤器,是职责链模式的一种变形,主要是为了方便事件的拦截和用户业务逻辑的定制。将Channel的数据管道抽象为ChannelPipeline,消息在ChannelPipeline中流动和传递,ChannelPipeline持有I/O事件拦截器ChannelHandler的链表,由ChannelHandler对I/O事件进行拦截和处理,可以方便地通过新增和删除ChannelHandler来实现不同的业务逻辑定制。

inbound事件通常由I/O线程触发(fire),outbound事件通常由用户主动发起的网络I/O操作。

用户不需要自己创建pipeline,因为使用ServerBootstrap和Bootstrap启动后,Netty会为每个Channel连接创建一个独立的pipeline,用户只需要将自定义的拦截器加入到pipeline中即可。

ChannelHandlerAdapter

ByteToMessageDecoder:ByteBuf解码为业务POJO对象

MessageToMessageDecoder:Netty的二次解码器,将一个对象二次解码为其他对象。

LengthFieldBasedFrameDecoder:半包解码器

类图



EventLoop 和EventLoopGroup

线程模型,Netty框架的主要线程就是I/O线程,被精心设计,即提升了框架的并发性性能,又在很大程度避免锁,局部实现了无锁化机制。

Reactor单线程模型,异步非阻塞I/O,理论上一个线程可以独立处理所有I/O相关的操作。

Reactor多线程模型



Acceptor线程:监听服务端,接受客户端的TCP连接请求,专门的NIO线程。

网络I/O操作

一个NIO线程可以处理N条链路,但是一个链路只对应一个NIO线程,防止并发操作的问题。

-

主从Reactor多线程模型

NIO线程池的引入。

Netty线程模型

并不是一成不变,取决于用户的启动参数配置。



NioEventLoop,需要处理I/O事件,所以必须聚合多路复用其Selector。



Future和Promise

Future用于获取异步操作的结果

ChannelFuture有两种状态:upcompleted和completed;ChannelFuture可以同时增加一个或多个GenericFutureListener。需要注意的是,不要在ChannelHandler中调用ChannelFuture的await()方法,否则会导致死锁。如果I/O线程和用户线程是同一个线程,就会导致I/O线程等待自己通知操作系统,属于自己把自己挂死。

Promise是可写的Future,对Future进行扩展,用于设置I/O操作的结果。强烈建议通过增加监听器Listener的方式接受异步I/O操作结果的通知,而不是调用wait或者sync阻塞用户线程。

(function () {('pre.prettyprint code').each(function () {
var lines = (this).text().split(′\n′).length;varnumbering = $('').addClass('pre-numbering').hide();
(this).addClass(′has−numbering′).parent().append(numbering);
for (i = 1; i
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: