netty面试题1

Netty解决Selector空轮询BUG的策略

selector

若Selector的轮询结果为空,也没有wakeup或新消息处理,则发生空轮询,CPU使用率100%。

注意:是CPU 100%,非常严重的bug。

这个臭名昭著的epoll bug,是 JDK NIO的BUG,官方声称在JDK1.6版本的update18修复了该问题,但是直到JDK1.7、JDK1.8版本该问题仍旧存在,只不过该BUG发生概率降低了一些而已,它并没有被根本解决。该BUG以及与该BUG相关的问题单可以参见以下链接内容:
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=2147719

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6403933

Netty解决空轮询的步骤

  • 对Selector的select操作周期进行统计,每完成一次空的select操作进行一次计数,若在某个周期内连续发生N次空轮询,则触发了epoll死循环bug。
  • 2、重建Selector,判断是否是其他线程发起的重建请求,若不是则将原SocketChannel从旧的Selector上去除注册,重新注册到新的Selector上,并将原来的Selector关闭。

Netty解决轮询的4个步骤

第一部分定时阻塞select

  • 先定义当前的时间currentTimeNanos
  • 接着计算出一个执行最少需要的时间timemillis
  • 定时阻塞select(timeMilins)
  • 每次对selectCnt++操作

第二部分:有效IO处理事件

第三部分:超时逻辑处理

  • 如果查询超时,则seletCnt重置为1。

第四部:解决空轮询BUG

  • 一旦到达SELECTOR_AUTO_REBUILD_THRESHOLD这个阀值,就需要重建selector来解决这个问题。
  • 这个阀值默认是512。
  • 重建selector,重新注册channel通道

netty是什么

Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端

Netty是基于nio的,让我们使用起来更加灵活

JDK原生NIO程序有什么问题

JDK原生也有一套网络应用程序的API,但是存在一系列问题如下

  • Nio的类库和API繁杂,需要熟练掌握Selector,ServerSocketChannel,ButeBuffer等
  • 需要具备其他额外技能做铺垫,要熟悉java多线程,因为NIO编程涉及到Reactor模式,你必须对多线程和网络编程十分熟悉,才能写出高质量NIO程序
  • 可靠性差,开发和工作量都非凡的航大,例如客户端面临重连,网络闪断,半包读写,失败缓存,网络拥塞和异常码流的处理等
  • JDK NIO的BUG,例如臭名昭著的select bug,它会导致Selector空轮询,最终导致CPU 100%。

Netty 的优势有哪些?

使用简单:封装了 NIO 的很多细节,使用更简单。
功能强大:预置了多种编解码功能,支持多种主流协议。
定制能力强:可以通过 ChannelHandler 对通信框架进行灵活地扩展。
性能高:通过与其他业界主流的 NIO 框架对比,Netty 的综合性能最优。
稳定:Netty 修复了已经发现的所有 NIO 的 bug,让开发人员可以专注于业务本身。
社区活跃:Netty 是活跃的开源项目,版本迭代周期短,bug 修复速度快。

Netty 的应用场景有哪些?

典型的应用有:

阿里分布式服务框架 Dubbo,默认使用 Netty 作为基础通信组件,

还有 RocketMQ 也是使用 Netty 作为通讯的基础。

Netty常见的使用场景如下

互联网行业 在分布式系统中,各个节点之间需要远程服务调用,高性能的RPC框架必不可少,Netty作为异步高新能的通信框架,往往作为基础通信组件被这些RPC框架使用。 典型的应用有:阿里分布式服务框架Dubbo的RPC框架使用Dubbo协议进行节点间通信,Dubbo协议默认使用Netty作为基础通信组件,用于实现各进程节点之间的内部通信。
游戏行业 无论是手游服务端还是大型的网络游戏,Java语言得到了越来越广泛的应用。Netty作为高性能的基础通信组件,它本身提供了TCP/UDP和HTTP协议栈。 非常方便定制和开发私有协议栈,账号登录服务器,地图服务器之间可以方便的通过Netty进行高性能的通信
大数据领域 经典的Hadoop的高性能通信和序列化组件Avro的RPC框架,默认采用Netty进行跨界点通信,它的Netty Service基于Netty框架二次封装实现

netty的特点

Netty的对JDK自带的NIO的API进行封装,解决上述问题,主要特点有:

设计优雅 适用于各种传输类型的统一API - 阻塞和非阻塞Socket 基于灵活且可扩展的事件模型,可以清晰地分离关注点 高度可定制的线程模型 - 单线程,一个或多个线程池 真正的无连接数据报套接字支持(自3.1起)

高性能 、高吞吐、低延迟、低消耗

最小化不必要的内存复制

安全 完整的SSL / TLS和StartTLS支持

高并发:Netty 是一款基于 NIO(Nonblocking IO,非阻塞IO)开发的网络通信框架,对比于 BIO(Blocking I/O,阻塞IO),他的并发性能得到了很大提高。

传输快:Netty 的传输依赖于零拷贝特性,尽量减少不必要的内存拷贝,实现了更高效率的传输。

封装好:Netty 封装了 NIO 操作的很多细节,提供了易于使用调用接口。

社区活跃,不断更新 社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会被加入

使用方便 详细记录的Javadoc,用户指南和示例 没有其他依赖项,JDK 5(Netty 3.x)或6(Netty 4.x)就足够了

转载自Netty面试题(史上最全)_40岁资深老架构师尼恩的博客-CSDN博客_netty面试题

Last modification:December 28, 2022
如果觉得我的文章对你有用,请随意赞赏