D-1.IO模型概念

1.概念

  • 阻塞/非阻塞:线程处理模式
  • 同步/异步:通信相关的模式

  • 同步:需要等待响应结果

  • 异步:监视响应结果,不等待。非常少见,需要操作系统底层支持,目前只有Windows的IOCP模型支持。

2.种类

阻塞Blocking 非阻塞(Non-Blocking)
同步 阻塞I/O模型(BIO) 非阻塞I/O模型(NIO)* Reactor
同步 I/O复用模型 信号驱动I/O模型
异步 - 异步I/O模型 Proactor

信号驱动I/O与非阻塞I/O最大的区别在于,I/O数据准备阶段,不需要轮询监视内核是否准备好数据,而是由内核主动发送信号通知用户进程。

3.Socket IO/BIO

image.png

4.NIO

image.png

5.Reactor模型

此模型下业务线程不会被I/O线程所阻塞,极大地提升了IO网络应用程序处理效率。此处的I/O线程就相当于NIO的selector。
Netty对以下三种Reactor模式都能很好地支持:

  • 单线程模式下,业务线程是单一线程,
  • 多线程模式下,业务线程是由线程池来管理。
  • 主从多线程模式下,I/O线程也是由线程池来管理。

image.png

6.Netty模式

NioEventLoop:可以看做是带有selector的线程thread。可以直接跟一个Channel通信,从Channel里拿到数据并进行处理。它不是只执行一次,而是不断地在轮询监听I/O事件来执行业务处理,所以叫Loop。

D-2.Netty实现原理

1.Netty定义

一种Java网络应用开发框架,基于事件机制。目前做网络开发的首选框架,或者说叫事实标准

2.Netty内部三大模块:

传输服务层 协议支持层
Socket & Datagram HTTP & WebSocket SSL & StartTLS Google Protobuf
HTTP Tunnel zlib/gzip Compression Large File Transfer RTSP
In-VM Pipe Legacy Text&Binary Protocols with Unit Testability

- Extensible Event Model:Netty本身事件模型


Netty核心

- Universal Communication API:统一网络通信API

- Zero-Copy-Capable Rich Byte Buffer:支持网络传统的高效数据结构


3.Netty框架特点:

  • 异步
  • 事件驱动
  • 基于NIO

4.Netty基本概念

  • Channel:抽象通道,Java NIO 中的基础概念,代表一个打开的连接,可执行读取/写入 IO 操作。 Netty对Channel的所有IO操作都是非阻塞的。这样不用操作Socket了,直接操作Channel。
  • Channel Future:Java的Future 接口,获取Channle状态是否准备好。只能查询操作的完成情况,或者阻塞当前线程等待操作完成。我们可以将回调方法传给 ChannelFuture,在操作完成时自动执行回调方法。相当于通过事件通知机制拉起了后续需要执行的处理逻辑。
  • Event & Handle:Netty基于事件驱动,事件和处理器可以关联到入站和出站数据流。成套出现的一组概念,拿到Event事件进行相应的Handle处理。

•ChannelHandler
•ChannelOutboundHandler:出站数据出去,适配器•ChannelOutboundHandlerAdapter
•ChannelInboundHandler:入站数据进来,适配器•ChannelInboundHandlerAdapter

  • Encoder & Decoder:处理网络IO时,需要进行序列化和反序列化,转换Java对象与字节流,即编码器和解码器,Netty内置已有很多种开箱即用的编码器解码器。成套出现的一组概念,对入站数据进行解码,基类是ByteToMessageDecoder。对出站数据进行编码,基类是MessageToByteEncoder。
  • ChannelPipiline:数据处理管道就是事件处理器链。有顺序、同一Channel的出站处理器和入站处理器在同一个列表中。把前面的不同的处理器串到这个Pipeline流水线上,用抽象的方式把各种不同的网络应用的复杂内部处理统一起来。

5.Netty运行原理

image.png

6.Netty关键对象

  • Bootstrap/ServerBootstrap:客户端/服务器端 启动线程,开启socket的入口点。
  • EventLoopGroup/EventLoop
  • SocketChannel:

1.ChannelInitializer
2.ChannelPipeline
ChannelInboundHandler
ChannelOutboundHandler
3.ChannelHandler

D-3.Netty常见网络优化

1.粘包拆包优化:

粘包拆包出现的消息错乱都是人为问题。ByteToMessageDecoder提供的一些常见的实现类:

  • 1.FixedLengthFrameDecoder:定长协议解码器,我们可以指定固定的字节数算一个完整的 报文
  • 2.LineBasedFrameDecoder:行分隔符解码器, 遇到\n 或者\r\n,则认为是一个完整的报文
  • 3.DelimiterBasedFrameDecoder:分隔符解码器,分隔符可以自己指定
  • 4.LengthFieldBasedFrameDecoder:变长长度编码解码器,将报文划分为报文头/报文体
  • 5.JsonObjectDecoder:json格式解码器,当检 测到匹配数量的“{” 、”}”或”[””]”时,则认为是一个完整的json对象或者json数组

2.网络拥堵与Nagle算法优化:

  • TCP_NODELAY:缓冲区数据包未装满,但已达到一定等待时间时,就启动发送。
  • MTU:Maxitum Transmission Unit 最大传输单元,一个数据包能装的数据量。一般情况下是1500byte,并非全部的业务数据容量。
  • MSS:Maxitum Segment Size 最大分段大小, 为 MTU - 20(IP) - 20(TCP)=1460,纯业务数据量的报文体。

3.TCP连接优化:

  • 连接建立的3次握手
    1. 客户端:你在吗?
    2. 服务器端:我在,你在吗?
    3. 客户端:我在
  • 连接关闭的4次挥手(可以通过任意一端发起)
    1. 客户端:分了吧
    2. 服务器端:好的
    3. 服务器端:确定分了哈?
    4. 客户端:分吧(客户端需要有个time-wait冷却时间,其中包含两个MSL,才能真正切断连接释放端口)

4.Netty优化

  • EventLoop是单线程的不要阻塞,如果确实有耗时较高的处理,则新起一个线程进行处理。
  • 系统参数优化

ulimit -a:查看当前资源描述符的使用上限
TcpTimedWaitDelay:Windows注册表里,修改连接关闭时客户端的time-wait冷却时间
/proc/sys/net/ipv4/tcp_fin_timeout:Linux文件,修改连接关闭时客户端的time-wait冷却时间

  • 缓冲区优化:绑定到Bootstrap上的参数

SO_RCVBUF
SO_SNDBUF
SO_BACKLOG:握手中的半连接状态数量设置
REUSEXXX:复用挥手中的time-wait状态中的连接,重新唤醒连接

  • 心跳周期优化
  • 内存与ByteBuffer优化:可以选择使用哪种内存

DirectBuffer:系统直接内存
HeapBuffer:堆内存

  • 其他

ioRatio:处理IO功能和业务功能所消耗的CPU资源比率,默认是1:1
Watermark:水位线判断,针对IO压力大小,做一些策略处理。
TrafficShaping:流量控制整形,请求数据队列,控制瞬时流量,类似于MQ。