Netty基础
TCP/IP
TCP是一个传输层协议,我们熟知的HTTP则是应用层协议,是基于TCP上再做封装。 很多东西都是基于TCP做的,比如RPC调用。 基于 TCP 的协议实现的 RPC 调用,由于 TCP 协议处于协议栈的下层, 能够更加灵活地对协议字段进行定制,减少网络开销,提高性能,实现更大的吞吐量和并发数。
HTTP 协议是上层协议,发送包含同等内容的信息, 使用 HTTP 协议传输所占用的字节数会比使用 TCP 协议传输所占用的字节数更高。
因此在同等网络下,通过 HTTP 协议传输相同内容, 效率会比基于 TCP 协议的数据效率要低,信息传输所占用的时间也会更长,当然压缩数据,能够缩小这一差距。
需要注意的是,TCP是一个基于流的传输方式,即你一次发送100个字节的数据,接收端并不会按照一次接受100个字节, 会分批的接受,共计100个字节的数据。
NIO/BIO
对于BIO首先需要了解的是B的含义,B:Block
在类似于网络中进行read, write, connect一类的系统调用时会被卡住。
举个例子,当用read去读取网络的数据时,是无法预知对方是否已经发送数据的。因此在收到数据之前,能做的只有等待,直到对方把数据发过来,或者等到网络超时。
对于单线程的网络服务,这样做就会有卡死的问题。因为当等待时,整个线程会被挂起,无法执行,也无法做其他的工作。
所以再BIO环境下,我们常用的方法是,有有个链接,就fork出一个子进程,来做对应IO操作。 显而易见,这种工作效率极其低下。于是我们有了NIO。
对于NIO,(N的意思为:Non-Blocking)我们最熟悉的通信模型就是select模型了。
如何实现非阻塞的?
在BIO模式下,调用read,如果发现没数据已经到达,就会Block住。
在NIO模式下,调用read,如果发现没数据已经到达,就会立刻返回-1, 并且errno被设为EAGAIN。
那么问题来了,如果有好多都要监听,我们总不能一个个的去轮询read吧。根本无法确定什么时候回来数据。 于是,IO多路复用产生了,就是把这些事情交给操作系统去做。把一堆fd丢给操作系统,让操作系统监控,一旦有数据过来,告知用户态即可。
linux下的IO模型: select,poll,epoll。
在Linux下,基于epoll的IO多路复用是解决这个问题的最佳方案;epoll相比select和poll有很大的性能优势和功能优势,适合实现高性能网络服务。
linux上Netty的底层实现就是用epoll。
reactor模式
什么是reactor模式
反应器设计模式(Reactor pattern)是一种为处理并发服务请求,并将请求提交到一个或者多个服务处理程序的事件设计模式。 当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收所有的请求,然后派发这些请求至相关的工作线程进行处理。 简单说,就是如何处理多个客户端的并发请求的解决模式。
关于详细的reactor线程模型可以参考下面: http://www.blogjava.net/DLevin/archive/2015/09/02/427045.html
Netty做了什么
Netty封装了NIO,更易用
Netty采用责任链模式,便于扩展
Netty采用reactor线程模型,无锁化方式更高效率
Netty采用零拷贝技术,提升效率
- 采用堆外内存
- Netty对于Buffer的合并采用了CompositeByteBuf形式,避免内存拷贝,只是保存了引用
- 底层使用了FileChannel.transferTo,依赖操作系统实现零拷贝
Netty核心组件
- Channel
- ChannelFuture
- EventLoop
- ChannelHandler
- ChannelPipeline
Channel
Channel是网络IO的抽象类,read,write之类
ChannelFuture
Channel的操作都为异步,所以需要ChannelFuture做回调
EventLoop
当一个连接到达时,Netty 就会注册一个 Channel,然后从 EventLoopGroup 中分配一个 EventLoop 绑定到这个Channel上,在该Channel的整个生命周期中都是有这个绑定的 EventLoop 来服务的。
ChannelHandler
ChannelHandler 为 Netty 中最核心的组件,它充当了所有处理入站和出站数据的应用程序逻辑的容器。 说白了,就是我们写业务逻辑的地方。
ChannelPipeline
借用网上的一张图表示Channel、ChannelPipeline、ChannelHandlerContext和ChannelHandler之间的关系

Netty使用方式
总结
技术最终为业务服务的,最终为业务场景提供支撑。一定要举一反三,活学活用,不要拿来主义。