1. Netty核心功能与线程模型详解

news2024/12/27 1:21:22

Netty

  • 1. 认识Netty
  • 2. 第一个Netty程序

本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。

课程内容:

01、Netty核心组件快速了解
02、Hello,Netty!
03、深入理解Channel、EventLoop(Group)
04、深入理解EventLoop和EventLoopGroup
05、ChannelHandler和它的适配器
06、ChannelPipeline辨析
07、ChannelHandlerContext辨析
08、用Netty解决TCP粘包/半包
09、Netty中的编解码器
10、实战Netty快速实现Web服务器
11、序列化框架Netty集成实战
12、Netty中的单元测试

1. 认识Netty

Netty 4.1.42.Final版本进行

<dependency>
   <groupId>io.netty</groupId>
   <artifactId>netty-all</artifactId>
   <version>4.1.42.Final</version>
   <scope>compile</scope>
</dependency>

基于Netty的知名项目

  • 数据库:Cassandra
  • 大数据处理:Spark、Hadoop
  • 消息中间件:RocketMQ
  • 检索:Elasticsearch
  • 框架:gRPC、Apache Dubbo、Spring5 WebFlux
  • 分布式协调器:ZooKeeper

Netty的优势

  1. API使用简单,开发门槛低;
  2. 功能强大,预置了多种编解码功能,支持多种主流协议;
  3. 定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展;
  4. 性能高,通过与其他业界主流的NIO框架对比,Netty的综合性能最优;
  5. 成熟、稳定,Netty修复了已经发现的所有JDK NIO BUG,业务开发人员不需要再为NIO的BUG而烦恼;
  6. 社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会加入;
  7. 经历了大规模的商业应用考验,质量得到验证。

为什么不用Netty5 ?
Netty5有两个重大改变:支持AIO(异步编程,就是要回调),将线程模型改成了favk/join。通过测试发现其实对性能的提高不是很大,几乎不明显。

因为Netty5还处于Alpha1版本,几乎停止维护了

为什么Netty使用NIO而不是AIO?
Linux下的AIO是一个伪AIO,Linux下的AIO性能也不如NIO的强。

为什么不用Mina ?

其实根据诞生关系是Netty的诞生稍微比Mina早了那么一点,这个Netty与Mina是同一个作者,这个作者在完成了Mina之后又投身于Netty种了,相当于Mina处于缺少维护的状态。并且Netty之后发布的版本的性能都比Mina优秀,因此就没有使用Mina

2. 第一个Netty程序

Netty的核心组件初步认识

  • Bootstrap、EventLoop(Group)、Channel
  • 事件和ChannelHandler、ChannelPipeline
  • ChannelFuture

Bootstrap是Netty框架启动类和主入口类。Bootstrap分为服务端的与客户端的,

在 Netty 中,Channel 是网络通信的基本概念和抽象。它代表着一个开放的连接,可以进行数据的读写和事件的处理。
具体来说,Channel 可以理解为应用程序与网络套接字之间的通道,它提供了以下主要功能:

  1. 数据的读写:通过 Channel,应用程序可以从网络中读取数据或将数据写入网络。它提供了高效的读写操作,支持异步非阻塞的 I/O 操作。可以通过 Channel 的读写方法来实现数据的传输和交换。
  2. 事件的处理:Channel 是一个事件驱动的实体,它可以处理各种网络事件,例如连接建立、数据到达、写就绪等。通过注册不同类型的事件处理器(ChannelHandler),应用程序可以根据需要处理这些事件,执行相应的逻辑处理。
  3. 状态的管理:Channel 提供了连接的状态管理,包括打开、关闭、活动状态等。应用程序可以通过 Channel 的状态变化事件进行相应的处理,例如连接建立或断开时的处理操作。
  4. 通道的配置:Channel 可以进行各种配置,如设置缓冲区大小、接收和发送缓冲区的设置、超时设置等。通过配置 Channel,可以调整网络通信的性能和行为。
    总之,Channel 在 Netty 中扮演着非常重要的角色,它是应用程序与网络之间的桥梁,提供了数据读写、事件处理和状态管理等功能。通过使用 Channel,开发者可以方便地进行网络编程,实现高性能和可靠的网络通信。

EventLoop(Group)
在 Netty 中,EventLoop 是用于处理 I/O 事件和任务的线程。它是 Netty 异步事件驱动的核心组件,负责管理 Channel 的生命周期、处理事件和执行任务。
EventLoop 在 EventLoopGroup 中扮演着重要角色,而 EventLoopGroup 则是一组维护和管理 EventLoop 的容器。一般情况下,一个应用程序只需要一个 EventLoopGroup,而其中的多个 EventLoop 可以同时处理多个 Channel 的 I/O 操作。
EventLoop 的主要功能包括:

  1. I/O 事件的处理:EventLoop 负责处理 Channel 的 I/O 事件,如数据的读写、连接的建立和关闭等。当一个 I/O 事件发生时,EventLoop 会调用相应的 ChannelHandler 处理事件,并触发相应的回调方法。通过事件驱动的方式,实现了高效的异步非阻塞 I/O。
  2. 任务的执行:除了处理 I/O 事件外,EventLoop 还可以执行用户自定义的任务。这些任务可以是一些耗时的计算、定时任务、事件调度等。通过将任务提交给 EventLoop,可以在事件循环中异步执行,避免了阻塞主线程的情况。
  3. 定时任务的处理:EventLoop 提供了定时任务的调度和执行,支持在一定的时间间隔或固定的时间点执行任务。这对于需要定时执行一些操作的应用场景非常有用,例如心跳检测、定时数据刷新等。

需要注意的是,EventLoop 在内部维护一个事件循环(Event Loop),它会不断地轮询 I/O 事件和任务,以便及时处理。每个 EventLoop 都有一个独立的线程来执行这个循环,确保了并发的安全性。

总之,EventLoop 是 Netty 中负责处理 I/O 事件和任务的线程,通过事件驱动的方式实现了高效的异步非阻塞 I/O。它在 EventLoopGroup 中起着重要的作用,为应用程序提供了高性能和可扩展的网络编程能力。

在 Netty 中,事件(Event)、ChannelHandler 和 ChannelPipeline 是实现高效网络通信的重要组件。

  1. 事件(Event):事件是 Netty 中的核心概念,它代表了网络通信过程中发生的各种状态和操作,如连接建立、数据到达、数据写就绪等。Netty 使用事件来驱动整个网络通信过程,通过触发和处理事件来实现异步的、非阻塞的网络通信。
  2. ChannelHandler:ChannelHandler 是用于处理事件和执行业务逻辑的组件。它定义了一组回调方法,如 channelRead()、channelActive()、channelInactive() 等,用于处理不同类型的事件。开发者可以实现自己的 ChannelHandler,并将其注册到 ChannelPipeline 中,以便在特定事件发生时执行相应的逻辑处理。
  3. ChannelPipeline:ChannelPipeline 是 ChannelHandler 的容器,它负责管理和执行 ChannelHandler 的调用顺序。每个 Channel 都会有一个对应的 ChannelPipeline,用于处理该 Channel 上的事件和数据。当一个事件被触发时,ChannelPipeline 会按照预定的顺序依次调用注册的 ChannelHandler 来处理事件。通过配置不同的 ChannelHandler,可以实现数据的编解码、数据处理、安全认证等功能。

ChannelPipeline 的设计遵循了责任链模式,每个 ChannelHandler 只负责自己关心的事件,通过调用下一个 ChannelHandler 来传递事件和数据。这样可以实现组件的解耦和灵活的功能扩展。

通过将不同的 ChannelHandler 注册到 ChannelPipeline 中,可以构建一个处理器链,每个处理器负责特定的功能。数据在经过 ChannelPipeline 时,会按照处理器链的顺序依次经过每个处理器,最终被发送到合适的目标。

总结来说,事件、ChannelHandler 和 ChannelPipeline 是 Netty 中实现高效网络通信的核心组件。事件用于驱动整个网络通信过程,ChannelHandler 用于处理事件和执行业务逻辑,而 ChannelPipeline 则是管理和执行 ChannelHandler 的调用顺序,实现了组件的解耦和灵活的功能扩展。通过合理配置和使用这些组件,可以实现高性能、可扩展的网络应用。

在 Netty 中,ChannelFuture 是用于异步操作结果的表示和处理的对象。它表示一个尚未完成的 I/O 操作,可以通过 ChannelFuture 来获取操作的结果、添加监听器以及执行后续的操作。
ChannelFuture 提供了以下主要功能:

  1. 异步操作的结果:ChannelFuture 可以获取异步操作的结果,如数据的发送、连接的建立等。它提供了方法来判断操作是否完成,获取操作的成功或失败状态,以及获取操作返回的结果对象。
  2. 添加操作完成的监听器:可以通过 ChannelFuture 添加一个或多个监听器,以便在操作完成后执行相应的操作。例如,可以添加一个监听器来处理操作完成时的逻辑,或者添加一个监听器来处理操作失败时的错误处理。通过监听器,可以对异步操作的结果进行处理。
  3. 等待和同步操作:可以通过 ChannelFuture 进行等待和同步操作,即阻塞当前线程,直到操作完成。这对于需要等待操作结果并进行后续处理的情况非常有用。可以使用 ChannelFuture 的一些方法,如 await()、sync() 等来实现等待和同步操作。
  4. 链式操作:ChannelFuture 支持链式操作,可以在一个操作完成后继续执行下一个操作。通过调用 ChannelFuture 的一些方法,如 addListener()、addListener(ChannelFutureListener) 等,可以实现链式操作的编写,简化了代码的编写。

总之,ChannelFuture 在 Netty 中用于表示和处理异步操作的结果。通过它,可以获取操作的结果、添加监听器来处理操作完成后的逻辑,进行等待和同步操作,以及实现链式操作。它提供了灵活的方式来处理和管理异步操作,使得网络编程更加简洁和高效。

在这里插入图片描述

Hello,Netty! 我们的第一个Netty程序

只要使用Netty,下面这个代码是必写的,唯一不同的是每个应用的handler不太一样。

package com.ding.nettybasic;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;

public class EchoServer {
    private static final Logger LOG = LoggerFactory.getLogger(EchoServer.class);

    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws InterruptedException {
        int port = 9999;
        EchoServer echoServer = new EchoServer(port);
        LOG.info("服务器即将启动");
        echoServer.start();
        LOG.info("服务器关闭");
    }

    private void start() throws InterruptedException {
        /*线程组*/
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
            /*服务端启动必备,*/
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EchoServerHandler());
                        }
                    });
            /*异步绑定到服务器,sync()会阻塞到完成*/
            ChannelFuture f = b.bind().sync();
            /*阻塞当前线程,知道服务器的ServerChannel被关闭*/
            f.channel().closeFuture().sync();
        }finally {
            group.shutdownGracefully().sync();
        }
    }
}

SocketChannel在与业务流转之间还有一个Buffer,因此这个里面也要有一个Buffer

在这里插入图片描述

package com.ding.nettybasic;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        ByteBuf in = (ByteBuf)msg;
        System.out.println("server accept:"+in.toString(CharsetUtil.UTF_8));
        ctx.writeAndFlush(in);
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/708484.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySql的使用

目录 一、安装与启动1.1 Ubuntu下的使用1.2 Mac下的使用 二、MySQL图形化管理工具的使用三、数据完整性3.1 数据类型3.2 约束 四、常用的sql语句4.1 数据库操作4.2 数据库表操作1.查看当前数据库中所有表2.查看建表的数据结构3.创建表4.添加字段5.修改字段6. 删除字段7. 查看表…

nodejs之net模块的使用

vscode的底层ipc通讯都是基于node的net模块进行封装&#xff0c;今天大概讲解下net模块的使用 官方文档地址&#xff1a;https://nodejs.cn/api/net.html net模块的作用 net模块提供了基于流的方式构建tcp或ipc服务器和客户端的能力。 node:net 模块提供异步网络 API&#x…

ChatGPT发展与技术基础

一、ChatGPT发展 【ChatGPT——GPT3.5】 诞生于&#xff1a;2022 年 11 月 类型&#xff1a;对话场景的大语言模型 特点&#xff1a;更贴近人的方式与使用者互动&#xff1b;在理解人类意图、精准回答问题、流畅生成结果方面远超人类预期。 功能&#xff1a;可以回答问题、…

bug--两个表格,数据来自于同一个抽屉表格,现在让两个表格的数据 不能一样--处理checked 和 disabled

步骤一、拿到表格数据 步骤二、处理 checked&#xff0c;要区分是A表 还是B表&#xff0c;这个区分要在 A表、B表 数据展示的组件里&#xff08;根源&#xff09;区分 &#xff1a; 点击A表&#xff0c;抽屉表格中A 已选的状态 是 checked 且 disabled&#xff0c;B 已选的 抽…

HCIA复习一

OSI七层模型 7.应用层&#xff1a; 用于人机交互&#xff0c;将抽象语言转化为编码&#xff1b; 6.表示层&#xff1a; 将编码转换为二进制&#xff1b;&#xff08;加解密&#xff0c;压缩解压缩&#xff09; 5.会话层&#xff1a; 管理通信双方的会话&#xff0c;细分为…

数模笔记6.30

目录 一、基础 建模步骤&#xff1a; 论文格式&#xff1a; 写作过程&#xff1a; 赛题类型&#xff1a; 二、优化类模型 2.1简单的优化模型 2.2数学规划模型 三、Lingo 一、基础 建模步骤&#xff1a; 找目标 找条件&#xff08;变量、常量、自己的假设&#xff09…

Tomcat的优化多实例部署

一.tomcat核心组件模块 1.web容器&#xff1a;接受.响应请求 2.展示动态页面 2..JSP容器&#xff1a;翻译java---》servlet 3.serverlet容器&#xff1a;serverlet代码格式是用于JSP容器处理 简述&#xff1a; web容器 &#xff1a;1.接受、响应请求 2.展示动态页面 JSP容…

python之 flask 框架

创建安装虚拟环境 两种方法 第二种 # 先打开cmd 中断 # 查看virtual是否安装过 pip show virtualenv # 安装 pip install virtualenvwrapper-win # workon 查看虚拟环境 vorkon # 切换虚拟环境 # workon 虚拟环境 # mkvirtualenv 创建新的虚拟环境 mkvirtualenv falsk2…

MySQL 字符集与比较规则

字符集与比较规则 一. 字符集相关操作1. 查看字符集1.1 查看数据库当前字符集配置1.2 查看某数据库/数据表字符集 2. 修改字符集2.1 全局修改字符集2.2 修改已有库表字符集 3. 字符集级别二. 比较规则1. 后缀表示含义2. 查看指定数据集比较规则3. 查看/修改数据库/表比较规则 一…

计算机视觉:窥探数字世界的眼睛

目录 简介&#xff1a; 一. 计算机视觉的起源与发展 二. 计算机视觉的应用领域 三. 计算机视觉的挑战与未来发展 结论&#xff1a; 简介&#xff1a; 计算机视觉&#xff08;Computer Vision&#xff09;是人工智能&#xff08;AI&#xff09;领域中的一个重要分支&#…

同一VLAN不同交换机之间的数据转发

实验环境&#xff1a; 思科模拟器&#xff0c;Cisco Packet Tracer 实验拓扑&#xff1a; 配置步骤&#xff1a; &#xff08;1&#xff09;配置四台PC的IP地址 双击PC选择Desktop&#xff0c;然后选择IP Configuration配置ip &#xff08;2&#xff09;配置交换机 双击交换…

登录校验-interceptor/拦截器

Interceptor 概念&#xff1a;拦截前端对后端的某些请求 使用步骤 自定义拦截器类&#xff0c;实现HandlerInterceptor接口&#xff0c;重写所有的方法&#xff08;preHandle方法在controller执行之前执行、【postHandle、afterCompletion】在controller执行后执行&#xff0…

基于java,springboot的零食零售系统设计与实现

背景 本系统实现管理员&#xff1a;首页、个人中心、用户管理、零食分类管理、零食信息管理、订单评价管理、系统管理、订单管理&#xff0c;用户&#xff1b;首页、个人中心、订单评价管理、我的收藏管理、订单管理&#xff0c;前台首页&#xff1b;首页、零食信息、零食资讯…

Vue工程创建及应用

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

Python Pandas之loc、iloc

df.loc 通过标签索引获取数据 df.iloc 通过位置索引获取数据

Airtest:Windows桌面应用自动化测试二【Airtest基于图像识别自动控制手机App流程】

Airtest基于图像识别自动控制手机App流程 一、Airtest基于图像识别自动控制手机App流程二、基于图像识别生成脚本有两种操作&#xff1a;三、Airtest基于Poco的UI组件自动化控制App流程四、Airtest实现手机群控操作 Airtest介绍与脚本入门 Airtest相关api操作 一、Airtest基于…

暑期学JavaScript【第三天】

事件流 很多时候&#xff0c;一个事件可能会被多个元素监听。那么这些元素应该按什么顺序响应呢&#xff1f;从父到子称为捕获&#xff0c;从子到父称为冒泡。 事件捕获 可选参数&#xff0c;true or fause&#xff0c;带true代表按捕获方式响应 obj.addEventListener(cli…

短视频seo源码部署打包分享---开源

功能概要&#xff1a; 1. 按关键词搜索账号排名 2. 按关键词布局查询视频排名 3. 按天计费功能开发 4. 达标天数及关键词数量统计 开发概要&#xff1a; 区别于其他开发者&#xff0c;同类产品多用第三方&#xff0c;如&#xff1a;站长之家&#xff0c;本系统代码开发使…

| 从头打造个人网站(超详细)

哈喽🤗,这篇博客从0开始教大家创建自己的网站,包含个人网站,商用网站等,并且提供模板类型,提供修改模块样本~ 看完本博客你将会收获: 一个想要的类型网站学习React解答过程中遇到的问题最终效果 那就开始吧👩‍💻👨‍💻 ********************************…

AutoSAR系列讲解(入门篇)4.9-BSW小结

首先&#xff0c;要恭喜各位&#xff0c;最为枯燥难懂的一章你已经看完了。也许现在你还是一头雾水&#xff0c;但是相信大部分人都差不多&#xff0c;不必着急&#xff0c;因为AutoSAR单纯看理论最终也就只能看到这个程度了。所以看不太懂的小伙伴在这里先给自己一个定位&…