深入理解Netty

Netty

Posted by TBKK on December 10, 2018

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之间的关系 image

Netty使用方式

总结

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