当前位置: 首页 > news >正文

使用Netty,当然也要了解它的连接闲置处理

连接闲置

网络连接的闲置指的是当前网络连接处于空闲状态,即没有正在进行的数据传输或通信活动。当我们的某个连接不再发送请求或者接收响应的时候,这个连接就开始处于闲置状态。

网络连接的闲置时间越长,说明该连接越不活跃。此时,可以根据不同的场景,采取不同行为,比如:

  • 关闭连接

  • 发送心跳,长连接场景下要求定时发送心跳保持连接状态或者是探活

Netty连接闲置handler

Netty默认提供了io.netty.handler.timeout.IdleStateHandler管理连接闲置事件,它可以检测连接空闲时间,当连接在指定时间内没有读或者写操作时,就会触发一个IdleStateEvent事件:

IdleStateHandler主要提供有三个参数,设置为0表示禁用:

  1. readerIdleTimeSeconds:读空闲时间,即当服务器指定时间没有数据读取,会触发一个读闲置事件。

  1. writerIdleTimeSeconds:写空闲时间,即当服务器指定时间没有数据发送(或写入动作,参数不同阶段不一样),会触发一个写闲置事件。

  1. allIdleTimeSeconds:读/写空闲时间,客户端连接在指定时间内没有读/写操作时,就会触发一个IdleStateEvent的All事件。

    public IdleStateHandler(int readerIdleTimeSeconds,int writerIdleTimeSeconds,int allIdleTimeSeconds) {this(readerIdleTimeSeconds, writerIdleTimeSeconds, allIdleTimeSeconds,TimeUnit.SECONDS);}

读闲置

Netty的ReadTimeoutHandler是一个针对读闲置处理的handler,用于处理读取超时事件。当客户端或服务器在指定时间内没有收到数据时,这个类会触发一个读取超时事件。

在Netty中,使用IdleStateHandler来管理读取超时和写入超时。ReadTimeoutHandler继承了IdleStateHandler,并在其基础上实现了定制化的读取超时功能。当读取超时发生时,ReadTimeoutHandler会调用其channelRead方法,其中实现了具体的读取超时逻辑。

ReadTimeoutHandler在达到闲置时间的时候会抛出一个读超时异常,并关闭连接:

    protected void readTimedOut(ChannelHandlerContext ctx) throws Exception {if (!closed) {ctx.fireExceptionCaught(ReadTimeoutException.INSTANCE);ctx.close();closed = true;}}

我一般把ReadTimeoutHandler用在服务端,当某个客户端的连接闲置太长时间就关闭这个客户端的连接,释放资源。

一般情况下IdleStateHandler都是作为ChannelPipeline中的第一个Handler,用于处理连接的心跳检测。当连接超时时会触发IdleStateEvent事件,然后交给下一个handler处理该事件,所以ReadTimeoutHandler也是这样,示例如下:

    @Overridepublic void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new ReadTimeoutHandler(READ_TIMEOUT_SECONDS));pipeline.addLast(new ServerHandler());}

写闲置

写闲置我一般用在客户端,比如达到闲置时间关闭与服务端的连接或者发送心跳给服务端以保持长连接。

写闲置则关闭示例如下:

public class ClientIdleHandler extends IdleStateHandler {private static final long IDLE_TIMEOUT = 30000;public ClientIdleHandler() {super(true, 0, IDLE_TIMEOUT, 0, TimeUnit.MILLISECONDS);}@Overrideprotected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {if (evt == IdleStateEvent.FIRST_WRITER_IDLE_STATE_EVENT) {// 连接闲置,关闭连接ctx.close();}}
}

或者也可以不关闭,发送一个心跳包,但是要注意,这种情况,客户端的闲置时间要少于服务端的。

我们也可以增加一个定时任务来发送心跳包:

    // 重写handlerAdded方法,添加一个定时任务@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {ctx.executor().scheduleAtFixedRate(() -> {// 判断连接是否处于活动状态if (ctx.channel().isActive()) { // 发送心跳包ctx.writeAndFlush(new Heartbeat()); }}, 0, idleTimeSeconds, TimeUnit.SECONDS);}

读写闲置

上面的读闲置时间和写闲置时间都达到了才触发,两者取最大值:

            long nextDelay = allIdleTimeNanos;if (!reading) {nextDelay -= ticksInNanos() - Math.max(lastReadTime, lastWriteTime);}

写意图

    public IdleStateHandler(boolean observeOutput,long readerIdleTime, long writerIdleTime, long allIdleTime,TimeUnit unit) 

在评估写闲置的时候还有一个参数:observeOutput。

非写闲置判定的时候,是以数据发送出去为准,还是有写的动作为准,默认该值是false,数据发送判定为写闲置,而设置为true就是写动作发生时,比如写入缓存但是还没发送就是非闲置。

依据观测当前缓存的数据变化情况和进度来判断。如下,和上次进行比对:

            if (buf != null) {int messageHashCode = System.identityHashCode(buf.current());long pendingWriteBytes = buf.totalPendingWriteBytes();if (messageHashCode != lastMessageHashCode || pendingWriteBytes != lastPendingWriteBytes) {lastMessageHashCode = messageHashCode;lastPendingWriteBytes = pendingWriteBytes;if (!first) {return true;}}long flushProgress = buf.currentProgress();if (flushProgress != lastFlushProgress) {lastFlushProgress = flushProgress;if (!first) {return true;}}}}

误区

Netty提供了读闲置处理的ReadTimeoutHandler,是不是提供的也有写闲置的WriteTimeoutHandler。

明确说明:没有写闲置的WriteTimeoutHandler,但确实存在WriteTimeoutHandler,该hander表示的是写数据动作的超时handler,却不是表示连接写闲置的handler,当在指定时间内数据没写完,会抛出一个写超时异常,可以看下源码:

        public void run() {// Was not written yet so issue a write timeout// The promise itself will be failed with a ClosedChannelException once the close() was issued// See https://github.com/netty/netty/issues/2159if (!promise.isDone()) {try {writeTimedOut(ctx);} catch (Throwable t) {ctx.fireExceptionCaught(t);}}removeWriteTimeoutTask(this);}protected void writeTimedOut(ChannelHandlerContext ctx) throws Exception {if (!closed) {ctx.fireExceptionCaught(WriteTimeoutException.INSTANCE);ctx.close();closed = true;}}

相关文章:

使用Netty,当然也要了解它的连接闲置处理

连接闲置网络连接的闲置指的是当前网络连接处于空闲状态,即没有正在进行的数据传输或通信活动。当我们的某个连接不再发送请求或者接收响应的时候,这个连接就开始处于闲置状态。网络连接的闲置时间越长,说明该连接越不活跃。此时,…...

2、K-Planes

运行配置 主页:https://sarafridov.github.io/K-Planes/ 代码:https://github.com/sarafridov/K-Planes 预训练权重:https://drive.google.com/drive/folders/1zs_folzaCdv88y065wc6365uSRfsqITH Neural_3D_Video_Dataset:htt…...

张文海教授课题组在国际高水平期刊《Cerebral Cortex》发表研究成果

调节悲伤情绪对于维持伴侣间的浪漫关系至关重要。人际情绪调节策略包括情感参与(AE)和认知参与(CE),这两种策略在浪漫关系中效用如何?它们是如何通过情感纽带调节伴侣情绪的?其背后的脑际神经互…...

ffmpeg4.1 源码学习之-转封装

前言 ffmpeg 的源码量非常的多,而且非常繁杂,非常多的函数,如果一个函数一个函数看的话要花费比较多的时间。所以本文通过跟踪ffmpeg转封装的过程来学习ffmpeg的源码具体转封装的命令:ffmpeg -i 1_cut.flv -c copy -f mp4 1.mp4在…...

ChatGPT写作文章-快速使用ChatGPT不用注册方式

如何更好地使用ChatGPT批量生成文章:详细教程 作为一款强大的文本生成器,ChatGPT可以帮助您快速、高效地批量生成文章。但如果您还不知道如何更好地使用ChatGPT,那么这篇详细的列表教程将会指导您如何使用它来生成高质量的文章,提…...

Nginx配置ip白名单(服务权限控制)

Nginx服务器权限控制:Nginx 是一款高性能的 HTTP 和反向代理服务器。它可以通过配置文件实现权限控制,从而限制或允许特定的 IP 地址、网络或用户访问指定的资源。这里是一些基本的 Nginx 权限控制方法: 1. 基于 IP 地址的访问控制 在 Ngin…...

Vue 核心(二)

文章目录Vue 核心(二)八、 绑定样式1、 class2、 style九、 条件渲染1、 渲染指令2、 使用示例十、 列表渲染1、 基本语法2、 key原理3、 列表过滤4、 列表排序5、 数组更新检测6、 大总结十一、 收集表单数据十二、 内置指令1、 v-text2、 v-html3、 v-…...

犯罪现场还原虚拟vr训练平台突破各种教学限制

在当今社会矛盾日益凸显、各式犯罪层出不穷的背景下,创新改革公安院校实战化教学方式,强化对基层公安队伍实战化应用型人才的供给能力具有重要性、紧迫性。 案件现场勘查是门技术活,如何让民警快速有效提升技能、服务实战? 常规刑侦专业现场…...

LeetCode 617. 合并二叉树 | C++语言版

LeetCode 617. 合并二叉树 | C语言版LeetCode 617. 合并二叉树题目描述解题思路思路一:使用递归代码实现运行结果参考文章:思路二:减少遍历节点数代码实现运行结果参考文章:LeetCode 617. 合并二叉树 题目描述 题目地址&#xf…...

Python量化交易08——利用Tushare获取日K数据

总有同学问我要数据...很多第三方接口都能直接获取数据的,本次介绍怎么用Tushare库获取A股日k线行情的数据。 Tushare有两个版本,老版现在快弃用了。 新版的官网链接在这:Tushare数据 需要注册一个账号,然后改一下资料&#xff0…...

30张精美可视化大屏,无需代码直接套用,解决你95%的大屏需求!

通常制作可视化大屏,一般有两种方式 代码开发:写代码调用数据和图表库,比如写JSEcharts ; 可视化工具:用现成的数据可视化工具 前者简单直接,直接写代码就完事。但对于大部分人来说门槛较高,维…...

TCP网络事件模型的封装1.0

TCP网络模型的封装 最近学习了TCP网络模型的封装,其中运用的封装技术个人感觉有点绕 在反复读代码、做思维导图下初步理解了这套封装模型,不禁感叹原来代码还能这样写?神奇! 为此将源码分享出来并将流程图画出,方便…...

NC271.二叉搜索树的后序遍历序列

文章目录一、题目描述二、示例三、主要思路一、题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回 true ,否则返回 false 。假设输入的数组的任意两个数字都互不相同。 提示: 1.二叉搜索树是指父亲节点大于左子树中…...

研究fastdds v2.8.0 1之 基础模块

阅读 dds 协议 1.4 版本 , 结合fastdds 2.8 的代码理解dds。 Entity 理解 DCPS基础设施模块由以下类组成: Entity DomainEntity QosPolicy Listener Status WaitSet Condition GuardCondition StatusCondition1、Entity 是所有DCPS 对象的基础类 virt…...

ElasticSearch系列 - SpringBoot整合ES:精确值查询 term

文章目录01. ElasticSearch term 查询?02. ElasticSearch term 查询数值型数据?03. ElasticSearch term 查询字符串类型数据?04. ElasticSearch term 查询日期型数据?05. ElasticSearch term 查询日期型数据的注意事项&#xff1f…...

关于async/await、promise和setTimeout执行顺序

关于async/await、promise和setTimeout执行顺序 async function async1() {console.log(async1 start);await async2();console.log(asnyc1 end); } async function async2() {console.log(async2); } console.log(script start); setTimeout(() > {console.log(setTimeOut…...

2023-03-31:如何计算字符串中不同的非空回文子序列个数?

2023-03-31:给定一个字符串 s,返回 s 中不同的非空 回文子序列 个数, 通过从 s 中删除 0 个或多个字符来获得子序列。 如果一个字符序列与它反转后的字符序列一致,那么它是 回文字符序列。 如果有某个 i , 满足 ai ! bi &#xff…...

D. The Number of Imposters(二分图染色)

Problem - D - Codeforces Theofanis开始玩名为“Among them”的新网络游戏。然而,他总是和塞浦路斯球员一起踢球,他们都有一个相同的名字:“安德烈亚斯”(塞浦路斯最常见的名字)。在每个游戏中,Theofanis和n个其他玩家一起玩。因为它们都有相…...

图片太大怎么改小kb?简单的图片压缩方法分享

平时当我们在朋友圈分享一些有趣的照片或者使用图片素材进行上传的时候,经常遇到图片大小kb超出平台限制的情况,这时就无法正常上传了,遇到这种情况我们就需要想办法降低图片大小kb,那么有什么办法能够压缩图片大小呢?…...

【python-leecode刷题】动态规划类问题----以53. 最大子数组和为例

作者:20岁爱吃必胜客(坤制作人),近十年开发经验, 跨域学习者,目前于海外某世界知名高校就读计算机相关专业。荣誉:阿里云博客专家认证、腾讯开发者社区优质创作者,在CTF省赛校赛多次取得好成绩。…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...