收集几十位大厂面试者的面试题及见解-Netty模块

1 简述BIO、NIO和AIO。

BIO:客户端并发数和后端的线程数是一比一,线程的创建和销毁很消耗系统资源。并发量大,服务器性能下降,会出现栈和堆溢出错误。当前线程创建连接后,如果没有操作进入阻塞操作,浪费服务器资源。
NIO:通过多路复用器一个线程处理多个通道,避免多线程之间的上下文切换导致系统开销过大。并且通道中有了事件,才能进行读写操作。减少系统开销。
AIO:异步IO,用户线程通过系统调用,告知内核启动某个IO操作(数据准备、数据复制),完成后通知用户程序,执行后续的操作。但是依赖操作系统底层,而且linux系统支持不完善。

2 为什么使用Netty进行项目开发?

  1. Netty是基于NIO实现的,实现了阻塞和非阻塞Socket。而且对各种协议API进行统一封装,简化开发。
  2. Netty只依赖JDK底层api,不需要引入额外依赖。
  3. 社区活跃,发现bug可以快速修复。
  4. 高度可定制线程模型,单线程、一个或多个线程池。
  5. 网络通信更加高性能、低延迟、尽可能的减少不必要的内存拷贝。
  6. NIO可能会导致Selector空轮询问题,官网JDK1.6修复该问题,只是概率低点。

3 什么是Reactor线程模型?

不是Java和Netty专有的,是一种并发编程模型,是一种思想。
Reactor有三种角色,Reactor负责监听和分配事件。Acceptor处理客户端新连接,并分派请求到处理链中。Handler将自身和事件绑定,执行读写操作。
Reactor线程模型有三种,单线程、多线程、主从多线程。

4 介绍下单线程、多线程、主从多线程模型。

单线程:
Reactor充当多路复⽤器⻆⾊,监听多路连接的请求,由单线程完成 。Reactor收到客户端发来的请求时,如果是新建连接通过Acceptor完成,其他的请求由Handler完成(读写操作)。
试用一些简单业务逻辑和并发量不高的地方。没有线程之间切换和线程之间通信问题。但是Reactor负担过重,导致系统性能下降,如果当前线程进入死循环,整个系统不可用。
多线程:
和单线程之间区别是,Handler只负责响应用户请求,真正读写操作在其他线程完成。降低Reactor的性能开销,充分利⽤CPU资源,从⽽更专注的做事件分发⼯作。提升整 个应⽤的吞吐。
多线程数据共享和访问⽐较复杂。如果⼦线程完成业务处理后,把结果传递给主线程Reactor进⾏ 发送,就会涉及共享数据的互斥和保护机制。 Reactor承担所有事件的监听和响应,只在主线程中运⾏,可能会存在性能问题。例如并发百万客户端连接,或者服务端需要对客户端握⼿进⾏安全认证,但是认证本身⾮常损耗性能。
主从多线程模型:
MainReactor负责监听server socket,处理⽹络IO连接建⽴,将建⽴的socketChannel指 定注册给SubReactor。
SubReactor主要完成和建⽴起来的socket的数据交互和事件业务处理操作。
响应快,不必为单个同步事件所阻塞,虽然Reactor本身依然是同步的。 可扩展性强,可以⽅便地通过增加SubReactor实例个数来充分利⽤CPU资源。 可复⽤性⾼,Reactor模型本身与具体事件处理逻辑⽆关,具有很⾼的复⽤性。

总结:在netty中多Reactor三种模型都有很好的支持,一般情况下,服务端采用主从架构模型。

5 IO模型:阻塞IO模型、非阻塞IO模型、select、epoll线程模型。

阻塞IO模型
创建socket,fd绑定监听,调用系统的accept()函数等待系统内核响应,如果内核没有接受连接,一直阻塞中,接受客户端数据函数也是阻塞中,发送信息也是等待客户端信息发送。
非阻塞IO模型
调用系统的连接函数、接受客户端数据函数、发送数据函数都变成异步了,不用等待内核响应,直接执行下一步。应用程序要得到响应不断的轮询调用。
select、epoll线程模型
redis模块中已总结过,https://www.jianshu.com/p/fe6d9f7d9e9b

6 Netty中的核心组件

ChannerHandler、Channel、EventLoop、EventLoopGroup、ChannelPipeline、Bootstrap、Future
Channel:每个客户端连接都会创建一个Channel,它负责基本的IO操作。
EventLoop:用于监控和协调事件,每个EventLoop会占用一个Thread,当前线程处理发生在EventLoop上所有IO操作。
EventLoopGroup:用于生成EventLoop。服务端需要两个,客户端需要一个。因为服务端需要建立连接和业务处理。
ChannelHandler:对于数据的⼊站和出站的业务逻辑的编写都是在ChannelHandler中完成的。
ChannelPipeline:channel进行数据传递时候,需要进行编码和节码等一系列操作操作。ChannelPipeline是对ChannelHandler管理。
Bootstrap:将各个组件串起来,并绑定端口,启动服务。
Future:了⼀种在操作完成时通知应⽤程序。

7 Netty零拷贝解释下?

Bytebuf 使⽤的是⽤池化的Direct Buffer类型使⽤的堆外内存,不需要进⾏字节缓冲区的⼆次拷 ⻉,如果使⽤堆内存,JVM会先拷⻉到堆内,再写⼊Socket,就多了⼀次拷⻉。 CompositeByteBuf将多个ByteBuf封装成⼀个ByteBuf,在添加ByteBuf时不需要进程拷⻉。 Netty的⽂件传输类DefaultFileRegion的transferTo⽅法将⽂件发送到⽬标channel中,不需要进 ⾏循环拷⻉,提升了性能。

8 ByteBuf 释放问题

手动释放:ReferenceCountUtil.release(byteBuf); 进⾏释放。

自动释放:
HeadHandler出站自动释放。
⼊站的TailHandler,TailHandler放在最后面,每个处理器将消息下穿。
继承SimpleChannelInboundHandler自动释放。

9 知道哪些编解码器?

在netty开发中定义编解码器需要实现ByteToMessageDecoder、MessageToByteEncoder。

对象编解码器:JDk自带的编解码器、Hessian编解码器。
基于Redis协议的编解码器。字符串编解码器。

10 Netty 拆包粘包的实质?TCP通信的粘包和拆包怎么处理?

在Netty的应用层,按照 ByteBuf 为单位来发送/读取数据,但是到了底层操作系统仍然是按照字节流发送数据。因此,从底层到应用层,需要进行二次拼装。操作系统底层,是按照字节流的方式读入,到了 Netty 应用层面,需要二次拼装成 ByteBuf。在Netty 层面,拼装成ByteBuf时,就是对底层TCP缓冲的读取,这里就有问题了。上层应用层每次读取底层缓冲的数据容量是有限制的,当TCP底层缓冲数据包比较大时,将被分成多次读取,造成断包,在应用层来说,就是半包。其次,如果上层应用层一次读到多个底层缓冲数据包,就是粘包。

在发送消息包时候,在头部加上两个字节,存储发送数据字节长度。在bytebuf获取数据时候,先读取两个字节,即字节长度len1,然后从bytebuf中读取len1长度的字节。

11 Netty服务启动流程?

创建服务端channel,


在这里插入图片描述
在这里插入图片描述

初始化服务端channel,


image

注册selector,
在这里插入图片描述

绑定端口。


在这里插入图片描述

在这里插入图片描述

12 连接过程刨析?

新连接接入:


在这里插入图片描述

在这里插入图片描述

注册读事件


在这里插入图片描述

在这里插入图片描述

13 使用Netty如何优化?

2. 使⽤EventLoop的任务调度
直接放⼊channel所对应的EventLoop的执⾏队列,⽽直接使⽤channel.writeAndFlush(data),会导致线程的切换。
3. 减少ChannelPipline的调⽤长度
ctx.channel().writeAndFlush(msg); ,所有的handler都会执行一遍。ctx.writeAndFlush(msg),从当前的handler一直执行到pipline尾部。
4. 减少ChannelHandler的创建
如果channelhandler是⽆状态的(即不需要保存任何状态参数),那么使⽤Sharable注解,并在 bootstrap时只创建⼀个实例,减少GC。否则每次连接都会new出handler对象。
5. ⼀些配置参数的设置
bossGroup只是需要配置一个,因为ServerSocketChannel只会注册到一个eventLoop上,⽽这个eventLoop只会有⼀个线程在运⾏。workGroup集器核数两倍,即发挥虚拟机内核优势,又防止线程上下文切换开销。
响应时间有⾼要求的场景,禁⽤nagle算法,不等待,⽴即发送。

14 我说Netty不是真正的“异步IO”,你认同吗?

认同。因为使用的IO模型是采用epoll,应用端不断循环调用epoll对象的消息队列,当消息队列中有事件消息,然后应用端对事件消息一个个处理。所以是同步操作。但是由于也是一个线程处理多个客户端的读写操作,类似异步感觉。

15 Netty的IO模型,Reactor模式,Handler线程一定要新起一个线程来进行数据库操作吗?

不一定,因为handler进行业务操作是在workeGroup线程池操作,这个线程池线程数是内核的两倍。所以Handler进行业务操作,如果线程数没有达到核心线程数,则会创建一个新的线程执行。如果达到了核心线程数,则会使用之前的线程执行。

16 Netty 中责任链?

就是ChannelPipeline,用来将每一个handler串成链表,然后进行管理。保证了进行消息传递时候,执行handler顺序。

17 长连接和短链接描述下。

TCP在进行读写前,需要server和client建立连接。建立连接的过程就是三次握手四次挥手。消耗网络资源和有事件延迟。
短链接:就是客户端和服务端读写完毕后,释放连接。再次读取,需要从新建立连接。
长连接:每次读写之后,连接不断开。后续读写依旧使用这个连接。

18 Netty的长连接/心跳机制有了解?

在TCP保持长连接时候,由于网络原理或者其他异常。client和server没有交互,无法发现对方掉线。引入心跳机制。
心跳机制原理,在client和server在一定时间内没有数据交互,服务端或者客户端发送一个特殊数据包给对象,对方立刻回应,代表连接中。
TCP实际上自带长连接选项,本身就有心跳包机制。但是TCP协议层面长连接灵活性不够,所以一般是在应用层自定义心跳机制,在netty中实现,则是通过IdleStateHandler核心类实现。

19 一个请求进入netty具体用了哪些类?

如果是一个连接请求,首先是被EventLoopGroup产生的EventLoop监控到是连接事件,然后由Acceptor进行连接创建。
如果是一个读/写请求,被工作的EventLoopGroup产生EventLoop监控到,然后进入Channel,进行执行链ChannelPipeline,执行每一个ChannelHandler。

20 Netty怎么处理http请求,tcp和http区别,http和https区别,怎么加密,每次都需要这样吗?

21 netty怎么解决IO阻塞在业务代码上?

22 在项目中有没有作过限流?

23 Netty guice?

24 Netty线程池中的线程建立连接之后,这条连接是不是始终属于这个请求,对于Netty来说是不是只占用服务端的一个套接字,了解zero copy嘛?

25 Netty 的实现(nio 实现)?

26 ProtoBuf?

27 Netty主流程源码描述一下 和NIO有什么区别?

28 Netty异步编程怎么做的?

29 项目里用到channle重用,是怎么实现?

30 Java Reactor在执行阻塞I/O时该怎么操作?

31 Netty的容错性?

32 Netty在不同操作系统上有何不同?

33 NIO是怎么调度的?

34 Netty的I/O线程堵住了会怎么样?怎么解决?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容