netty的面试题

1,netty 是什么?

     netty是一款基于NIO(非阻塞IO)的通信框架,对于BIO(阻塞IO)来说,很大的提高了其并发性。极大的简化并优化了tcp和udp套接字服务器等网络编程,并且性能和安全性更好,支持多种协议,如ftp,smtp,http等

     BIO可参考java jdk中的 ServerSocket的写法,在读取字节流时,没有可用于前后移动的索引,只是一个连续的数据流,每次客户端请求链接到服务器,它都会阻塞一个线程,如果需要很多同时链接,就需要一个线程池。

     NIO是基于套接字连接的非阻塞API,也就意味着对可用线程的数量并不紧密,使用它,一个线程可以同时处理多个连接。比如netty的channel。

2,netty的特点是什么?为什么要用netty?

  • 高并发:比java api有更好的吞吐量,较低的延时,减少内存拷贝,资源耗时更少(这个得益于共享池和重用)
  • 传输快: Netty 的传输依赖于零拷贝特性,尽量减少不必要的内存拷贝,实现了更高效率的传输。
  • 易用性:设置了多种编解码功能,支持多种主流协议。扩展性强,而且稳定。

   netty比jdk自带的NIO相关的API更加易用。

  • 简单而强大的线程模型
  • 自带编解码解决TCP粘包/拆包问题
  • 自带各种协议栈
  • 真正的无连接数据包套接字支持
  • 比直接使用jdk的api有更高的吞吐量,更低的延时,更低的资源和更少的内存复制
  • 安全性强,有完整的SSL/TLS以及StartTLS支持
  • 成熟稳定,现在很多开源项目使用了netty,比如dubbo和es等

3,什么是netty的零拷贝?

     netty的接受和发送byteBuffer 采用 direct buffers,使用堆外直接内存进行Socket读写,不需要进行字节缓冲区的二次拷贝,如果使用传统的堆内存进行socket读写,jvm会将堆内存buffer拷贝一份到直接内存中,然后才写入socket中,相对于堆外直接内存,消息在发送过程中多了一次缓存区的内存拷贝。

     netty提供了组合Buffer对象,可以聚合多个byteBuffer对象,用户可以像操作一个Buffer那样方便的对组合Buffer进行操作,避免了传统通过内存拷贝的方式将几个buffer合并成一个大的buffer。

     netty的文件传输采用了transferTo方法,它可以直接将文件的缓冲区的数据发送到目标Channel,避免了传统通过循环write的方法导致的内存拷贝问题。

4,netty的使用场景?

     dubbo框架就是基于netty的通信组件,还有ElasticSearch 也是。由Transport负责通信,基于tcp通信采用netty实现。RocketMQ,gRPC 等

     作为RPC框架的网络通信工具:我们在分布式系统中,不通服务节点之间经常需要相互调用,这个时候就需要RPC框架了,就可以用netty实现,比如我调用另外一个节点的方法的化,至少需要让对方知道我调用的是哪个类中的哪个方法以及相关参数

     实现一个即时通讯系统: 类似与微信

     实现消息推送系统:

5,netty高性能的具体表现?

  • 同步非阻塞IO,
  • 内存零拷贝,
  • 内存池设计,申请的内存可以重用,主要指直接内存,内部实现是一颗二叉树找树管理内存分配情况,
  • 串形化处理读写:避免使用锁带来的性能开销
  • 高性能序列化协议: 支持protobuf等高性能序列化协议。

6,netty和tomcat的区别?

  • 作用不同:tomcat是Servlet容器,可以视为web服务器,而netty是异步事件驱动的网络应用程序框架和工具用于简化网络编程。
  • 协议不同:tomcat是基于http协议的web服务器,而netty是通过编程自定义各种协议,因为netty本身自己能编码/解码字节流,所有netty可以实现,http服务,ftp服务,udp服务,rpc服务,websocket服务,redis的proxy服务,mysql的proxy服务等

7,netty中有哪些重要的组件?

  • Channel:netty网络操作抽象类。它包括了基本的 I/O 操作,如 bind、connect、read、write 等。比较常用的Channel接口实现类是NioServerSocketChannel(服务端)和NioSocketChannel(客户端),这两个 Channel 可以和 BIO 编程模型中的ServerSocket以及Socket两个概念对应上。NettyChannel 接口所提供的 API,大大地降低了直接使用 Socket 类的复杂性。
  • EventLoop:主要是配合 Channel 处理 I/O 操作,用来处理连接的生命周期中所发生的事情。主要作用实际就是负责监听网络事件并调用事件处理器进行相关 I/O 操作的处理。Channel 为 Netty 网络操作(读写等操作)抽象类,EventLoop 负责处理注册到其上的Channel 处理 I/O 操作,两者配合参与 I/O 操作。
  • ChannelFuture:Netty 框架中所有的 I/O 操作都为异步的,因此我们需要 ChannelFuture 的 addListener()注册一个 ChannelFutureListener 监听事件,当操作执行成功或者失败时,监听就会自动触发返回结果。
  • ChannelHandler:充当了所有处理入站和出站数据的逻辑容器。ChannelHandler 主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等。
  • ChannelPipeline:为 ChannelHandler 链提供了容器,当 channel 创建时,就会被自动分配到它专属的 ChannelPipeline,这个关联是永久性的。

8,Netty 发送消息有几种方式?

  • 直接写入 Channel 中,消息从 ChannelPipeline 当中尾部开始移动;
  • 写入和 ChannelHandler 绑定的 ChannelHandlerContext 中,消息从 ChannelPipeline 中的下一个 ChannelHandler 中移动。

9,默认情况 Netty 起多少线程?何时启动?

  Netty 默认是 CPU 处理器数的两倍,

// 从1,系统属性,CPU核心数*2 这三个值中取出一个最大的 //可以得出 DEFAULT_EVENT_LOOP_THREADS 的值为CPU核心数*2

private static final int DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));

bind 完之后启动。
channelFuture = serverBootstrap.bind(PORT).sync()

10,什么是TCP粘包/拆包?有什么解决方法?

     TCP粘包/拆包是基于TCP发送数据的时候,出现了多个字符串“粘”在了一起或者一个字符串被“拆”开的问题,

      解决方案:

  • 使用netty自带的解码器:
    • LineBasedFrameDecoder : 发送端发送数据包的时候,每个数据包之间以换行符作为分隔,LineBasedFrameDecoder 的工作原理是它依次遍历 ByteBuf 中的可读字节,判断是否有换行符,然后进行相应的截取。
    • DelimiterBasedFrameDecoder : 可以自定义分隔符解码器,LineBasedFrameDecoder 实际上是一种特殊的 DelimiterBasedFrameDecoder 解码器。
    • FixedLengthFrameDecoder: 固定长度解码器,它能够按照指定的长度对消息进行相应的拆包。
    • LengthFieldBasedFrameDecoder
  • 自定义序列化编解码器:

       在 Java 中自带的有实现 Serializable 接口来实现序列化,但由于它性能、安全性等原因一般情况下是不会被使用到的。

       通常情况下,我们使用 Protostuff、Hessian2、json 序列方式比较多,另外还有一些序列化性能非常好的序列化方式也是很好的选择:

  •             专门针对 Java 语言的:Kryo,FST 等等
  •             跨语言的:Protostuff(基于 protobuf 发展而来),ProtoBuf,Thrift,Avro,MsgPack 等等

11,TCP长连接和短连接

        我们知道 TCP 在进行读写之前,server 与 client 之间必须提前建立一个连接。建立连接的过程,需要我们常说的三次握手,释放/关闭连接的话需要四次挥手。这个过程是比较消耗网络资源并且有时间延迟的。所谓,短连接说的就是 server 端 与 client 端建立连接之后,读写完成之后就关闭掉连接,如果下一次再要互相发送消息,就要重新连接。短连接的优点很明显,就是管理和实现都比较简单,缺点也很明显,每一次的读写都要建立连接必然会带来大量网络资源的消耗,并且连接的建立也需要耗费时间。长连接说的就是 client 向 server 双方建立连接之后,即使 client 与 server 完成一次读写,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。长连接的可以省去较多的 TCP 建立和关闭的操作,降低对网络资源的依赖,节约时间。对于频繁请求资源的客户来说,非常适用长连接。

           

12,为什么需要心跳机制?Netty 支持哪些心跳类型设置?

在 TCP 保持长连接的过程中,可能会出现断网等网络异常出现,异常发生的时候, client 与 server 之间如果没有交互的话,他们是无法发现对方已经掉线的。为了解决这个问题, 我们就需要引入 心跳机制 。

心跳机制的工作原理是: 在 client 与 server 之间在一定时间内没有数据交互时, 即处于 idle 状态时, 客户端或服务器就会发送一个特殊的数据包给对方, 当接收方收到这个数据报文后, 也立即发送一个特殊的数据报文, 回应发送方, 此即一个 PING-PONG 交互。所以, 当某一端收到心跳消息后, 就知道了对方仍然在线, 这就确保 TCP 连接的有效性.

TCP 实际上自带的就有长连接选项,本身是也有心跳包机制,也就是 TCP 的选项:SO_KEEPALIVE。但是,TCP 协议层面的长连接灵活性不够。所以,一般情况下我们都是在应用层协议上实现自定义信跳机制的,也就是在 Netty 层面通过编码实现。通过 Netty 实现心跳机制的话,核心类是 IdleStateHandler 。

  • readerIdleTime:为读超时时间(即测试端一定时间内未接受到被测试端消息)。IdleState.READER_IDLE
  • writerIdleTime:为写超时时间(即测试端一定时间内向被测试端发送消息)。IdleState.WRITER_IDLE
  • allIdleTime:所有类型的超时时间。IdleState.ALL_IDLE
//心跳机制 PING-PONG 交互 第一个参数设置未读时间,第二个参数设置为未写时间,第三个为都未进行操作的时间
//一般第一个时间是服务器设置多长时间没有收到客户端消息的时间,第二个是netty客户端设置多长时间给服务器发送一条消息的时间.心跳检测主要是通过向线程任务队列中添加定时任务,判断channelRead()方法或write()方法是否调用空闲超时,如果超时则触发超时事件执行自定义userEventTrigger()方法
ch.pipeline().addLast(new IdleStateHandler(0, 0, idleTImeSec) {
    @Override
    protected final void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {
        log.info("evt {}", evt.state());
        //IdleState.READER_IDLE 读空闲超时时间设定,如果channelRead()方法超过readerIdleTime时间未被调用则会触发超时事件调用userEventTrigger()方法; 表示 如果客户端没有在规定的时间内给你发送消息,服务端就会认为这个客户端宕掉了,关闭这个链接
        //IdleState.WRITER_IDLE 写空闲超时时间设定 allIdleTime所有类型的空闲超时时间设定,包括读空闲和写空闲;
        if (evt.state() == IdleState.ALL_IDLE) {
            ctx.fireExceptionCaught(ReadTimeoutException.INSTANCE);
        }
    }
});

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 什么是NettyNetty是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。它基于NIO(Non-blocking I/O)技术,提供了一种高度可定制的网络编程框架。 2. Netty有哪些主要的优点? Netty的主要优点包括: - 高性能:Netty使用异步事件驱动模型,能够处理更高的并发连接数,具有更低的延迟和更高的吞吐量。 - 易于使用:Netty提供了简单、直观的API,使开发人员能够快速上手,快速开发网络应用程序。 - 可扩展性:Netty的设计使其易于扩展,可以通过添加自定义处理器来实现特定的协议或功能。 - 安全性:Netty提供了强大的安全性功能,包括SSL/TLS支持和嵌入式加密。 - 可维护性:Netty的代码结构清晰、模块化,使其易于维护和调试。 3. Netty的核心组件是什么? Netty的核心组件包括: - Channel:表示一个网络连接,可以进行读、写和关闭操作。 - EventLoop:负责处理一个或多个Channel上的事件,包括读、写和空闲事件等。 - ChannelFuture:表示一个异步操作的结果,可以通过添加监听器来处理操作完成后的事件。 - ChannelHandler:用于处理Channel上的事件,包括读、写和异常事件等。 4. Netty的线程模型是什么? Netty的线程模型采用了Reactor模式,它是一种事件驱动的设计模式。在Reactor模式中,有一个或多个EventLoop线程负责处理事件,当有事件发生时,它们会调用相应的处理器来处理事件。 在Netty中,每个Channel都会被注册到一个EventLoop上,当有事件发生时,它们会调用注册在Channel上的ChannelHandler来处理事件。由于EventLoop是单线程的,因此需要通过多个EventLoop来实现并发处理。 5. Netty支持哪些协议? Netty支持多种协议,包括: - TCP/UDP:Netty提供了TCP和UDP协议的实现,支持多种编解码器,可以轻松实现自定义协议。 - HTTP/HTTPS:Netty提供了HTTP和HTTPS协议的实现,可以轻松构建高性能的Web应用程序。 - WebSocket:Netty提供了WebSocket协议的实现,可以轻松构建实时应用程序,如聊天应用程序。 - DNS:Netty提供了DNS协议的实现,可以轻松构建高性能的DNS服务器。 - SMTP:Netty提供了SMTP协议的实现,可以轻松构建高性能的邮件服务器。 - SSH:Netty提供了SSH协议的实现,可以轻松构建安全性高的远程访问应用程序。 6. Netty的内存模型是什么? Netty的内存模型采用了堆外内存池技术,它将Java对象和操作系统的I/O缓冲区分离开来,可以减少Java垃圾回收的负担,提高了性能。 Netty的ByteBuf类用于表示堆外内存,它提供了一种高效的读写字节数据的方式。由于ByteBuf是直接内存,因此可以通过零拷贝技术来减少内存拷贝,提高了性能。 7. 如何优化Netty应用程序的性能? 要优化Netty应用程序的性能,可以采取以下措施: - 使用异步I/O:Netty的异步事件驱动模型可以提高并发连接数、降低延迟和提高吞吐量。 - 精简处理器:只加载必要的处理器,可以减少内存占用和提高性能。 - 合理使用内存:采用堆外内存池技术,可以减少Java垃圾回收的负担,提高性能。 - 使用编解码器:Netty提供了多种编解码器,可以轻松实现自定义协议,提高性能。 - 合理使用线程:合理设置线程数,可以充分利用系统资源,提高性能。 - 使用性能监控工具:可以使用性能监控工具来发现性能瓶颈和优化空间。 8. Netty的异常处理机制是什么? Netty的异常处理机制基于ChannelPipeline,ChannelPipeline中的每个ChannelHandler都可以处理异常。当发生异常时,Netty会将异常抛给最后一个ChannelHandler,并且沿着ChannelPipeline向前传播,直到有处理该异常的ChannelHandler。 如果没有找到能够处理该异常的ChannelHandler,Netty会调用默认的异常处理器,它会将该异常记录到日志中,并关闭该Channel。 9. Netty如何实现心跳机制? Netty可以通过添加IdleStateHandler处理器来实现心跳机制。该处理器会检测Channel是否空闲,如果超过指定的时间没有读或写事件发生,就会触发一个IdleStateEvent事件。开发人员可以通过重写ChannelHandler的userEventTriggered方法来处理该事件,实现心跳机制。 10. Netty如何实现高可用性? 要实现Netty应用程序的高可用性,可以采用以下措施: - 使用负载均衡器:可以通过负载均衡器将请求分发到多个Netty服务器上,提高可用性和吞吐量。 - 实现集群化部署:将Netty应用程序部署到多个服务器上,可以提高可用性和扩展性。 - 配置自动故障转移:在Netty应用程序出现故障时,可以自动将请求转移到备用服务器上,提高可用性。 - 实现数据备份:对于关键数据,可以进行备份,以防止数据丢失。 - 配置监控和告警机制:对于Netty应用程序的关键指标,可以配置监控和告警机制,及时发现和处理故障。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值