创建一个channel实例,并把它register到eventLoopGroup中之后,这个channel然后处于inactive状态,仍然是不可用的.只有在bind或connect方法调用成功之后才能正常.因此bind或connect算是channel初始化的最后一步,本章这就重点分析这两个功能的实现. 接下来的代码分析如果没有特别说明,都是以NioSocketChannel为例. bind实现 bind方法的调用栈如下: io.netty.channel.AbstractChannel#bi…
  结构设计 Channel的NIO实现位于io.netty.channel.nio包和io.netty.channel.socket.nio包中,其中io.netty.channel.nio是抽象实现,io.netty.channel.socket.nio最终实现.下面是Channel NIO相关类的派生图: NIO实现最终派生出3个类型NioServerSocketChannel实现了tcp server, NioSocketChannel实现了tcp client, NioDatagram…
事件触发.传递.处理是DefaultChannelPipleline实现的另一个核心能力.在前面在章节中粗略地讲过了事件的处理流程,本章将会详细地分析其中的所有关键细节.这些关键点包括: 事件触发接口和对应的ChannelHandler处理方法. inbound事件的传递. outbound事件的传递. ChannelHandler的eventExecutor的分配. 事件的触发方法和处理方法 netty提供了三种触发事件的方式:通过Channel触发,通过ChannelPipleline触发,…
io.netty.handler.timeout.IdleStateHandler功能是监测Channel上read, write或者这两者的空闲状态.当Channel超过了指定的空闲时间时,这个Handler会触发一个IdleStateEvent事件. 在第一次检测到Channel变成active状态时向EventExecutor中提交三个延迟任务: ReaderIdleTimeoutTask: 检测read空闲超时. WriterIdleTimeoutTask: 检测write空闲超时. A…
编解码框架和一些常用的实现位于io.netty.handler.codec包中. 编解码框架包含两部分:Byte流和特定类型数据之间的编解码,也叫序列化和反序列化.不类型数据之间的转换. 下图是编解码框架的类继承体系: 其中MessageToByteEncoder和ByteToMessageDecoder是实现了序列化和反序列化框架. MessageToMessage是不同类型数据之间转换的框架. 序列化抽象实现: MessageToByteEncoder<I> 序列化是把 I 类型的数据转换…
本章不会直接分析Netty源码,而是通过使用Netty的能力实现一个自定义协议的服务器和客户端.通过这样的实践,可以更深刻地理解Netty的相关代码,同时可以了解,在设计实现自定义协议的过程中需要解决的一些关键问题. 本周章涉及到的代码可以从github上下载: https://github.com/brandonlyg/tinytransport.git. 设计协议 本章要设计的协议是基于TCP的应用层协议.在设计一个协议之前需要先回答以下几个问题: 使用场景是什么? 这个协议有哪些功能? 性…
 本章分析Nio Channel的数据读取功能的实现. Channel读取数据需要Channel和ChannelHandler配合使用,netty设计数据读取功能包括三个要素:Channel, EventLoop和ChannelHandler.Channel有个read方法,这个方法不会直接读取数据,它的作用是通知持有当前channel的eventLoop可以从这个这个channel读取数据了,这个方法被调用之后eventLoop会在channel有数据可读的时候从channel读出数据然后把数…
io.netty.channel.DefaultChannelPipeline implements ChannelPipleline   DefaultChannelPiple给出了ChannelPipleline的默认实现.ChannelPipleline是一个双向链表,本章的内容是分析默认实现中双向链表的实现. 双向列表的的数据结构 DefaultChannelPiple使用了三种节点类型: HeadContext, TailContext, DefaultChannelHandlerCo…
写数据是NIO Channel实现的另一个比较复杂的功能.每一个channel都有一个outboundBuffer,这是一个输出缓冲区.当调用channel的write方法写数据时,这个数据被一系列ChannelOutboundHandler处理之后,它被放进这个缓冲区中,并没有真正把数据写到socket channel中.然后再调用channel的flush方法,flush会把outboundBuffer中数据真正写到socket channel.正常情况下flush之后,数据已经真正写完了.…
把NIO事件转换成对channel unsafe的调用或NioTask的调用 processSelectedKeys()方法是处理NIO事件的入口: private void processSelectedKeys() { if (selectedKeys != null) { processSelectedKeysOptimized(); } else { processSelectedKeysPlain(selector.selectedKeys()); } } 这个方法会调用process…
接口定义 io.netty.channel.EventLoopGroup extends EventExecutorGroup 方法 说明 ChannelFuture register(Channel channel) 把一个channel注册到一个EventLoop ChannelFuture register(Channel channel, ChannelPromise promise); 同上 io.netty.channel.EventLoop extends OrderedEvent…
Channel提供了3个方法用来实现关闭清理功能:disconnect,close,deregister.本章重点分析这个3个方法的功能的NIO实现. disconnect实现: 断开连接 disconnect方法的调用栈如下: io.netty.channel.AbstractChannel#disconnect() io.netty.channel.DefaultChannelPipeline#disconnect() io.netty.channel.AbstractChannelHand…
全名: io.netty.channel.Channel Channel内部定义了一个Unsafe类型,Channel定义了对外提供的方法,Unsafe定义了具体实现.我把Channel定义的的方法分为三种类型: 辅助方法. outbound方法 inbound方法 下面依次对这三种方法给予详细说明:   1. 辅助方法 方法 说明 EventLoop eventLoop() 得到EventLoop实例,每个Channel实例都会被注册到一个EventLoop中,这个EventLoop实例就是C…
netty是java开源社区的一个优秀的网络框架.使用netty,我们可以迅速地开发出稳定,高性能,安全的,扩展性良好的服务器应用程序.netty封装简化了在服务器开发领域的一些有挑战性的问题:jdk nio的使用:多线程并发:扩展性.它还提供了多种应用层协议的支持:http/https/websock, protobuf, 自定义协议, 简化了服务器协议的开发. netty是一个基于事件驱动的框架,它把事件分成两种类型:输入事件(inbound)和输出事件(outbound), 整个框架都是围…
netty线程体系概览 netty的高并发能力很大程度上由它的线程模型决定的,netty定义了两种类型的线程: I/O线程: EventLoop, EventLoopGroup.一个EventLoopGroup包含多个EventLoop, 每个Channel会被注册到一个,一个EventLoop中, 一个EventLoop可以包含多个Channel.Channel的Unsafe实例的方法必须要在EventLoop中执行(netty中明确指明的不需要在I/O线程中执行的几个方法除外,前面的章节中有…
上一章讲了EventExecutorGroup的整体结构和原理,这一章我们来探究一下它的具体实现. EventExecutorGroup和EventExecutor接口 io.netty.util.concurrent.EventExecutorGroup java.util.concurrent.ScheduledExecutorService EventExecutorGroup继承了ScheduledExecutorService接口,它自己定义了如下的新方法 方法 说明 EventExe…
AbstractChannel和AbstractUnsafe抽象类 io.netty.channel.AbstractChannel 从本章开始,会有大量的篇幅涉及到代码分析.为了能够清晰简洁的地说明代码的结构和功能,我会用代码注释+独立段落的方式加以呈现. 所以,为你能更好地理解代码,请不要忽略代码中黑体字注释.   AbstractChannel和AbstractUnsafe之间的关系 AbstractChannel实现了Channel接口,AbstractUnsafe实现了Unsafe.这…
数据包编解码过程中主要的工作就是:在编码过程中进行序列化,在解码过程中从Byte流中分离出数据包然后反序列化.在MessageToByteEncoder中,已经解决了序列化之后的问题,ByteToMessageDecoder中已经部分第解决了从Byte流中分离出数据包的问题.实现具体的数据包编解码,只需要实现MessageToByteEncoder的encode和ByteToMessageDecoder的decode方法即可. 为了方便开发者使用Netty,在io.netty.handler.c…
    ByteBuf的I/O主要解决的问题有两个: 管理readerIndex和writerIndex.这个在在AbstractByteBuf中解决. 从内存中读写数据.ByteBuf的不同实现主要使用两种内存:堆内存表示为byte[]:直接内,可能是DirectByteBuffer或者是一块裸内存.这个问题在HeapByteBufUtil, UnsafeByteBufUtil中解决. 管理readerIndex和writerIndex     AbstractByteBuf中实现了对read…
ByteBuf内存分配和释放由具体实现负责,抽象类型只定义的内存分配和释放的时机. 内存分配分两个阶段: 第一阶段,初始化时分配内存.第二阶段: 内存不够用时分配新的内存.ByteBuf抽象层没有定义第一阶段的行为,但定义了第二阶段的方法: public abstract ByteBuf capacity(int newCapacity) 这个方法负责分配一个长度为newCapacity的新内存. 内存释放的抽象实现在AbstractReferenceCountedByteBuf中实现,这个类实…
io.netty.buffer.PooledByteBuf<T>使用内存池中的一块内存作为自己的数据内存,这个块内存是PoolChunk<T>的一部分.PooledByteBuf<T>是一个抽象类型,它有4个派生类: PooledHeapByteBuf, PooledUnsafeHeapByteBuf 使用堆内存的PooledByteBuffer<byte[]>. PooledDirectByteBuf, PooledUnsafeDirectByteBuf…
PoolArena实现了用于高效分配和释放内存,并尽可能减少内存碎片的内存池,这个内存管理实现使用PageRun/PoolSubpage算法.分析代码之前,先熟悉一些重要的概念: page: 页,一个页是可分配的最小的内存块单元,页的大小:pageSize = 1 << n (n <= 12). chunk: 块,块是多个页的集合.chunkSize是块中所有page的pageSize之和. Tiny: <512B的内存块. Small: >=512B, <pageSi…
io.netty.channel.ChannelPipeline   设计原理 上图中,为了更直观地展示事件处理顺序, 故意有规律地放置两种handler的顺序,实际上ChannelInboundHandler和ChanneOutboundHandler的顺序可以是任意,取决于用户调用add方法把handler方在哪里.   ChannelPipeline的特性: 1. 它是一个双向链表 2. 每个节点持有一个ChannelHandler实例,这个实例可以是ChannelInboundHandl…
本章开始分析ChannelHandler实现代码.ChannelHandler是netty为开发者提供的实现定制业务的主要接口,开发者在使用netty时,最主要的工作就是实现自己的ChannelHandler.ChannelHandler在设计上需要和ChannelPipeline配合共同实现pipeline的事件传递能力,这要求ChannelHandler需要实现一些固定的基本功能.由于这个原因,如果让用户自己完整地实现,会显得比较麻烦.为此netty实现类一系列的类来帮助开发者以简单的方式实…
概述 开启博客分享已近三个月,感谢所有花时间精力和小编一路学习和成长的伙伴们,有你们的支持,我们继续再接再厉 **本人博客网站 **IT小神 www.itxiaoshen.com 定义 Tomcat官网 http://tomcat.apache.org/ Apache Tomcat软件是Jakarta Servlet.Jakarta Server Pages.Jakarta Expression Language.Jakarta WebSocket.Jakarta annotation和Jaka…
Universal-Image-Loader在github上的地址:https://github.com/nostra13/Android-Universal-Image-Loader 它的基本使用请参考我的另一篇博客 http://www.cnblogs.com/yuan1225/p/8426900.html,下面我从源码角度研究它. ImageLoader使用的是双重判断的懒汉试单例模式. /** Returns singleton class instance */ public stat…
简介 Java NIO 是由 Java 1.4 引进的异步 IO. Java NIO 由以下几个核心部分组成: Channel Buffer Selector NIO 和 IO 的对比 IO 和 NIO 的区别主要体现在三个方面: IO 基于流(Stream oriented), 而 NIO 基于 Buffer (Buffer oriented) IO 操作是阻塞的, 而 NIO 操作是非阻塞的 IO 没有 selector 概念, 而 NIO 有 selector 概念. 基于 Stream…
前面两章分析的PoolChunk和PoolSubpage,从功能上来说已经可以直接拿来用了.但直接使用这个两个类管理内存在高频分配/释放内存场景下会有性能问题,PoolChunk分配内存时算法复杂度最高的是allocateNode方法,释放内存时算法复杂度最高的是free方法. PoolChunk中二叉树的高度是maxOrder,  那么算法负责度是O(maxOrder),netty默认的maxOrder是11.另外,PoolChunk不是线程安全的,如果在多线程环境下需要加锁调用,这个开销比算…
本文通过阅读Netty源码,解析Netty服务端启动过程. 源码分析基于Netty 4.1 Netty是一个高性能的网络通信框架,支持NIO,OIO等多种IO模式.通常,我们都是使用NIO模式,该系列文章也是解析Netty下NIO模式的实现. 首先,看一个NIO网络通信示意图 Netty中NIO网络通信过程在此基础上实现,下面来看一下具体实现. Channel 首先,看一下Netty中的通道Channel,它代表了一个能完成IO操作的通道,提供read, write, connect, bind…
本文继续阅读Netty源码,解析ChannelPipeline事件传播原理,以及Netty读写过程. 源码分析基于Netty 4.1 ChannelPipeline Netty中的ChannelPipeline可以理解为拦截器链,维护了一个ChannelHandler链表,ChannelHandler即具体拦截器,可以在读写过程中,对数据进行处理. ChannelHandler也可以分为两类. ChannelInboundHandler,监控Channel状态变化,如channelActive,…