Netty4笔记

 

目录

一,Netty重要组件:

1:eventloop

(事件循环,工人)(默认内部eventloop个数是cpu线程数*2)执行任务,io事件

2:eventloopgroup(事件循环组)

3:channel(通道)

4:pipeline(管道,工序)

5:handler(每道工序)

6:Bytebuf(区别于nio的Bytebuffer)

二,netty的优点:

(1):reactor线程模型支持高并发,海量连接。

(2):异步事件驱动,提高性能。

(3):自带编解码器解决Tcp拆包粘包问题。

(4):串行化处理读写。

(5):内存零拷贝 :

三 ,netty的io模型vs BIO:

 四 ,netty的线程模型:

4.1 reactor单线程模型

 

4.2 reactor多线程模型

4.3 主从reactor多线程模型

 五 ,面试常见问题:

0:为什么不用AIO而是NIO?

1:为什么netty使用异步处理读写事件?

2:netty3和netty4的区别?答:

2:netty的ByteBuf和nio的ByteBuffer的区别:


一,Netty重要组件:

1:eventloop

(事件循环,工人)(默认内部eventloop个数是cpu线程数*2)执行任务,io事件

2:eventloopgroup(事件循环组)

3:channel(通道)

4:pipeline(管道,工序)

5:handler(每道工序)

6:Bytebuf(区别于nio的Bytebuffer)

Netty4的ByteBuf分为池化的和非池化的,池化的优点包含如下两点:

  1. 对于DirectByteBuffer的分配和释放是比较低效的,使用池化技术能快速分配内存。
  2. 池化技术使对象可以复用,从而降低gc频率。
  3. 默认是开启的池化。
  4. Bytebuf:可以选择直接内存或者堆内存,直接内存分配效率低但是读写效率高,减少了一次拷贝,因为从系统内存缓冲区到Java内存中。堆内存 分配效率高但是读写效率低 因为频繁gc 会导致数据复制 搬迁。因此 直接内存适合和池化搭配使用。(Netty4.X提供了基于内存池的缓冲区重用机制。性能测试表明,采用内存池的ByteBuf相比于朝生夕灭的ByteBuf,性能高23倍左右(性能数据与使用场景强相关)。)
  5. 垃圾回收 :引用计数 release 减一 retain加一

注:同一个客户端channel和同一个eventloop绑定,但是如果handler耗时 可以交给DefaultEventloopGroup内的eventloop线程去处理

二,netty的优点:

(1):reactor线程模型支持高并发,海量连接。

(2):异步事件驱动,提高性能。

(3):自带编解码器解决Tcp拆包粘包问题。

(4):串行化处理读写。

(串行化处理读写 :避免使用锁带来的性能开销。即消息的处理尽可能再同一个线程内完成,期间不进行线程切换,这样就避免了多线程竞争和同步锁。表面上看,串行化设计似乎CPU利用率不高,并发程度不够。但是,通过调整NIO线程池的线程参数,可以同时启动多个串行化的线程并行运行,这种局部无锁化的串行线程设计相比一个队里-多个工作线程模型性能更优。)

(5):内存零拷贝 :

尽量减少不必要的内存拷贝,实现了更高效率的传输。

(Netty的接收和发送ByteBuffer采用DIRECT BUFFERS,使用堆外直接内存进行Socket读写,不需要进行字节缓冲区的二次拷贝。如果使用传统的堆内存(HEAP BUFFERS)进行Socket读写,JVM会将堆内存Buffer拷贝一份到直接内存中,然后才写入Socket中。相比于堆外直接内存,消息在发送过程中多了一次缓冲区的内存拷贝。)

三 ,netty的io模型vs BIO:


 四 ,netty的线程模型:

 
netty线程模型主要是基于reactor实现。
基于reactor可以实现3种线程模型:reactor单线程模型,reactor多线程模型、主从reactor多线程模型
在使用时主要是靠NioEventLoopGroup来实现上诉的3种线程模型

一般使用netty实现服务端时,一般会初始化两个线程组:
bossEventLoopGroup:监听接受客户端连接
workEventLoopGroup:负责具体的IO事件,交由handler处理

 

4.1 reactor单线程模型


一个线程需要处理所有的accept、recieve、decode、procces、encode、send事件。对于高负载、高并发、并且性能要求比较高的系统并不适用

 

4.2 reactor多线程模型


主线程仍然负责accept、recieve、send等事件,将业务的处理派由一个线程池去处理。高并发时也会出现性能瓶颈

4.3 主从reactor多线程模型


主reactor线程监听accept事件,并派发给从reactor线程,从reactor负责监听IO的recieve、send事件,并且将监听到的事件交由从reactor线程池处理业务

 五 ,面试常见问题:

0:为什么不用AIO而是NIO?

  1. Netty不看重Windows上的使用,在Linux系统上,AIO的底层实现仍使用EPOLL,没有很好实现AIO,因此在性能上没有明显的优势,而且被JDK封装了一层不容易深度优化。
  2. Linux上AIO不够成熟,处理回调结果速度跟不上处理需求,比如外卖员太少(reactor),顾客太多(请求),供不应求,造成处理速度有瓶颈(待验证)。

1:为什么netty使用异步处理读写事件?

答:通过服务器的吞吐量,而不是多线程就一定效率高!

2:netty3和netty4的区别?答:

(1)我们知道当系统在运行过程中,如果频繁的进行线程上下文切换,会带来额外的性能损耗。多线程并发执行某个业务流程,业务开发者还需要时刻对线程安全保持警惕,哪些数据可能会被并发修改,如何保护?这不仅降低了开发效率,也会带来额外的性能损耗。为了解决上述问题,Netty 4采用了串行化设计理念,从消息的读取、编码以及后续Handler的执行,始终都由I/O线程NioEventLoop负责,这就意外着整个流程不会进行线程上下文的切换,数据也不会面临被并发修改的风险,对于用户而言,甚至不需要了解Netty的线程细节,这确实是个非常好的设计理念,

(2)随着JVM虚拟机和JIT即时编译技术的发展,对象的分配和回收是个非常轻量级的工作。但是对于缓冲区Buffer,情况却稍有不同,特别是对于堆外直接内存的分配和回收,是一件耗时的操作。为了尽量重用缓冲区,Netty4.X提供了基于内存池的缓冲区重用机制。性能测试表明,采用内存池的ByteBuf相比于朝生夕灭的ByteBuf,性能高23倍左右。

2:netty的ByteBuf和nio的ByteBuffer的区别:

ByteBuf容量可以自动扩容的(当数据大小大于初始容量(256)大小 就会自动扩容(翻倍))而ByteBuffer不能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值