netty keepalive 和 idle 的关系
实际应用中:结合起来使用,按需keepalive,保证不空闲,如果空闲,关闭链接。
netty keepalive 和 idle 的三角关系?
keepalive 就是类似于心跳时间,通俗点来说就是看看对方有没有彻底凉了。
Linux Kernel有三个选项影响到KeepAlive的行为:
1 tcp_keepalive_time 7200 // 距离上次传送数据多少时间未收到新报文判断为开始检测,单位秒,默认7200s(没必要频繁,浪费资源)。
2 tcp_keepalive_intvl 75// 检测开始每多少时间发送心跳包,单位秒,默认75s。
3 tcp_keepalive_probes 9// 发送几次心跳包对方未响应则close连接,默认9次。
整体上的判断需要小心,不能因为它可能中途凉了几下就认为它已经死掉了。
注意缺点是
1 keepalive只能检测连接是否存活(对面只要回复就认为是正常的),不能检测连接是否可用(比如死锁中还认为是能用的)。
2 下面会说到解决方案以及一些可以让tcp keep-alive失效的东西(如代理(socks proxy之类的)、负载均衡器)。
在应用层用keepalive的原因
1.tcp层关注的是有没有活着,应用层关注的是能不能用。
2.tcp默认是关的,而且在传输途中可能没了,所以应用层再做一层保险。
3.tcp的参数是系统参数,如果是自己的应用在用就没事。如果别人也在用,你改了他也要变,就变化很大了。。。不过这关应用层用keepalive什么事情?难道是自己可以在应用层再设置一遍?
提示:Http属于应用层协议,但是常常听到名词“HTTP keep-Alive”,值得是对长连街 和 短连街的选择:
Connection:keep-Alive 长连接(HTTP/1.1 M默认长链接,不需要带着个header)
Connection:Close 短连接
tcp的keepalive 和 http的 keep-alive看清楚了,中间有个杠。
tcp的keepalive是在ESTABLISH状态的时候,双方如何检测连接的可用行。
而http的keep-alive说的是如何避免进行重复的TCP三次握手和四次挥手的环节(选择长连接还是短的)。
Http1.1默认是长连接
直接关闭连接
1 快速释放的,恶意的,很久不用的连接,让系统时刻保持最好的状态。
2 简单粗暴,客户端可能需要重连。
实际应用中:结合起来使用。按需keepalive,保证不会空闲,如果空闲,关闭连接。
长连接:指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包。
短连接:指通讯双方有数据交互时,就建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。
问题:http 长连接 http短连接 区别在哪里 还有tcp这个连接 ?
回复: 一个永远牵着手,一个一会牵手一会断。http是基于tcp的,http的长连接是说它下面用的tcp连接一直连着,所有请求都复用这个传输通道,而http短连接,就是比如一个请求就建一个tcp连接,处理完就断了。实际上,一般我们现在经常用的是比如保持几分钟的长连接。
记住:这三个东西是三个不同的东西。是独立的。
首先,老习惯,先来点毒鸡汤,知识,热热身。
什么是 keepalive?
什么是keepalive,维基百科
http的keepalive和TCP keepalive是两回事
为什么还需要应用层keepalive?
1 协议分层,各个层关注点不同; 传输层关注的是否“通”,应用层关注是否可以服务?类比前面的电话订餐例子,电话能通,不代表有人接;服务器连接在,但是不一定可以服务(例如服务不过来等)。
2 TCP层的keepalive默认关闭,并且经过路由等中转设备keepalive包可能会被丢弃
3 TCP层的keepalive时间太长:默认>7200秒 +75秒 * 9 , 尽管可以修改,但是属于系统参数,改动影响所有应用.
问题:那http默认的keep-alive是用TCP的keepalive的方式链接的吗
问题:rocktmq有没有办法去监控服务是不是挂了呢。跟这种模式是一样么,怎么借鉴呢?
回复: 这是两个不同的事情,因为一个服务不做keepalive和idle监控也能工作(或许会偶尔失败),但是监控还是需要做的,比如停电了。但是就像你用的词“借鉴”一样,思想倒是可以借鉴,在做监控的时候,你要划分下多个层次,比如机器的进程在不在,机器本身资源使用率,服务质量三个层次,Java的可以打开jmx做监控,然后监控的方式上,可以调用它提供的api或者自己写一个轻量级的任务定时去测试下,类似keepalive了:定时,轻量级。
什么是 idle ?
idle检测:就是看对方有没有反应。作用是省的你每次都去问人家。
idle:就是对方不回复你,对方就是idle状态
去询问的动作叫keepalive
idle监测是什么?
重现生活场景:
1 假设你开了一个饭店,别人电话来订餐,电话通了后,订餐的说了一堆要求,说着说着,对方就不说话了。
2 你会立马发问:你还在么?
肯定是不会的。一般正常人的话,你都会稍微等待一定的时间,一小会,在这个时间内看看对方还会不会说话(idle监测)如果还不说,认定对方存在问题(idle),于是开始发问“你还在么”(keepalive),或者问都不问干脆直接挂机(关闭连接)。
keepalive 与 idle 的 关系 ?
idle监控,只是负责诊断,诊断后,做出不同的行为,决定idle监测的最终用途:
发送keepalive:一般用来配合keepalive,减少keepalive消息。
keepalive设计演进:
v1定时keepalive消息 -> V2空闲监测 + idle时才发 keepalive
v1:keepalive消息与服务器正常消息交换完全不关联,定时就发送;
v2:有其他数据传输的时候,不发送keepalive,
无数据传输超过一定时间,判定为idle,再发keepalive。
知识运用: Netty 如何使用 keepalive 与 idle ?
问题:如何Netty开启keepalive
可以在创建ServerBootstrap的group后通过额外参数(childOption)来指定开启
开启idle检测可以在handler下的初始化Channel那里开启,记得那个addlast不,就是加在这个里面。
问题:一般Http的keep-alive是有客户端(即浏览器)发起web请求的时候带在Header里的,所以idleHandler的方法是不是netty作为httpclient端的时候才需要写的?
回复: 不是的,所有服务器开发最好都有,因为最简单的,你服务器,别人连上来不做事怎么办,肯定要自我保护下,http只是一种基于tcp的服务器。
问题:应用层的keeplive 就是心跳机制吧?
回复: 不管哪层的keepalive都算心跳,差不多一个意思,只是心跳的层次不同。
问题:设置keepalive参数的流程:有个用于接收连接的后续处理ServerBootstrapAcceptor,把选项设置到消息里面去(不同的io实现不同)
问题:开启keepalive的 NioChannelOption和普通的ChannelOption的区别
NioChannelOption会优先根据jdk版本是否大于7和请求是否为NioChannelOption,如果是的话就通过NioChannelOption.setOption来设置(调用jdk的设置方法,当然,其中也包括规避jdk的一些bug版本来用自己的,这个也对应了开始章节讲的:netty的思想是解决不了的就绕过),不是的话就通过父类老方法来set(要一个一个的if else你的入参是什么类型的)
idle检测
idle有三个状态:没有数据收(READER_IDLE),没有数据发送(WRTIER_IDLE),收和发都没有(ALL_IDLE)。总之跟idle状态相关的(比如event、handle) 一定有这三个状态,只是具体的类型不同
关于idle事件的状态,又根据这个状态是否为第一次来把上面的三个状态分成6个,是第一次的话就在名字前面加个FIREST_,不是就不加
idle检测核心是触发event 是通过定时任务轮询看是否有空闲并且写ing或者成功(会跟踪这个进度,通过比较哈希以及上一次待发送字节数是否不等于这次的字节数),不是idle话就再建一个定时任务
问题:请教一下 option 和 childOption 设置的参数有何不同呢?
回复: option和childoption是设置不同socket channel的,分别服务于ServerSocketChannel和SocketChannel。
之所以用了child前缀作为区分,是因为服务的channel有父子关系(前者产生后者: SocketChannel = serverSocketChannel.accept();)。
他们都在channel初始化时使用,具体而言。前者是在启动服务时,后者是在创建连接时,但是这里有个问题是,就是可以设置的option是共享的,这就导致,一些参数(例如io.netty.channel.ChannelOption#SO_BACKLOG,
)仅仅对serversocketchannel有效,但是可能会不小心设置给socketchannel。例如本应该是.option(ChannelOption.SO_BACKLOG, 100),却不小心写成了.childOption(ChannelOption.SO_BACKLOG, 100),这样的话,会发生什么?实际上并没有报错,只是后期使用时,可能无法生效,可以说是一个隐蔽的坑。这里要注意下。
所以你的问题,总结下就是:设置的参数服务目标不同,且应该根据不同的目标选择参数,当然这些参数有一些是都可以设置的,有一些却是专有的。
问题:有个疑问请教下,如下:
一、netty使用IdleStateHandler类做idle监测
1、对于读idle监测,IdleStateHandler的子类ReadTimeoutHandler会触发ReadTimeoutException异常,自定义的handler感知到这个异常可以做一些处理操作。
2、对于写idle监测,
a、如果observeOutput为false, 只有写入缓冲区成功 才算有写操作。
b、如果observeOutput为true,只要有写的意图 就算 有写操作,写意图包括:①写了,但缓冲区满了,没写成功 ②写了一个大数据,写确实在动,但没有完成。
这里些疑问:
如果有个场景:调用write方法写入了一个4个G的文件(一时半会写不完,假如每次只能写1k到缓冲区)
问题一:这对应的是b.②情况么?
问题二:如果observeOutput为false, 是要把4G都写入完缓冲区才算有写操作?
我先说下我的理解:
问题一:不知道
问题二:
1、如果observeOutput为false,虽然发送的是4个G数据,只要有n字节(n>0)写入成功 都算有写操作.
2、如果发送的是4个G的数据,判断在一段时间内有没有全部把4G写完,是WriteTimeoutHandler干的事情。
回复: 问题1:对的;问题2:也对,但是问题2的(1)你写反了吧?observeOutput = true。这里补充说下,这么大的文件,应该用chunk的方式那写了,否则容易OOM的。
问题:两点问题请教一下
1.如果想idle和keepalive配合使用,是否是需要在处理idle事件时进行编码,向客服端去发送对应的keepalive请求?
2.客户端是否要对我发送的keepalive请求进行回复,没有回复是否视为连接失效,直接断开?(此处服务端和客户端是否都要进行相应的编码?)
回复: 配合方式有很多种,你这种是可以的,而且很多也这么做,然后不管哪种,只要收发消息都需要编解码,所以才是统一的(不然不就不是消息的一种了么?),你在案例中可能没有看到显示编解码,而是直接写出了消息。那是因为这个写的过程经过了之前写的二对编解码器了,所以都会做的,也应该做的。
**问题:**我有一点不明白;keepalive其实本质也是用来检测链路是否正常,而idle检测看起来也是用来检测链路是否正常;tcp的keepalive是在7200s之后如果没有数据就进行发送,那会不会在之前idle就已经被触发然后断掉连接呢? 这块没怎么搞明白?
回复: 会的,如果你设置idle监测的时间低于你的keepalive时间,然后没数据,就会监测到空闲后就关闭连接,就是你说的情况,所以一般把空闲监测的时间设置的比keepalive大,这样就好了。当然这里说的都是应用层keepalive.你说的那个tcp层的keepalive对应用层的idle监测并没用,idle监测是应用层在做,它看的是应用层有没有数据,而不是tcp层的,另外idle监测主要是保护系统的,优化系统的,所以连接正常也可能触发的。
问题:不是说tcp keepalive不好吗,怎么netty不在应用层用keepalive
回复: 因为应用层的keeplive属于应用层,而且每个协议,除了那些流行的外,大多是我们自己的内部写的应用,都不同,所以他不知道我们怎么定义我们的keepalive,所以他不好提供通用的实现什么的,所以我们自己要去实现keepalive.
问题:keepalive发送的是什么数据来探测的,需要对端做处理吗?
回复: 一般就特别简单的数据。比如ping pong字符这种都可以,原则就是简单数据量小。对端一般都要处理下,但比如只想服务器看看有没有请求过来,不考虑客户端,那也可以不处理,但是作为完整性,最好还是要处理的,这样所有消息定义都是一来一回清晰。
问题:idlestate 那里的all 我看注释写的是either or 这个的意思不是或者。。或者。。么,意思是写idle或者读idle,如果是并且的关系应该是用neither nor呀。
回复: 但是原文前面是no data.意思没有读,也没有写,用你说的表达肯定也行,就要换句表达了,二个本质都是一个意思,类似 双重否定等于肯定。
netty keepalive 和 idle 的关系相关推荐
- Netty如何实现 keepalive和idle监测
1 为什么需要keepalive ? 类比如下场景 2 怎么设计keepalive 以TCP keepalive为例 TCP keepalive 核心参数: # sysctl -algrep tcp_ ...
- Netty之Channel的继承关系
我们学习的顺序将是从下往上进行!
- Netty 学习笔记(已完结)
Netty 0代码示例 A.经典IO多线程 // 获取到的inputStream是SocketInputStream,这个类不是公开的,继承了FileInputStream, InputStream ...
- BGP状态机及其总结
成功是留给有准备的人. 文章目录 一.拓扑 二.基础配置 三.BGP状态停留测试 四.总结 4.1 BGP5种报文类型 4.2 BGP状态机 4.3 BGP邻居的建立 4.4 BGP邻居关系建立 4. ...
- CCNP基础知识-路由(二)
重发布 重发布定义 在本路由器上,要将A协议重发布给B,需要在B路由器上实施,将通过A协议学习并加表的路由以及本路由器上通告进入A协议的接口路由重发布进入B协议. 在重发布时会产生一个seed-met ...
- 华为HCIP-RS 数通笔记
2021.6.20 ospf dis ip int bri 查看接口状态 dis ospf int 查看哪些接口有ospf配置 dis ospf peer bri ...
- 大数据全体系年终总结
到年底了,想着总结下所有知识点好了~今年应用的知识点还是很多的~ Hadoop生态圈: 1.文件存储当然是选择Hadoop的分布式文件系统HDFS,当然因为硬件的告诉发展,已经出现了内存分布式系统Ta ...
- Netty--Future和Promise
目录 概述 JDK.Future Netty.Future ChannelFuture Promise 继承关系 源码分析 AbstractFuture CompleteFuture DefaultP ...
- 净资产滚动率_净资产的结构
净资产滚动率 Netty的包装结构很棒. 每个程序员都应该研究它. 每个系统都应该模仿它: 每个项目经理都应将其打印出来,拍在墙上,然后对开发人员说:"那样." Netty是一个& ...
最新文章
- 小程序动态class_微盛小程序“圈子动态”来了!仿朋友圈发布动态,引流拓客神器...
- 可伸缩性架构常用技术——之数据切分
- 达摩院副院长金榕:中国 AI 将向何处?热潮有回落,但不应沮丧
- java 之 语言基础
- 浅析网站页面加载速度如何提升?
- Elicpse创建Maven项目
- c++ 4.变量名规则
- leetcode 41. First Missing Positive 1
- 深入理解.NET Core的基元(三) - 深入理解runtimeconfig.json
- 百度在线解析站不限速下载
- mysql去重操作哪个最快_如何将 MySQL 去重操作优化到极致?| CSDN 博文精选
- 比量iOS6/iOS7, 3.5inch/4.0inch
- 股票卖出以后可以立即把钱转出吗?
- android okhttp+解析json( okhttp 工具类)
- Android 代码中执行adb shell命令
- 借助C++类结构计算矩形面积(矩形类)
- UE4 四叉树 QuadTree
- 就让这大雨全都落下 - 容祖儿
- Excel如何将符合要求的所有数据全部查找出来
- 模糊图像的倒谱matlab,基于倒谱分析方法的离焦模糊图像特征鉴别
热门文章
- SpringBoot之获取配置文件中的数据
- Maven生命周期和插件的那些事(2021版)
- DDGScreenShot —图片加各种滤镜高逼格操作
- 超详细动手搭建一个 VuePress 站点及开启 PWA 与自动部署
- 《HTML5与CSS3实战指南》——第2章 HTML5样式的标记2.1 The HTML5 Herald简介
- 《HTML5 2D游戏编程核心技术》——第2章,第2.3节使用CSS背景
- nginx 后端获取真实ip
- 免费mac虚拟机下载 快速安装win系统
- AXFR和IXFR区域传输及原理
- [译]用Visual Studio2012来开发SQL Server 2012商业智能项目