Netty经典32连问

admin2024-04-03  9

文章目录

  • 1、Netty是什么,它的主要特点是什么?
  • 2、Netty 应用场景了解么?
  • 3、Netty 核心组件有哪些?分别有什么作用?
  • 4、Netty的线程模型是怎样的?如何优化性能?
  • 5、EventloopGroup了解么?和 EventLoop 啥关系?
  • 6、Netty 的零拷贝了解么?
  • 7、Netty 长连接、心跳机制了解么?
  • 8、Netty 服务端和客户端的启动过程了解么?
  • 9、Netty 的 Channel 和 EventLoop 之间的关系是什么?
  • 10、什么是 Netty 的 ChannelPipeline,它是如何工作的?
  • 11、Netty 中的 ByteBuf 是什么,它和 Java 的 ByteBuffer 有什么区别?
  • 12、Netty 中的 ChannelHandlerContext 是什么,它的作用是什么?
  • 13、什么是 Netty 的 ChannelFuture,它的作用是什么?
  • 14、Netty 中的 ChannelHandler 是什么,它的作用是什么?
  • 15、Netty 中的各种 Codec 是什么,它们的作用是什么?
  • 16、什么是 Netty 的 BootStrap,它的作用是什么?
  • 17、Netty的IO模型是什么?与传统的BIO和NIO有什么不同?
  • 18、如何在Netty中实现TCP粘包/拆包的处理?
  • 19、Netty如何处理大文件的传输?
  • 20、如何使用Netty实现心跳机制?
  • 21、Netty中如何实现SSL/TLS加密传输?
  • 22、NioEventLoopGroup 默认的构造函数会起多少线程?
  • 23、如何使用Netty实现WebSocket协议?
  • 24、Netty 高性能表现在哪些方面?
  • 25、Netty 和 Tomcat 的区别?
  • 26、服务端Netty的工作架构图
  • 27、简单聊聊:Netty的线程模型的三种使用方式?
  • 28、Netty 是如何保持长连接的
  • 29、Netty 发送消息有几种方式?
  • 30、Netty 支持哪些心跳类型设置?
  • 31、Netty的内存管理机制是什么?
  • 32、Netty 中如何实现高可用和负载均衡?

1、Netty是什么,它的主要特点是什么?

Netty经典32连问,在这里插入图片描述,第1张

2、Netty 应用场景了解么?

Netty经典32连问,在这里插入图片描述,第2张

Dubbo、RocketMQ、redis都是使用 Netty 作为通讯的基础。以及tomcat也在规划使用netty作为通讯基础

3、Netty 核心组件有哪些?分别有什么作用?

Netty经典32连问,在这里插入图片描述,第3张

这些核心组件共同构成了Netty的核心架构,可以帮助开发人员快速地实现高性能、高并发的网络应用程序。

4、Netty的线程模型是怎样的?如何优化性能?

线程池

优化线程池参数

优化通信协议、数据结构、业务

5、EventloopGroup了解么?和 EventLoop 啥关系?

6、Netty 的零拷贝了解么?

mmap适合小数据量的传输, RocketMQ使用的就是mmap。
sendFile 适合大数据量的传输,Kafka使用的就是sendFile。

6.1 传统拷贝
Netty经典32连问,在这里插入图片描述,第4张

经过了:
4次拷贝的过程:
硬盘—>内核—>应用程序内存(可以理解为用户态,相当于jvm中)—>socket缓冲区—>网卡;
3次上下文切换:
上下文的切换经过了:用户态–>内核态–>用户态

6.2 mmap拷贝

Netty经典32连问,在这里插入图片描述,第5张
经过了:
硬盘—>内核—>socket缓冲区—>网卡,这3次拷贝的过程。
上下文的切换经过了:用户态–>内核态–>用户态 这三次上下文切换

6.3 sendFile零拷贝
2次拷贝
Netty经典32连问,在这里插入图片描述,第6张

6.4 netty的零拷贝

7、Netty 长连接、心跳机制了解么?

8、Netty 服务端和客户端的启动过程了解么?

总的来说,Netty 的服务端和客户端启动过程比较简单,只需要进行一些基本的配置和设置,就可以完成相应的功能。通过使用 Netty,可以方便地开发高性能、高可靠性的网络应用程序。

9、Netty 的 Channel 和 EventLoop 之间的关系是什么?

10、什么是 Netty 的 ChannelPipeline,它是如何工作的?

netty设计责任链模式的ChannelPipeline,使得netty可以为所欲为,Netty实现了高度可配置和可扩展的网络通信模型,使得开发人员可以根据自己的需求选择和组合不同的处理器,以构建出高效、稳定、安全的网络通信系统。

11、Netty 中的 ByteBuf 是什么,它和 Java 的 ByteBuffer 有什么区别?

Netty经典32连问,在这里插入图片描述,第7张

12、Netty 中的 ChannelHandlerContext 是什么,它的作用是什么?

总之,ChannelHandlerContext是一个重要的Netty组件,它提供了一种简单的机制,让开发者在处理网络I/O事件时可以更加灵活和高效地操作管道中的Handler。

13、什么是 Netty 的 ChannelFuture,它的作用是什么?

总之,ChannelFuture是Netty中异步I/O操作的基础,它提供了一种简单而有效的机制,使得开发者可以方便地处理I/O操作的结果。

14、Netty 中的 ChannelHandler 是什么,它的作用是什么?

15、Netty 中的各种 Codec 是什么,它们的作用是什么?

Netty经典32连问,在这里插入图片描述,第8张

这些 Codec 组件可以通过组合使用来构建复杂的数据协议处理逻辑,以提高代码的可重用性和可维护性。

16、什么是 Netty 的 BootStrap,它的作用是什么?

Netty经典32连问,在这里插入图片描述,第9张

17、Netty的IO模型是什么?与传统的BIO和NIO有什么不同?

18、如何在Netty中实现TCP粘包/拆包的处理?

Netty经典32连问,在这里插入图片描述,第10张

可以通过以下几种方式来解决TCP粘包/拆包问题:

  • 1.消息定长:
// 编码器,将消息的长度固定为100字节
pipeline.addLast("frameEncoder", new LengthFieldPrepender(2));
pipeline.addLast("messageEncoder", new StringEncoder(CharsetUtil.UTF_8));
// 解码器,根据固定长度对消息进行拆分
pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(100, 0, 2, 0, 2));
pipeline.addLast("messageDecoder", new StringDecoder(CharsetUtil.UTF_8));
  • 2.消息分隔符:
// 编码器,以"\r\n"作为消息分隔符
pipeline.addLast("frameEncoder", new DelimiterBasedFrameEncoder("\r\n"));
pipeline.addLast("messageEncoder", new StringEncoder(CharsetUtil.UTF_8));
// 解码器,根据"\r\n"对消息进行拆分
pipeline.addLast("frameDecoder", new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
pipeline.addLast("messageDecoder", new StringDecoder(CharsetUtil.UTF_8));
  • 3.消息头部加长度字段:
// 编码器,将消息的长度加入消息头部
pipeline.addLast("frameEncoder", new LengthFieldPrepender(2));
pipeline.addLast("messageEncoder", new StringEncoder(CharsetUtil.UTF_8));
// 解码器,先读取消息头部的长度字段,再根据长度读取消息内容
pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 0, 2, 0, 2));
pipeline.addLast("messageDecoder", new StringDecoder(CharsetUtil.UTF_8));

19、Netty如何处理大文件的传输?

具体使用方法如下:

  1. 在服务端和客户端的ChannelPipeline中添加ChunkedWriteHandler。

    pipeline.addLast(new WriteBufferWaterMark(8 * 1024, 32 * 1024));
    pipeline.addLast(new ChunkedWriteHandler());
    
  2. 在服务端和客户端的业务逻辑处理器中,接收并处理ChunkedData。

    public class MyServerHandler extends SimpleChannelInboundHandler<Object> {
       @Override
       protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
           if (msg instanceof HttpRequest) {
               HttpRequest request = (HttpRequest) msg;
               // 处理HTTP请求
               // ...
           } else if (msg instanceof HttpContent) {
               HttpContent content = (HttpContent) msg;
               // 处理HTTP内容
               if (content instanceof LastHttpContent) {
                   // 处理完整个HTTP请求
                   // ...
               } else if (content instanceof HttpChunkedInput) {
                   HttpChunkedInput chunkedInput = (HttpChunkedInput) content;
                   // 处理ChunkedData
                   while (true) {
                       HttpContent chunk = chunkedInput.readChunk(ctx.alloc());
                       if (chunk == null) {
                           break;
                       }
                       // 处理单个Chunk
                       // ...
                   }
               }
           }
       }
    }
    
    
  3. 在客户端向服务端发送数据时,将需要传输的文件包装成ChunkedFile并写入管道。

    public void sendFile(Channel channel, File file) throws Exception {
       RandomAccessFile raf = new RandomAccessFile(file, "r");
       DefaultFileRegion fileRegion = new DefaultFileRegion(raf.getChannel(), 0, raf.length());
       HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/");
       HttpUtil.setContentLength(request, raf.length());
       channel.write(request);
       channel.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, file.length(), 8192)));
    }
    

在传输大文件时,还需要注意以下几点 :

  • 1.使用ChunkedFile时需要指定Chunk的大小,根据实际情况选择合适的大小,一般建议不要超过8KB。
  • 2.为了避免大文件传输过程中对网络造成影响,可以在服务端和客户端的ChannelPipeline中添加WriteBufferWaterMark,限制写入缓冲区的大小

20、如何使用Netty实现心跳机制?

Netty经典32连问,在这里插入图片描述,第11张

  1. 定义心跳消息的类型

    public class HeartbeatMessage implements Serializable {
       // ...
    }
    
  2. 在客户端和服务端的ChannelPipeline中添加IdleStateHandler,用于触发定时任务。

    pipeline.addLast(new IdleStateHandler(0, 0, 60, TimeUnit.SECONDS));
    
  3. 在客户端和服务端的业务逻辑处理器中,重写userEventTriggered方法,在触发定时任务时发送心跳包。

public class MyServerHandler extends SimpleChannelInboundHandler<Object> {
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                // 读空闲,发送心跳包
                ctx.writeAndFlush(new HeartbeatMessage());
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
}
  1. 在客户端和服务端的业务逻辑处理器中,重写channelRead方法,接收并处理心跳包。
public class MyClientHandler extends SimpleChannelInboundHandler<Object> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HeartbeatMessage) {
            // 收到心跳包,不做处理
            return;
        }
        // 处理其他消息
        // ...
    }
}

需要注意的是,由于心跳包不需要传输大量数据,因此建议使用Unpooled.EMPTY_BUFFER作为心跳包的内容。另外,心跳间隔的时间应根据实际情况设置,一般建议设置为连接的超时时间的一半。

21、Netty中如何实现SSL/TLS加密传输?

以下是实现 SSL/TLS 加密传输的示例代码:

// 创建 SSLContext 对象,用于构建 SSLEngine
SSLContext sslContext = SSLContext.getInstance("TLS");

// 初始化 SSLContext
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream("server.jks"), "password".toCharArray());
keyManagerFactory.init(keyStore, "password".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

// 获取 SSLEngine
SSLEngine sslEngine = sslContext.createSSLEngine();
sslEngine.setUseClientMode(false);

// 添加 SslHandler 到 ChannelPipeline 中
pipeline.addLast("ssl", new SslHandler(sslEngine));

22、NioEventLoopGroup 默认的构造函数会起多少线程?

23、如何使用Netty实现WebSocket协议?

以下是实现 WebSocket 协议的示例代码:

// 添加 HTTP 请求解码器
pipeline.addLast("httpDecoder", new HttpRequestDecoder());
// 添加 HTTP 响应编码器
pipeline.addLast("httpEncoder", new HttpResponseEncoder());
// 添加 HTTP 聚合器
pipeline.addLast("httpAggregator", new HttpObjectAggregator(65536));
// 添加 WebSocket 服务器协议处理器
pipeline.addLast("webSocketHandler", new WebSocketServerProtocolHandler("/ws"));
// 添加自定义的 WebSocket 处理器
pipeline.addLast("handler", new MyWebSocketHandler());

在以上示例代码中,WebSocketServerProtocolHandler 的参数 “/ws” 表示 WebSocket 请求的 URL 路径,MyWebSocketHandler 是自定义的 WebSocket 处理器。

24、Netty 高性能表现在哪些方面?

Netty经典32连问,在这里插入图片描述,第12张

25、Netty 和 Tomcat 的区别?

Netty经典32连问,在这里插入图片描述,第13张

26、服务端Netty的工作架构图

todo

             ┌───────┐        ┌───────┐
             │ Channel │◀───────│ Socket│
             │Pipeline │        │       │
             └───────┘        └───────┘
                   ▲                 │
                   │                 │
         ┌─────────┴─────────┐       │
         │                   │       │
         ▼                   ▼       ▼
┌──────────────┐   ┌──────────────┐  ┌──────────────┐
│EventLoopGroup│   │EventLoopGroup│  │EventLoopGroup│
│       boss   │   │     work     │  │     work     │
└──────────────┘   └──────────────┘  └──────────────┘
         ▲                   ▲       ▲
         │                   │       │
┌────────┴─────────┐ ┌────────┴─────────┐
│     NioServerSocketChannel   │   NioSocketChannel      │ ...
└──────────────────┘ └──────────────────┘

27、简单聊聊:Netty的线程模型的三种使用方式?

Netty经典32连问,在这里插入图片描述,第14张

28、Netty 是如何保持长连接的

Netty经典32连问,在这里插入图片描述,第15张

29、Netty 发送消息有几种方式?

Netty经典32连问,在这里插入图片描述,第16张

在使用上述三种方式发送消息时,需要注意到写操作可能会失败或被延迟,因此需要在发送消息时进行一定的错误处理或者设置超时时间。另外,也可以使用 Netty 提供的 ChannelFuture 对象来监听操作结果或者进行异步操作。

30、Netty 支持哪些心跳类型设置?

Netty经典32连问,在这里插入图片描述,第17张

需要注意的是,为了避免因心跳机制导致的网络负载过大或者频繁的连接断开和重连,应该根据具体业务场景选择适合的心跳类型和频率。

31、Netty的内存管理机制是什么?

在使用 ByteBuf 时,Netty 还实现了一些优化和特殊处理,如池化缓冲区、零拷贝等技术,以提高内存的利用率和性能的表现。

32、Netty 中如何实现高可用和负载均衡?

  1. 高可用:通过在多台服务器上部署同一个应用程序实现高可用。可以使用负载均衡器来将请求分配给不同的服务器,当某台服务器出现故障时,负载均衡器可以将请求转发给其他可用的服务器。常用的负载均衡器包括Nginx、HAProxy等。
  2. 负载均衡:负载均衡是将请求分配给多台服务器的过程,常用的负载均衡算法包括轮询、随机、权重 等。在Netty中可以使用多个EventLoop来处理请求,将请求分配给不同的EventLoop,从而实现负载均衡。另外,可以使用第三方框架,如Zookeeper、Consul等,来实现服务注册、发现和负载均衡。
  3. 高可用与负载均衡的结合:可以使用多台服务器来实现高可用和负载均衡。在每台服务器上部署同一个应用程序,并使用负载均衡器来分配请求。当某台服务器出现故障时,负载均衡器可以将请求转发给其他可用的服务器,从而保证高可用和负载均衡。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!