一次偶现问题的排查 inputMessage.getBody().available()

问题概述

测试同学请求某接口,偶尔会出现一个错误提示。此接口在 body 中会传一段 base64 后的 json。看服务端的日志发现有异常日志,如下图。具体打印出 body ,发现拿到的是截断的字符串。


v2-ea1c6a9fcefbd58477fff1d73cd680b8_b.jpg


排查问题

  1. 正好测试有抓到app的异常的包,当我们查看此包时,发现包中 body 无问题。排除前端问题。


v2-b5b0778b799e14eb854613a7aa134d01_b.jpg


  1. 直接在业务服务器端抓包,看传递过来的参数是否有问题。于是通过 charles repeat 功能,重复请求接口以复现问题。


v2-549231a84b11cf2fdcf8b93de098352c_b.jpg


同时在业务服务器端 tcpdump -i any port 8080 -A -s 1500 。复现后。查看同一个 traceId 的包。发现确实有问题。body 的数据分成了两个 tcp 包。而我们在代码中 debug 拿到的数据确实只有前面这一段。(图中取的是不同的包,可不必在意数据不一样)


v2-0c2089b270b2ab1fcafa97b1c96eff65_b.jpg



v2-00850d94dc940e8979eaa7352167e784_b.jpg


为了更好的看清包是否都正常。直接通过 tcpdump -i any port 8080 -A -s 1500 -w test.cap 。重新 repeat 请求然后导入到 wireshark 中方便查看。


v2-bcd98a11688900bfed23b200a1fcfebb_b.jpg


  1. 这里看起来包都正常,那么就把问题定位到代码层面去分析了。关键代码如下。我们发现这时 available 方法返回的数值只有一部分。


v2-14f259bfaabc5474f94cd1a4b9e9b670_b.jpg


这个 avaiable()方法 获取到的值是不是有问题,后来 google 发现这个方法调用时,数据可能还没完全读入。于是改写了方法。先读出 content-length 。再通过循环等待,调用 avaiable() 方法。期待能获取完整的数据。可惜并没有用。


v2-ecb81f33fec2389f11657bd53ed1add9_b.jpg


4.于是去查看,工具类中是否有类似方法。于是查看了 FormHttpMessageConverter 中读取 body。


v2-26f0ba22f044845d94df198d92c5d082_b.jpg



v2-8e62b39bbb658ff42f509b6d8cd0085d_b.jpg


5.改写为直接调用 StreamUtils 工具类。测试后无问题。


v2-0f5552a1e201927b48a6e9934a843587_b.jpg


这里顺便说下,debug available() 方法,看到的注释。这个数值不一定准确,不要依赖他。


v2-39a350e5af2bd3f6419c4203ac80b34d_b.jpg



v2-6091ce6d8aa7c672a813fb056e570666_b.jpg


另外

还有两个问题需要再去分析一下。

  • 前端的包会先到一个 【网关服务】 ,再由【网关服务】转发到【业务服务】。网关服务收到包时是1个完整的包。而转发到业务服务变成了多个包。虽然增加了一些头部,但看长度并未达到拆包的程度。需要再去查下原因网关服务做了什么特殊处理。
  • 没有完全debug到 available() 方法是为何没有把第二个 tcp 包body 长度计算进去的?只是从注释上分析。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值