首页 > 其他分享 >面试官:说说Netty的核心组件?

面试官:说说Netty的核心组件?

时间:2024-05-30 15:01:12浏览次数:22  
标签:Netty 面试官 netty io 组件 import EventLoopGroup Channel

Netty 核心组件是指 Netty 在执行过程中所涉及到的重要概念,这些核心组件共同组成了 Netty 框架,使 Netty 框架能够正常的运行。

Netty 核心组件包含以下内容:

  1. 启动器 Bootstrap/ServerBootstrap
  2. 事件循环器 EventLoopGroup/EventLoop
  3. 通道 Channel
  4. 通道处理器 ChannelHandler
  5. 通道管道 ChannelPipeline

这些组件的交互流程如下:
image.png
上图是 Netty 逻辑处理架构,这个逻辑处理架构为典型网络分层架构设计,共分为网络通信层、事件调度层、服务编排层,每一层各司其职,共同成为了 Netty 的核心组件。

1.Bootstrap/ServerBootstrap【启动器】

Bootstrap 是“引导”的意思,它主要负责整个 Netty 程序的启动、初始化、服务器连接等过程,它相当于一条主线,串联了 Netty 的其他核心组件。

PS:Netty 中的引导器共分为两种类型:一个为用于客户端引导的 Bootstrap,另一个为用于服务端引导的 ServerBootStrap。

2.Channel【通道】

Channel 是网络数据的传输通道,它代表了到实体(如硬件设备、文件、网络套接字或能够执行 I/O 操作的程序组件)的开放连接,如读操作和写操作。

Channel 提供了基本的 API 用于网络 I/O 操作,如 register、bind、connect、read、write、flush 等。Netty 自己实现的 Channel 是以 JDK NIO Channel 为基础的,相比较于 JDK NIO,Netty 的 Channel 提供了更高层次的抽象,同时屏蔽了底层 Socket 的复杂性,赋予了 Channel 更加强大的功能,你在使用 Netty 时基本不需要再与 Java Socket 类直接打交道。

常见的 Channel 类型有以下几个:

  • NioServerSocketChannel 异步 TCP 服务端。
  • NioSocketChannel 异步 TCP 客户端。
  • OioServerSocketChannel 同步 TCP 服务端。
  • OioSocketChannel 同步 TCP 客户端。
  • NioDatagramChannel 异步 UDP 连接。
  • OioDatagramChannel 同步 UDP 连接。

当然 Channel 也会有多种状态,如连接建立、连接注册、数据读写、连接销毁等状态。

3.EventLoopGroup/EventLoop【事件循环器】

EventLoopGroup 是一个处理 I/O 操作和任务的线程组。在 Netty 中,EventLoopGroup 负责接受客户端的连接,以及处理网络事件,如读/写事件。它包含多个 EventLoop,每个 EventLoop 包含一个 Selector 和一个重要的组件,用于处理注册到其上的 Channel 的所有 I/O 事件

3.1 EventLoopGroup、EventLoop和Channel

它们三者的关系如下:

  1. 一个 EventLoopGroup 往往包含一个或者多个 EventLoop。EventLoop 用于处理 Channel 生命周期内的所有 I/O 事件,如 accept、connect、read、write 等 I/O 事件。
  2. EventLoop 同一时间会与一个线程绑定,每个 EventLoop 负责处理多个 Channel。
  3. 每新建一个 Channel,EventLoopGroup 会选择一个 EventLoop 与其绑定。该 Channel 在生命周期内都可以对 EventLoop 进行多次绑定和解绑。

3.2 线程模型

Netty 通过创建不同的 EventLoopGroup 参数配置,就可以支持 Reactor 的三种线程模型:

  1. 单线程模型:EventLoopGroup 只包含一个 EventLoop,Boss 和 Worker 使用同一个EventLoopGroup;
  2. 多线程模型:EventLoopGroup 包含多个 EventLoop,Boss 和 Worker 使用同一个EventLoopGroup;
  3. 主从多线程模型:EventLoopGroup 包含多个 EventLoop,Boss 是主 Reactor,Worker 是从 Reactor,它们分别使用不同的 EventLoopGroup,主 Reactor 负责新的网络连接 Channel 创建,然后把 Channel 注册到从 Reactor。

4.ChannelHandler【通道处理器】

ChannelHandler 是 Netty 处理 I/O 事件或拦截 I/O 操作的组件。当发生某种 I/O 事件时(如数据接收、连接打开、连接关闭等),ChannelHandler 会被调用并处理这个事件。

例如,数据的编解码工作以及其他转换工作实际都是通过 ChannelHandler 处理的。站在开发者的角度,最需要关注的就是 ChannelHandler,我们很少会直接操作 Channel,都是通过 ChannelHandler 间接完成。

5.ChannelPipeline【通道管道】

ChannelPipeline 是 ChannelHandler 的容器,提供了一种方式,以链式的方式组织和处理跨多个 ChannelHandler 之间的交互逻辑。当数据在管道中流动时,它会按照 ChannelHandler 的顺序被处理。

6.Netty 简单示例

下面是一个使用 Netty 构建的最简单服务器端和客户端示例,这个例子中,服务器接收到客户端的消息后,会直接将消息原样回传给客户端。

6.1 服务器端

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class NettyServer {

    public static void main(String[] args) throws Exception {
        // 创建BossGroup和WorkerGroup,它们都是EventLoopGroup的实现
        // BossGroup负责接收进来的连接
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        // WorkerGroup负责处理已经被接收的连接
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            // 创建服务器端的启动对象,配置参数
            ServerBootstrap bootstrap = new ServerBootstrap();

            // 设置两个线程组
            bootstrap.group(bossGroup, workerGroup)
                    // 设置服务器通道实现类型
                    .channel(NioServerSocketChannel.class)
                    // 设置通道初始化器,主要用来配置管道中的处理器
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            // 向管道加入处理器
                            // 解码器:ByteBuf -> String
                            ch.pipeline().addLast(new StringDecoder());
                            // 编码器:String -> ByteBuf
                            ch.pipeline().addLast(new StringEncoder());

                            // 自定义的处理器
                            ch.pipeline().addLast(new ServerHandler());
                        }
                    });

            System.out.println("服务器 is ready...");

            // 绑定一个端口并且同步,生成了一个ChannelFuture对象
            ChannelFuture cf = bootstrap.bind(6668).sync();

            // 对关闭通道进行监听
            cf.channel().closeFuture().sync();
        } finally {
            // 优雅关闭线程组
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

6.2 客户端代码

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class NettyClient {

    public static void main(String[] args) throws Exception {
        // 创建EventLoopGroup,相当于线程池
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            // 创建客户端启动对象
            Bootstrap bootstrap = new Bootstrap();

            // 设置相关参数
            bootstrap.group(group) // 设置线程组
                    .channel(NioSocketChannel.class) // 设置客户端通道实现类型
                    .handler(new ChannelInitializer<SocketChannel>() { // 设置处理器
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            // 向管道加入处理器
                            ch.pipeline().addLast(new StringDecoder());
                            ch.pipeline().addLast(new StringEncoder());
                            // 自定义的处理器
                            ch.pipeline().addLast(new ClientHandler());
                        }
                    });

            System.out.println("客户端 is ready...");

            // 发起异步连接操作
            ChannelFuture future = bootstrap.connect("127.0.0.1", 6668).sync();

            // 发送消息
            future.channel().writeAndFlush("Hello Server!");

            // 对关闭通道进行监听
            future.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully(); // 优雅关闭线程组
        }
    }
}

参考&鸣谢

《Netty核心原理剖析与RPC实践》

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

标签:Netty,面试官,netty,io,组件,import,EventLoopGroup,Channel
From: https://www.cnblogs.com/vipstone/p/18222352

相关文章

  • 微信小程序之实现弹窗组件及点击弹窗按钮实现页面跳转
    创建一个名为PopupWindow的弹窗组件:   1、创建组件目录结构:    在项目的components目录下新建一个名为PopupWindow的文件夹,里面包含四个核心文件: PopupWindow.wxml 、PopupWindow.wxss、PopupWindow.js 、PopupWindow.json   2、编写组件文件......
  • Intel(R) Optane(TM) Memory and Storage Management Component 是一种软件组件,用于管
    Intel(R)Optane(TM)MemoryandStorageManagementComponent是一种软件组件,用于管理英特尔Optane存储技术。Optane技术是英特尔推出的一种新型存储技术,利用3DXPoint存储介质,具有极高的读写速度和低延迟,可用于加速系统的启动、应用程序加载和文件传输等操作。OptaneMem......
  • 十四.吊打面试官系列-JVM优化-JVM垃圾回算法详解
    前言说到JVM不可避免的会聊到垃圾回收器,(GarbageCollection,简称GC)。它负责跟踪哪些对象仍然在使用,哪些对象已经不再被引用,并释放那些不再被引用的对象所占用的内存空间。这一过程涉及到对象的标记、清除、压缩等多个阶段,每个阶段都有其特定的算法和策略。随着Java技术的不......
  • Vue 组件生命周期:探索钩子
    title:Vue组件生命周期:探索钩子date:2024/5/2718:42:38updated:2024/5/2718:42:38categories:前端开发tags:生命周期异步加载通信原理父子通信兄弟通信跨层通信性能优化第1章:介绍与背景1.1什么是Vue组件生命周期?Vue组件生命周期是指Vue组件从创建......
  • 面试官:前端加密怎么做?这,这,这不是后端的活儿吗?
    目录 一、Base64编码二、哈希算法三、对称加密(AES/DES) 四、非对称加密(RSA) 五、加盐六、WebCryptographtAPI七、总结    随着信息和数据安全重要性的日益凸显,如何保证信息数据在传输的过程中的安全成为开发者重点关注的内容。前端加密通常是指在浏览器中......
  • Android 四大组件 service
    前言在Android系统中,Service是一个用来执行长时间运行的操作而不提供用户界面的应用组件。它可以在后台执行任务,即使用户切换到其他应用也不会被中断。Service在Android中主要用于在后台执行长时间运行的任务,例如播放音乐、执行文件下载、处理网络请求等。尽管Service运行......
  • HarmonyOS实战开发:@ohos.pluginComponent (插件组件管理器)
    用于给插件组件的使用者请求组件与数据,使用者发送组件模板和数据。如需实现插件模板的显示,请参考PluginComponent。说明:本模块首批接口从APIVersion8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。导入模块importpluginComponentManagerfrom......
  • QT C++实现表头添加组件
    QTableWidget在表头添加组件QTableWidget的表头有一个类QHeaderView是专门处理表头的类,要在表头添加一个类似QCheckBox的组件需要重写一个类并继承QHeaderView。QTableWidget中添加复选框并实现全选居中:自定义类MyHeaderView并继承QHeaderView自定义类MyTableWidget并继承QTa......
  • 鸿蒙HarmonyOS实战-Web组件(前端函数和应用侧函数相互调用)
    ......
  • 封装通用 ECharts 图表组件(三):环形图实现
    在数据可视化领域,ECharts是一个非常流行且功能强大的图表库。它提供了丰富的图表类型,能够满足各种复杂的数据展示需求。在本系列的第三篇文章中,我们将探讨如何封装一个通用的ECharts环形图组件。什么是环形图?环形图是一种特殊的饼图,它由一个内圆和一个外圆组成,中间的部分是......