目录
一、为什么Netty能保证高并发下的高性能
- 1、Netty采用了主从Reactor线程模型
- 2、采用了NIO多路复用非阻塞的通信模式
- 3、采用了无锁串行化的设计思想
- 4、支持高性能的序列化协议,如kryo、Protobuf等
- 5、零拷贝(直接内存的使用)
- 6、ByteBuf内存池设计
- 7、灵活的TCP参数配置能力
- 8、并发优化
二、什么是主从Reactor线程模型
主从即拥有两个线程池,一主一从。主线程池专门处理连接、从线程池专门处理读写。Reactor为响应式编程模型,就是当一个事件发生了后会马上被检测到并安排线程去处理。两者合并起来就是会有多个线程池处理不同的业务事件,每个业务事件发生的时候会唤醒对应的线程去处理,从而达到线程高可用的目标。
三、什么是零拷贝?
零拷贝并不是不拷贝,而是类似这一类减少了拷贝次数的设计方案都称为零拷贝。
一般来说完成一次数据交互需要经历四次拷贝:缓冲区到内核空间(直接内存)、内核空间(直接内存)到用户空间(JVM堆内存)、用户空间(JVM堆内存)到内核空间(直接内存)、内核空间(直接内存)到缓冲区。Netty对这四次拷贝做了优化,所有的数据存储都是在内核空间进行的,从而减少了拷贝次数,提升的效率。
四、Netty是如何解决JDK中Selector BUG的?
首先解释一下JDK中的Selector会有什么样的BUG
一版情况下JDK中的Selector只会监测四种类型的事件:连接、接收连接、读、写。Selector被唤醒后会尝试获取这四类事件。但是有一些特殊情况下,Selector被唤醒了,但是事件区域却没有这四类事件,这就导致了Selector不停的尝试获取对应事件,造成空转。使得CUP的使用率不断升高,最终可能导致服务器崩溃。
然后说一下Netty的解决方案
Netty主要是通过对Selector尝试读取事件的次数进行限制,当到达一定次数后会关闭当前Selector并新建一个包含有相同信息的未被唤醒的Selector来替换之前的Selector。以此来解决空轮训的问题。
五、如何让单机下基于Netty的应用程序支持几十万甚至百万的长链接?
首先声明一点,该台机器的硬件配置(至少8核16G)一定要能支持百万级的长链接,如果硬件配置不行,该种需求根本不可能实现。
- 1、操作系统需要做变更
Linux中的一切皆文件,而操作系统对一个用户下面能打开的文件数是有限定的(通过ulimit -n
可查看),也就是说Selector这个文件被打开的个数是有一个上限的,一般默认值是65535个。所以如果需要支持百万连接,即可以打开百万文件,那么就需要对这个数值进行调整,将它调整至百万级别。
相关的参数还有:linux系统限制的最大打开文件数量(通过cat /proc/sys/fs/file-max
可以查看)- 2、Netty应用程序需要做相关的调优
调整NIO线程组的核心线程数量
心跳逻辑优化(尽可能的关闭无效连接、设置合理的心跳周期)
设置合理的接收缓存和发送缓存大小
IO线程和业务线程分离
做相对应的流控- 3、JVM调优
六、什么是水平触发(LT)和边缘触发(ET)?
只要接收缓存中有数据就会一直的触发读事件,这就是水平触发;
边缘触发是接收缓存从外部获取到数据后才会触发一次,哪怕缓存中还有数据没有读完它也不会再次触发读事件,只有当下一次从外部获取到新的数据后才会再次触发;
七、请说说浏览器中输入URL到返回页面的全过程
- 1、根据域名,进行DNS的域名解析;
- 2、拿到解析的IP地址,建立TCP连接;
- 3、向IP地址,发送http请求;
- 4、服务器处理请求;
- 5、返回响应结果;
- 6、关闭TCP连接;
- 7、浏览器解析HTML;
- 8、浏览器布局渲染;
八、请说说DNS域名解析的全过程
DNS服务器有三种:根DNS服务器、顶级域DNS服务器、权威DNS服务器。DNS域名解析的过程是先从根DNS服务器拿到当前地址的顶级域DNS服务器地址,然后再从顶级域DNS服务器获取到权威DNS服务器的地址,最后再从权威DNS服务器获取到该域名所对应的真正的IP地址
顶级域:.com、.cn、.gov以这种命名结尾的域名