文章目录
bio,nio,aio区别
IO类型
1.同步,异步
数据拷贝的过程是由操作系统做的,是异步。如果是程序亲自取的是同步。
2.阻塞,非阻塞
阻塞:一个请求对一个线程
非阻塞:一个线程对多个请求
在数据就绪前需不需要等待,需要的话为阻塞。
看一张比较模糊的图,将就看吧~
有两个阶段:数据就绪,数据拷贝
nio就是一个一个线程处理多个请求,简称多路复用。
结论:阻塞,非阻塞看数据就绪,同步异步看数据拷贝过程。
区别
多路复用
redis也是使用多路复用的情况,在nio上,基于selector的基础上实现。会创建不同的socket,由selector来决定哪个socket执行。当然一个线程可以执行不同的业务~
来这某乎的讲解,就是当哪个线路有数据,就拨到哪条线,进行传输。
上面的nio是同步非阻塞就好理解了,基于selector IO请求的时候,不会阻塞的,但是IO线程处理是同步的,必须等结果返回。
参考博客
Netty基础
netty大致流程图
看下上面的大概流程图,Netty是由事件进行驱动的,不同事件交由不同ChannelHandler进行处理。
当一个请求过来时,EventLoopGroup会跟他分配一个EventLoop,他有一个线程来负责接待IO请求,一堆线程来处理IO。跟dubbo的线程池模型有内味~(当然多路复用也在这里体现)
接着将请求传到Channel Pipeline中,其中ChannelHandler是作为一个出入站来处理各种信息,其中包含解码编码。
ByteBuf
大家都知道Nio是基于字节缓存区,传统io基于字节流。
Nio的Buffer
get和set的话是不会移动索引的,read,write会移动ByteBuf的读写索引,当超过索引的时候会报超出范围异常。
DIRECT Buffer
这个很像面试题的零拷贝~ kafka就使用了,一般程序做处理的时候,是先从磁盘读到数据—>内核空间—>用户空间—>flush到socket输出。
那么零拷贝:就是从内核空间直接刷到socket。
Channel
ChannelFuture
由于netty是非阻塞的,所以需要channelFuture去进行操作,提供listener来监听返回结果
ChannelFuture由Channel来生成,加上listener根据结果做出相关处理。
EventLoop
ChannelPipeline
ChannelPipeline 提供了一个容器给 ChannelHandler 链并提供了一个API 用于管理沿着链入站和出站事件的流动。
每个 Channel 都有自己的ChannelPipeline,当 Channel 创建时自动创建的。 ChannelHandler 是如何安装在 ChannelPipeline? 主要是实现了ChannelHandler 的抽象 ChannelInitializer。
ChannelInitializer子类 通过 ServerBootstrap 进行注册。当它的方法 initChannel() 被调用时,这个对象将安装自定义的 ChannelHandler 集到 pipeline。
当这个操作完成时,ChannelInitializer 子类则 从 ChannelPipeline 自动删除自身。
ChannelHandler
channelRead0的时候会移动byteBuffer的索引,channelRead是不会的
Coder
ChannelHandlerContext
上下文可以用来传递值。
心跳
参考资料
- Netty in Action