深入理解Netty及核心组件使用—下
目录
ChannelHandler
ChannelHandler 接口
ChannelInboundHandler 接口
ChannelHandler 的适配器
Handler 的共享和并发安全性
资源管理和 SimpleChannelInboundHandler
Bootstrap
ChannelInitializer
ChannelOption
ChannelHandler
ChannelHandler 接口
从开发人员的角度来看,Netty 的主要组件是 ChannelHandler,它充当了所有处理入站和出站数据的应用程序逻辑的容器。ChannelHandler 的方法是由网络事件触发的。事实上,ChannelHandler 可专门用于几乎任何类型的动作,例如将数据从一种格式转换为另外一种格式,例如各种编解码,或者处理转换过程中所抛出的异常。
Netty 定义了下面两个重要的 ChannelHandler 子接口:
ChannelInboundHandler——处理入站数据以及各种状态变化。
ChannelOutboundHandler——处理出站数据并且允许拦截所有的操作。
ChannelInboundHandler 接口
ChannelInboundHandler 接口方法:
channelRegistered
当 Channel 已经注册到它的 EventLoop 并且能够处理 I/O 时被调用。channelUnregistered
当 Channel 从它的 EventLoop 注销并且无法处理任何 I/O 时被调用。channelActive
当 Channel 处于活动状态时被调用;Channel 已经连接/绑定并且已经就绪。channelInactive
当 Channel 离开活动状态并且不再连接它的远程节点时被调用。channelReadComplete
当 Channel 上的一个读操作完成时被调用。channelRead
当从 Channel 读取数据时被调用。ChannelWritabilityChanged当 Channel 的可写状态发生改变时被调用。可以通过调用 Channel 的 isWritable()方法
来检测 Channel 的可写性。与可写性相关的阈值可以通过Channel.config().setWriteHighWaterMark()和 Channel.config().setWriteLowWaterMark()方法来设置。userEventTriggered
当ChannelnboundHandler.fireUserEventTriggered()方法被调用时被调用。
ChannelOutboundHandler 接口方法:
bind(ChannelHandlerContext,SocketAddress,ChannelPromise)
当请求将 Channel 绑定到本地地址时被调用connect(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise)
当请求将 Channel 连接到远程节点时被调用disconnect(ChannelHandlerContext,ChannelPromise)
当请求将 Channel 从远程节点断开时被调用close(ChannelHandlerContext,ChannelPromise)
当请求关闭 Channel 时被调用deregister(ChannelHandlerContext,ChannelPromise)
当请求将 Channel 从它的 EventLoop 注销时被调用read(ChannelHandlerContext)
当请求从 Channel 读取更多的数据时被调用flush(ChannelHandlerContext)
当请求通过 Channel 将入队数据冲刷到远程节点时被调用write(ChannelHandlerContext,Object,ChannelPromise)
当请求通过 Channel 将数据写到远程节点时被调用
ChannelHandler 的适配器
有一些适配器类可以将编写自定义的 ChannelHandler 所需要的工作降到最低限度,因为它们提供了定义在对应接口中的所有方法的默认实现。Netty 提供了抽象基类 ChannelInboundHandlerAdapter(处理入站) 和 ChannelOutboundHandlerAdapter(处理出站)。
可以使用 ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter 类作为自己的 ChannelHandler 的起始点。这两个适配器分别提供了 ChannelInboundHandler 和 ChannelOutboundHandler 的基本实现。通过扩展抽象类 ChannelHandlerAdapter,它们获得了它们共同的超接口 ChannelHandler 的方法。

ChannelOutboundHandler 有个非常让人迷惑的 read 方法,这个 read 方法不是表示读数据,而是表示业务发出了读(read)数据的要求,这个要求也会封装为一个事件进行传播,这个事件 因为是业务发出到网络的,自然就是个出站事件,而且这个事件触发的就是 ChannelOutboundHandler 中 read 方法。
如果我们的 Handler 既要处理入站又要处理出站可以使用类 ChannelDuplexHandler,也可以同时实现 ChannelOutboundHandler,ChannelInboundHandler 这两个接口。
Handler 的共享和并发安全性
ChannelHandlerAdapter 还提供了实用方法 isSharable()。如果其对应的实现被标注为 Sharable,那么这个方法将返回 true,表示它可以被添加到多个 ChannelPipeline。
@ChannelHandler.Sharable
//在具体的处理器上打上该注解,在服务端引用的时候提前创建一个实例,可以在多个channel中引用该共享处理器
资源管理和 SimpleChannelInboundHandler
Netty 在处理网络数据时,需要 Buffer,在 Read 网络数据时由 Netty 创建 Buffer,Write 网络数据时 Buffer 往往是由业务方创建的。不管是读和写,Buffer 用完后都必须进行释放,否则可能会造成内存泄露。
在 Write 网络数据时,可以确保数据被写往网络了,Netty 会自动进行 Buffer 的释放,但是如果 Write 网络数据时,我们有 outBoundHandler 处理了 write()操作并丢弃了数据,没有继续往下写,要由我们负责释放这个 Buffer,就必须调用 ReferenceCountUtil.release 方法,否则就可能会造成内存泄露。所以 Netty 提供了一个特殊的被 称为 SimpleChannelInboundHandler 的 ChannelInboundHandler 实现。这个实现会在数据被 channelRead0()方法消费之后自动释放数据。
同时系统为我们提供的各种预定义 Handler 实现,都实现了数据的正确处理,当我们自行编写业务 Handler 时,需要注意:数据要么继续传递,要么自行释放。
Bootstrap
网络编程里,“服务器”和“客户端”实际上表示了不同的网络行为。换句话说,是监听传入的连接还是建立到一个或者多个进程的连接。因此,有两种类型的引导:一种用于客户端(简单地称为 Bootstrap),而另一种(ServerBootstrap)用于服务器。无论你的应用程序使用哪种协议或者处理哪种类型的数据,唯一决定它使用哪种引导类的是它是作为一个客户端还是作为一个服务器。
Bootstrap和ServerBootstrap区别:
1. ServerBootstrap 将绑定到一个端口,因为服务器必须要监听连接,而 Bootstrap 则是由想要连接到远程节点的客户端应用程序所使用的。
2. 引导一个客户端只需要一个 EventLoopGroup,但是一个 ServerBootstrap 则需要两个(也可以是同一个实例)。
因为服务器需要两组不同的 Channel。第一组将只包含一个 ServerChannel,代表服务器自身的已绑定到某个本地端口的正在监听的套接字。而第二组将包含所有已创建的用来处理传入客户端连接(对于每个服务器已经接受的连接都有一个)的 Channel。
与 ServerChannel 相关联的 EventLoopGroup 将分配一个负责为传入连接请求创建 Channel 的 EventLoop。一旦连接被接受,第二个 EventLoopGroup 就会给它的 Channel 分配一个 EventLoop。
ChannelInitializer
//Netty 提供了一个特殊的 ChannelInboundHandlerAdapter 子类
public abstract class ChannelInitializer<C extends Channel> ext ends
ChannelInboundHandlerAdapter//定义了下面的方法:
protect ed abstract void initChannel(C ch) throws Exception;
这个方法提供了一种将多个 ChannelHandler 添加到一个 ChannelPipeline 中的简便方法。你只需要简单地向 Bootstrap 或 ServerBootstrap 的实例提供你的 ChannelInitializer 实现即可,并且一旦 Channel 被注册到了它的 EventLoop 之后,就会调用你的initChannel()版本。在该方法返回之后,ChannelInitializer 的实例将会从 ChannelPipeline 中移除它自己。
之前案例中的:

ChannelOption

//通用 TCP 参数:
ChannelOption.SO_KEEPALIVE: 保持长连接,定期发送TCP保活包。
ChannelOption.TCP_NODELAY: 禁用 Nagle 算法,即禁用延迟发送。//接收缓冲区和发送缓冲区大小:
ChannelOption.SO_RCVBUF: 设置接收缓冲区大小。
ChannelOption.SO_SNDBUF: 设置发送缓冲区大小。//连接相关参数:
ChannelOption.CONNECT_TIMEOUT_MILLIS: 连接超时时间。
ChannelOption.SO_LINGER: 设置延迟关闭的时间,单位为秒。//多路复用相关参数:
ChannelOption.SO_BACKLOG: 设置等待接受的连接队列大小。
ChannelOption.SO_REUSEADDR: 允许重用地址。
ChannelOption.SO_REUSEPORT: 允许多个Socket绑定到同一端口,一般用于实现负载均衡。//其他:
ChannelOption.AUTO_READ: 如果为 true,则注册Channel的时候会自动创建并注册一个关联的ChannelHandlerContext,并调用 ChannelHandlerContext.read() 来开始读取数据。相关文章:
深入理解Netty及核心组件使用—下
目录 ChannelHandler ChannelHandler 接口 ChannelInboundHandler 接口 ChannelHandler 的适配器 Handler 的共享和并发安全性 资源管理和 SimpleChannelInboundHandler Bootstrap ChannelInitializer ChannelOption ChannelHandler ChannelHandler 接口 从开发人员的…...
vscode 突然连接不上服务器了(2024年版本 自动更新从1.85-1.86)
vscode日志 ll192.168.103.5s password:]0;C:\WINDOWS\System32\cmd.exe [17:09:16.886] Got some output, clearing connection timeout [17:09:16.887] Showing password prompt [17:09:19.688] Got password response [17:09:19.688] "install" wrote data to te…...
element-ui link 组件源码分享
link 组件的 api 涉及的内容不是很多,源码部分的内容也相对较简单,下面从以下这三个方面来讲解: 一、组件结构 1.1 组件结构如下图: 二、组件属性 2.1 组件主要有 type、underline、disabled、href、icon 这些属性,…...
序列化和反序列化、pytest-DDT数据驱动
序列化 序列化就是将对象转化成文件 python转成json import jsondata {"数字": [1, 1.1, -1],"字符串": ["aaaa", bbbb],"布尔值": [True, False],"空值": None,"列表": [[1, 2, 3], [4, 5, 6], [7, 8, 9]],&…...
Spring Boot整合MyBatis Plus实现基本CRUD与高级功能
文章目录 1. 引言2. 项目搭建与依赖配置2.1 添加MyBatis Plus依赖2.2 配置数据源与MyBatis Plus 3. 实现基本CRUD功能3.1 创建实体类3.2 创建Mapper接口3.3 实现Service层3.4 控制器实现 4. 高级功能实现4.1 自动填充功能4.2 乐观锁功能4.3 逻辑删除功能 5. 拓展:My…...
CSS 闪电按钮效果
<template><view class="const"><div class="voltage-button"><button>闪电按钮</button><svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox=&q…...
【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案
【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案 大家好 我是寸铁👊 总结了一篇Error: only one service expected goctl一键转换生成rpc服务错误解决方案的文章✨ 喜欢的小伙伴可以点点关注 💝 问题背景 今天寸铁在…...
从头开始构建和训练 Transformer(上)
1、导 读 2017 年,Google 研究团队发表了一篇名为《Attention Is All You Need》的论文,提出了 Transformer 架构,是机器学习,特别是深度学习和自然语言处理领域的范式转变。 Transformer 具有并行处理功能,可以实现…...
JVM-JVM内存结构(一)
程序计数器 Program Counter Register程序计数器(寄存器) 程序计数器在物理层上是通过寄存器实现的 作用:记住下一条jvm指令的执行地址特点 是线程私有的(每个线程都有属于自己的程序计数器)不会存在内存溢出 虚拟机栈 每个线程运行时所需要的内存称为虚拟机栈…...
React Emotion 如何优雅的使用样式(一)
简介 Emotion 是一个专为使用 JavaScript 编写 css 样式而设计的库。它提供了强大且可预测的样式组合,以及源映射、标签和测试实用程序等功能为开发人员提供了出色的体验,并且支持字符串和对象样式。 与框架无关的样式应用包 Emotion中提供了一个与框…...
1+X运维试题样卷A卷(初级)
云计算A卷 单选题(200分) 1.在OSI模型中,HTTP协议工作在第()层,交换机工作在第()层。(10分) (答案正确:10分) A、7/3 B、7/2 (正确答案) C、6/3 D、6/2 2.Linux有三个查看文件的命令,若希望在查看文件内容过程中可以用光标上下移动来查看文件内容,应使用命令。(10分…...
QT QDialog 中的按钮,如何按下后触发 accepted 消息?
QT 作为跨平台的系统,对话框并没有采用 Windows API 那种模式,通过返回 mrOK、mrCancel 等结果告诉调用方结果,而是采用了 accepted、rejected 等信号确定执行结果。下面介绍几种出发这些信号的方法。 1. 在按钮的 clicked 槽函数中触发 acc…...
seata分布式事务
文章目录 1、分布式事务1.1 事务的ACID原则原子性一致性隔离性持久性 1.2 分布式事务的问题示例代码准备环境1. seata_demo数据库2. 启动nacos seata-demo父工程pom.xml order-servicepom.xmlapplication.ymlOrderApplicationOrderControllerOrderServiceImplAccountClientStor…...
Python HttpServer 之 简单快速搭建本地服务器,并且使用 requests 测试访问下载服务器文件
Python HttpServer 之 搭建本地服务器,并且使用requests访问下载服务器文件测试 目录 Python HttpServer 之 搭建本地服务器,并且使用requests访问下载服务器文件测试...
【Python 实战】---- 实现批量给 pdf 插入 excel 动态生成的印章
1. 需求 想要能否实现批量自动为多个pdf加盖不同六格虚拟章(不改变pdf原有分辨率和文字可识别性);改在pdf首页上方空白位置,一般居中即可;如可由使用者自主选择靠页边距更好,以便部分首页上方有字的文件时人工可微调位置;从上而下,自左往右分别对应 excel 中各个字段;…...
51单片机实验课二
实验任务一: 用C语言设计实现8个led灯左右移动显示效果。具体要求如下: 左移时,8个灯中的奇数位灯依次点亮; 右移时,8个灯中的偶数灯依次点亮; 如此循环往 #include <REGX52.H> void Delay(unsi…...
1-4 动手学深度学习v2-线性回归的简洁实现-笔记
通过使用深度学习框架来简洁地实现 线性回归模型 生成数据集 import numpy as np import torch from torch.utils import data # 从torch.utils中引入一些处理数据的模块 from d2l import torch as d2ltrue_w torch.tensor([2,-3.4]) true_b 4.2 features, labels d2l.syn…...
SQL如何实现数据表行转列、列转行?
SQL行转列、列转行可以帮助我们更方便地处理数据,生成需要的报表和结果集。本文将介绍在SQL中如何实现数据表地行转列、列转行操作,以及实际应用示例。 这里通过表下面三张表进行举例 SQL创建数据库和数据表 数据表示例数据分别如下: data_…...
【React】redux状态管理、react-redux状态管理高级封装模块化
【React】react组件传参、redux状态管理 一、redux全局状态管理1、redux概述2、redux的组成1.1 State-状态1.2 Action-事件1.3 Reducer1.4 Store 3、redux入门案例1.1 前期准备1.2 构建store1.2.1 在src下新建store文件夹1.2.2 在store文件夹下新建index.ts文件1.2.3 在index.t…...
HAProxy 和负载均衡概念简介
简介 HAProxy,全称高可用代理,是一款流行的开源软件 TCP/HTTP 负载均衡器和代理解决方案,可在 Linux、macOS 和 FreeBSD 上运行。它最常见的用途是通过将工作负载分布到多台服务器(例如 Web、应用程序、数据库)上来提…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
