背景

最近在使用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: 远程主机强迫关闭了一个现有的连接”的一次排查相关推荐

  1. SpringBoot整合Redis:java.io.IOException: 远程主机强迫关闭了一个现有的连接。或者控制台报连接超时异常

    场景: 项目启动过后 Redis 连接过一会就会断开,报如下问题: 问题1: 2022-12-05 23:05:18.287 ERROR 10752 --- [sson-netty-1-11] o.r ...

  2. java.io.IOException: 远程主机强迫关闭了一个现有的连接。

    参考文档: (2条消息) 解决redis中java.io.IOException: 远程主机强迫关闭了一个现有的连接_zeal9s的博客-CSDN博客_redis远程主机强迫关闭了一个现有连接怎么解决 ...

  3. java.io.IOException: 远程主机强迫关闭了一个现有的连接

    摆脱烦恼最有效的是慢思考,为什么和我想的不一样,出入在哪里,什么导致的? 疑惑 我使用netty框架接受数据,每隔半个小时存储数据,运行不到三个小时报错 java.io.IOException: 远程 ...

  4. java强制关闭远程桌面_elasticsearch中的java.io.IOException: 远程主机强迫关闭了一个现有的连接...

    [2018-07-31T14:29:41,289][WARN ][o.e.x.s.t.n.SecurityNetty4HttpServerTransport] [9rTGh-y] caught exc ...

  5. java nio 强制关闭_Java NIO服务器:远程主机强迫关闭了一个现有的连接

    Java NIO聊天室 中,若客户端强制关闭,服务器会报"java.io.IOException: 远程主机强迫关闭了一个现有的连接.",并且服务器会在报错后停止运行,错误的意思就 ...

  6. 远程计算机强迫关闭一个连接,远程主机强迫关闭了一个现有的连接。

    org.apache.catalina.connector.ClientAbortException: java.io.IOException: 远程主机强迫关闭了一个现有的连接. at org.ap ...

  7. es远程主机强迫关闭了一个现有的连接

    Caused by: java.io.IOException: 远程主机强迫关闭了一个现有的连接.     at sun.nio.ch.SocketDispatcher.read0(Native Me ...

  8. netty 远程主机强迫关闭了一个现有的连接。

    如果你的netty报这个错误 java.io.IOException: 远程主机强迫关闭了一个现有的连接. 或者 System.Net.Sockets.SocketException (0x80004 ...

  9. 循环报错: 远程主机强迫关闭了一个现有的连接

    客户端终止后,服务端一直循环 报java.io.IOException: 远程主机强迫关闭了一个现有的连接. 原始代码 private void read(SocketChannel channel, ...

最新文章

  1. 用 PHPMailer 发送邮件
  2. css3 选择器_CSS 3
  3. 搜狐视频怎么开启自动连播
  4. spark的异步消息总线LiveListenBus
  5. python怎么做软件程序_Revit二次开发python怎么做?人工智能python语言在BIM软件高效建模的运用尝试...
  6. 用vb写计算机程序代码,用VB编写的抽奖程序源代码随机抽取不重复
  7. 使用JavaScript在页面打印系统当前时间
  8. 静态网站生成器(开源项目)
  9. Matlab中max函数详解
  10. 一行代码教你屏蔽你的博客广告
  11. 史上最简单的word文档docx文档解密方法,忘记word文档docx密码怎么办?
  12. Manjaro-architect 安装指南
  13. 两个程序员老友的会面
  14. 算法之美_源码公布(1)
  15. DBeaver解决连接Oracle之后出现库名为数字问题
  16. 我的十一Win10之旅
  17. MATLAB消除图像白边
  18. 优恩解答GDT放电管是怎么工作的
  19. 全网最快的M1 MacBook Air详细测评
  20. java毕业生设计医院门诊分诊系统计算机源码+系统+mysql+调试部署+lw

热门文章

  1. Python第3章 流程控制
  2. 重磅 !微软官方出了免费 Python 视频教程
  3. Python之建模规划篇--整数规划
  4. java界面——可视化窗口入门级
  5. input光标位置设置至行末端
  6. Html和Xml中注释符
  7. 11广义表的基本概念和性质
  8. 基于PCA的人脸识别
  9. SpringCloud 基本使用
  10. 算法-并查集-加边无向图