Connection reset————记一次奇怪的网络波动造成的bug

718 阅读7分钟

bug与程序

在开发的过程中,会遇到各式各样的bug。

大部分的bug,要么是自己粗心,要么是代码问题,或者是使用sdk不当,对业务理解不够深。这一类的问题,修改一下代码就行了。

有的bug呢,需要别人的配合,比如接口问题,需要前后端联调,要么格式,要么数据类型不对。如果遇到sdk出现问题,就得去git上找找了,更新sdk版本,或者提一个issues,等作者更新。

还有一些bug呢,是偶现的。这种bug,复现难度大,有的复现了,也不好找问题。而有的,即便复现了,也会不知道为什么。

当然,上面提到的,是开发工作中会遇到的大部分bug。而现在要提的bug,和网络有关。

网络问题

和网络问题有关的bug,大多数是和接口有关。

比如,

404 Not Found,是接口地址有误,

502 Bad Gateway,一般情况下,都是后端发版本,等后端版本发完,接口就正常了。

403 Forbidden,一般情况下,前端和后端有做一些接口的身份校验的,防止接口被盗刷。

还有类似的接口请求超时,有可能是网络波动,复现难度比较大,可能是数据量太大,传输比较慢,可能是后端处理比较慢,数据返回的时候超过了超时时间。

包丢失

在网络通信中,不同的网络链路通常限制每个数据包的最大大小,一旦数据较大,就会被分成多个小的数据包进行传输。在接收端根据序列号,进行排序。如果其中一个包丢失了,会通知发送端重新发送。

一般情况下,数据的传输是不存在丢包问题的。只是,这个问题,恰恰被我遇到了。

复现

流程

暂且把这个出问题的接口称为接口A吧。在接口A之前,又有接口B、C、D三个接口,这三个接口会收集设备数据,然后上传数据。在B、C、D接口上传数据的同时,调用接口A。如下图所示:

B--↘
C---→ 下一步
D--↗ ↗
   A↗

此时,调用A接口,会出现偶现的bug:java.net.SocketException: Connection reset。

image.png

因为当时(下午)还有其他工作,初步认定是网络波动,暂且把这个问题放下来了。到了晚上的重新测试这个bug的时候,同样的流程走下来,这个bug成了必现的--那个时间段,这个bug一定会复现。

java.net.SocketException: Connection reset 是一个常见的网络通信错误,通常在Java程序中使用Socket进行网络通信时出现。它指示在尝试建立连接或发送数据时,连接被对方重置或中断。

  1. 服务端意外关闭连接。
  2. 网络中断。
  3. 数据发送超时。
  4. 数据包大小限制。
  5. 防火墙或代理问题。

服务端意外关闭连接

找后端确认了一下,服务器是正常的,正常接收到请求并返回数据。而且从日志来看,数据也是完整的,正常的40条数据正常传输,在看客户端,发现就是报错Connection reset。利用Fiddler抓包,结果如下:

image.png

ReadResponse() failed: The server did not return a complete response for this request, Server return 14,520 bytes.

这个是Fiddler自己的返回,用Charles抓包,则能抓到返回的数据,但数据没办法阅读--因为加密的,数据丢失,导致无法解密。但确实,发现报错的时候,数据量只有27kb,而没有报错的时候,这个接口返回的数据量是32kb。那么,其中5kb左右的数据包,去哪里了?

网络连接

网络是正常的,因为内网,网络访问甚至会更快。

数据发送超时

接口请求返回的数据在超时时间以内(假设超时时间设置为10s,5s钟内就会返回response),所以也不会是这个问题。

防火墙或者代理

应该不是这个问题,内网环境,且wifi没有设置代理,也不是这个问题导致的。

数据包大小限制

打印日志,发现整个接口数据大小也才32kb左右,其他接口的数据量更大,却没有报这个错误,而且这个错误也是最近才遇到的。

如果单独请求接口A,是不会遇到这个问题的,但按流程走下来,收集数据,请求接口A,同步请求接口B、C、D,此时就会报错。

那,最近做了什么改动呢?

想来,应该就是接口B、C、D在传输的过程中同时进行接口A的请求了,而B、C、D接口传输的数据量比较大,会不会因此导致接口报错呢?

那,修改数据试了下:

数据量结果
40条数据报错
前20条数据成功
后20条数据成功
前30条数据报错
后30条数据报错

难不成,真的和数据大小有关?可,仅仅只有40条数据啊。挠头,想不到解决办法。

问chatGPT,结果找了一圈,一样一头雾水。

处理办法

其实最后这个bug是没有解决掉的。一方面,因为接口A需要的数据基本上算是固定的,经过产品的同意,把数据放在客户端本地了。第二,太晚了,产品加班加不了了...

第二天重复试了几次,发现这个bug又消失了,同样的流程,接口正常返回数据,重复试验了几次,都是没问题的,不过,其他接口开始报错了。到了下午再次测试,都没问题了。

猜想

因为,这个bug复现难度大,也无法真正确定是哪里出现了问题( 注:服务器日志显示是正常返回数据的,且数据完整的;客户端抓包发现收到的包是丢了一部分数据的),所以只有一些猜想了,也不知道猜想是否正常。

猜想一

服务器带宽限制

感觉接口A请求时,服务器的带宽已经接近临界值了--接口B、C、D传输的数据够大,此时接口A相当于是压弯骆驼的最后一根稻草。

猜想二

数据在传输的过程中,经过某一路由时,丢失了数据,但未丢失包。


当然,以上只是我的猜想,没办法去验证--后续几次测试过来,这个bug没有复现了。其实只要和领导确定了,这个问题是网络波动造成的,就没事了,不过网络波动在领导这里是不过的--以前遇到过bug,用网络波动忽悠领导,最后发现是代码问题,所以领导从那以后不信任网络波动这个问题了。

不过,代码过程中,总会遇到一两个难以处理的bug,算是代码人生中不一样的经历吧。


最后

这篇文章写的有点虎头蛇尾啊,不过,还是要感谢你看到最后,最后说一两点~

1.如果你有不同的看法,欢迎你在文章下面进行评论留言。

2.如果文章对你有帮助,或者你认可的话,请随手点个赞,支持一下。

我是个技术小白,欢迎私信交流。

(文章内容仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除,同样,转载请提前告知)