关于Redis出现“java.io.IOException: 远程主机强迫关闭了一个现有的连接”的一次排查
背景
最近在使用springboot(Windows下)连接redis(云服务器)开发时发现一些问题:连接成功的情况下,在一段时间未交互数据后,再次通过连接与Redis传输数据回出现异常java.io.IOException: 远程主机强迫关闭了一个现有的连接。
于是我上网找了一些博客主要是两种:
- 可能是客户端连接太多了,开启timeout设置或tcp-keepalive
- 将配置的的tcp-keepalive设置为60(可能之前是300)
这两个设置是什么意思呢
- timeout,单位是秒,如果客户端连接空闲时间达到这个时间,就释放掉这个连接
- tcp-keepalive,单位是秒,空闲时间达到这个时间就发送一个tcp-keepalive心跳包,用于检测客户端(在这里就是我的springboot程序)是否在线
探索
为了弄清楚原因,我开始对Linux用tcpdump抓包,在Windows下用wireshark抓包分析,发现一些问题
我的设置是
tcp-keepalive 300
,在到达300s后,Linux的tcpdump抓到redis发送了心跳包,但是并未得到客户端回应,Windows的wireshark也没有抓到有收到redis的心跳包此后,redis每100秒重发一次心跳包,直到600秒发送rst,释放了tcp连接,而Windows还是无感知,连接状态是establish,因此,第10分钟(600秒)后,客户端用原来的连接与Linux的redis通信,不会得到ack回应,于是不断重发,直到超出阈值,springboot出现
远程主机关闭连接的异常
,然后重新进行三次握手重建连接并非要到10分钟连接才会失效,据我的测试,在
240s
后,Windows的springboot尝试通过连接与Linux的redis通信,但是发送不会得到ack,于是重发,直到超过阈值释放,重新三次握手。
此时,springboot不会出现刚刚那个异常
,但是是打印如下日志:
此时,Linux端还保留原来的连接,直到10分钟后(就像上面那样)。
如果使用本地Windows的redis服务器,即使tcp-keepalive是300,redis在300s发送的心跳包就能被wireshark抓到,并且得到回应,保持连接,也就是表现正常。
由上面几点分析,可以认为两端的tcp通信受到阻碍。240s后,无论是Linux通过tcp连接给本地Windows发(tcp-keepalive),还是Windows给Linux发,都是无法得到回应。并且是Linux和本地的开发机之间才会出现,在一段时间不通信后,tcp连接就失效了。
推测原因
为了检验这个是底层tcp出现了问题,于是使用golang写了个小程序,连接后不发心跳包,等到250s后发送消息。
测试结果结果是:同样出现了发送数据未得到ack,重试几次后释放,tcpdump也没抓到对应数据。也就是我这边发的数据那边根本就没收到。
由于这个时间比较固定,在我的环境中,240秒后连接就失效了,我推测是某些地方设置了过期时间,再由同一个本地环境中的redis和springboot表现正常,我的推测是这可能是NAT(网络地址转换协议)的会话过期导致的
这个协议的作用是在本地多个设备使用同一个公网IP的情况下,通过一些配置路由到对应的子网设备。
解决
在我这里,只要把tcp-keepalive
设置为240秒以下就好了
结束
推测的原因没有亲自去证实,希望有大佬能够证实或指出错误。
关于Redis出现“java.io.IOException: 远程主机强迫关闭了一个现有的连接”的一次排查相关推荐
- SpringBoot整合Redis:java.io.IOException: 远程主机强迫关闭了一个现有的连接。或者控制台报连接超时异常
场景: 项目启动过后 Redis 连接过一会就会断开,报如下问题: 问题1: 2022-12-05 23:05:18.287 ERROR 10752 --- [sson-netty-1-11] o.r ...
- java.io.IOException: 远程主机强迫关闭了一个现有的连接。
参考文档: (2条消息) 解决redis中java.io.IOException: 远程主机强迫关闭了一个现有的连接_zeal9s的博客-CSDN博客_redis远程主机强迫关闭了一个现有连接怎么解决 ...
- java.io.IOException: 远程主机强迫关闭了一个现有的连接
摆脱烦恼最有效的是慢思考,为什么和我想的不一样,出入在哪里,什么导致的? 疑惑 我使用netty框架接受数据,每隔半个小时存储数据,运行不到三个小时报错 java.io.IOException: 远程 ...
- java强制关闭远程桌面_elasticsearch中的java.io.IOException: 远程主机强迫关闭了一个现有的连接...
[2018-07-31T14:29:41,289][WARN ][o.e.x.s.t.n.SecurityNetty4HttpServerTransport] [9rTGh-y] caught exc ...
- java nio 强制关闭_Java NIO服务器:远程主机强迫关闭了一个现有的连接
Java NIO聊天室 中,若客户端强制关闭,服务器会报"java.io.IOException: 远程主机强迫关闭了一个现有的连接.",并且服务器会在报错后停止运行,错误的意思就 ...
- 远程计算机强迫关闭一个连接,远程主机强迫关闭了一个现有的连接。
org.apache.catalina.connector.ClientAbortException: java.io.IOException: 远程主机强迫关闭了一个现有的连接. at org.ap ...
- es远程主机强迫关闭了一个现有的连接
Caused by: java.io.IOException: 远程主机强迫关闭了一个现有的连接. at sun.nio.ch.SocketDispatcher.read0(Native Me ...
- netty 远程主机强迫关闭了一个现有的连接。
如果你的netty报这个错误 java.io.IOException: 远程主机强迫关闭了一个现有的连接. 或者 System.Net.Sockets.SocketException (0x80004 ...
- 循环报错: 远程主机强迫关闭了一个现有的连接
客户端终止后,服务端一直循环 报java.io.IOException: 远程主机强迫关闭了一个现有的连接. 原始代码 private void read(SocketChannel channel, ...
最新文章
- 用 PHPMailer 发送邮件
- css3 选择器_CSS 3
- 搜狐视频怎么开启自动连播
- spark的异步消息总线LiveListenBus
- python怎么做软件程序_Revit二次开发python怎么做?人工智能python语言在BIM软件高效建模的运用尝试...
- 用vb写计算机程序代码,用VB编写的抽奖程序源代码随机抽取不重复
- 使用JavaScript在页面打印系统当前时间
- 静态网站生成器(开源项目)
- Matlab中max函数详解
- 一行代码教你屏蔽你的博客广告
- 史上最简单的word文档docx文档解密方法,忘记word文档docx密码怎么办?
- Manjaro-architect 安装指南
- 两个程序员老友的会面
- 算法之美_源码公布(1)
- DBeaver解决连接Oracle之后出现库名为数字问题
- 我的十一Win10之旅
- MATLAB消除图像白边
- 优恩解答GDT放电管是怎么工作的
- 全网最快的M1 MacBook Air详细测评
- java毕业生设计医院门诊分诊系统计算机源码+系统+mysql+调试部署+lw