吐槽:

技术,是服务于人而不是局限住人的。技术能力取决于个人,而经验取决于时间。

Netty

  • Netty框架是基于事件机制的,简单说,就是发生什么事,就找相关处理方法。就跟着火了找119,cj了找110一个道理。
    所以,这里,我们处理的是当客户端和服务端完成连接以后的这个事件。什么时候完成的连接,Netty知道,他告诉我了,我就负责处理,并且封装了nio开发复杂的操作,简化开发,这就是框架的作用。

  • 学习netty,不学习它的零拷贝机制,那就白学了。在nio开发中,buffer的空间大小在一开始申请内存空间时已经定死了,如果容量不足怎么办呢?(单个buffer的数据不完整)
    重新分配一个更大的buffer,然后将当前数据copy过去,这种做法万万是不可行的。在这种高并发开发中,应尽量避免数据在本机的停留时间、避免消耗本机资源,更别说这种又费马达又费电的数据拷贝了(谨记)。

  • CPU处理数据必须先将数据读入内存,再从内存读入到寄存器。然后再做相关计算处理,Zero Copy是不经过CPU的处理。

如果你还没想到办法,那就看看Netty的零拷贝机制吧!!

  • 其实netty也是模仿了Linux的数据拷贝机制
  • 看看Zero Copy实现的思路:
    CompositeChannelBuffer类的作用是将多个ChannelBuffer组成一个虚拟的ChannelBuffer来进行操作。
    为什么说是虚拟的呢,因为CompositeChannelBuffer并没有将多个ChannelBuffer真正的组合起来,而只是保存了他们的引用,这样就避免了数据的拷贝,实现了Zero Copy。
看看代码变量大概就明白了:
private int readerIndex;
private int writerIndex;
private ChannelBuffer[] components;
private int[] indices;
private int lastAccessedComponentId;
  • 我的理解是这样,声明一个buffer数组,调用者按顺序将buffer返回数组里,并记录相应索引,只要保证获取数据时数据没有遗漏,顺序正确即可。
    其实想想,StringBuffer,不也就这么实现的吗?以便提供更好的性能。

  • Netty提供的api使用:
    //wrappedBuffer的实现依赖于CompositeChannelBuffer
    ChannelBuffer message = ChannelBuffers.wrappedBuffer(header, body);
    ChannelBuffer messageWithFooter = ChannelBuffers.wrappedBuffer(message, footer);

  • Netty 4.0之后就不同了,ChannelBuffer改名ByteBuf,成为了单独项目buffer,并且为了性能优化,加入了BufferPool之类的机制,已经变得比较复杂了(本质倒没怎么变)

文章目录
  1. 1. 吐槽:
  2. 2. Netty
  3. 3. 如果你还没想到办法,那就看看Netty的零拷贝机制吧!!
    1. 3.0.1. 看看代码变量大概就明白了:

Sides

IT技术分享博客