Java面试(3)之 netty篇

Netty原理

1, netty实现原理?

NIO模型(同步非阻塞),主要由eventLoopGroup、channel、channelPipeline 三大类组成.

eventLoopGroup主要有两个,一个用来接收请求的线程组,一个是用来处理IO操作的线程组;前者接收到请求后将请求注册到selector上,每个selector对应多个channel管道,另一个线程组通过轮训selector的select来处理channel上的任务,channelpipeline通过handler来监听回调返回处理结果.

多路复用: 是一种同步IO模型,实现一个线程可以监视多个文件句柄,一旦某个文件句柄就绪,就能够通知应用程序进行相应读写操作;没有文件句柄就绪时就阻塞应用,交出CPU;多路是指网络连接,复用的是一个线程.

实现多路复用的三种方式: select、poll、epoll

b01f30006abe41c5921e2a9b712661fe.png

redis、nginx采用的就是epoll模型(IO模型)

2, netty的粘包和拆包问题

首先netty采用的是TCP协议进行数据传输的

什么是粘包?

一般情况下TCP发送的数据是一个没有界限的长串的二进制数据,在发送数据之前会先将数据存在缓存区;如果缓存区没满,就继续存数据,然后一起发送出去,这个过程就是粘包.

什么是拆包?

如果一条数据存在缓存区不足了,那就需要将数据拆分成多条数据存到缓存区发送,这个过程叫拆包.

为什么数据要先存到缓存区而不直接发送到服务端?

这个是TCP协议决定的,客户端发送数据必须要先到缓存区,然后等缓存区满了才统一发送数据.

如何解决粘包、拆包问题?

1, 发送的消息定个长度: 指定每次发送数据的字节长度大小,如果不够就用空格补齐

2, 特殊符号分割: 解析消息使用特殊符号来分割每次发送的消息,发送方的消息不能有这个特殊符号.

3, 发送长度: 将每次发送消息的长度放到消息头里面,服务端根据消息头的长度来解析消息.

netty包编码器、包解码器

3, netty零拷贝实现原理

1, 避免数据流经用户空间,即 A、B两个设备进行数据传输时,从A的内核空间读缓冲区直接到B的内核空间写缓冲区,不再经过A的用户空间缓冲区. netty实现的类是FileRegion类的transferTo()方法

2, 避免数据从JVM heap到C Heap的拷贝, 即在JVM层面,程序执行一个IO操作都需要先从JVM管理的堆内存复制到使用C malloc()或类似函数分配的Heap内存(堆外内存)才能触发系统调用,而netty省去了JVM堆内存到堆外内存的复制过程

3, 减少数据在用户空间的多次拷贝,即netty的CompositeByteBuf类实现了对多个相同byteBuffer会生成一个视图,避免数据多次复制开辟多个内存空间

参照: Netty对零拷贝(Zero Copy)三个层次的实现 - 知乎

------------------------------------------------------------------------------------------------------

零拷贝的原理

1, 零拷贝的原理

背景: 以前数据从磁盘到应用程序的大概流程如下

d5487622ecc049b3b36660b61e2b0496.png

零拷贝出现的原因:

如果应用程序不对数据做修改,从内核缓冲区到用户缓冲区,再从用户缓冲区到内核缓冲区。两次数据拷贝都需要CPU的参与,并且涉及用户态与内核态的多次切换,加重了CPU负担。

3015842b7a964f4399e77bf43f8c6c8a.png

mmap+write: 适合大文件传输,小文件传输容易产生碎片

172f6d60a95842cdbff664647f6f0192.png

sendfile: 相对mmap有一些优化,但内核缓冲区与socket缓冲区仍然存在一次CPU拷贝

0646f17a03984872bd65bb25a281bbf0.png

sendfile+DMA: 去掉了CPU拷贝,但无法对数据进行修改,并且需要硬件DMA支持,有一定局限性

f33602d0806542349cf5d0e890b39df3.png

splice: 不需要硬件支持,通过管道建立内核缓冲与socket缓冲的连接,局限在于必须要有管道

9a132c2c5bc34529852e0f33882dd8c7.png

 

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loren_云淡风轻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值