问题出现: 视频剪辑超时

   1。检查系统日志

 

 发现这个报错信息,导致接口访问超时获取数据失败。

2。经过对网上信息梳理,发现这个超时是在用域名访问nginx时候,有一个send_timeout超时时间,超过这个时间nginx将连接断开了。代码会报错

     (如果有遇到相同问题的同学,并且正好是域名访问接口报错,可以直接更改配置,调整超时时间。 但同样也要反思,这个接口响应这么久真的没问题吗?)

 

3。由于这个请求的数据大小只有2M,大概四千条数据,响应不应该这么慢,然后开始debug查询问题。

4。看图

 

这个是httpUtil的一个工具类,可以看到这行代码是有问题的。

 

原因:

使用+拼接字符串的实现原理,基于jdk1.8

 

下面一段代码。把他生成的字节码进行反编译,看看结果。

String testJoin = "testJoin";
String introduce = "测试数据拼接";
String result =
testJoin + "," + introduce;

反编译后的内容如下,反编译工具为jad。

String testJoin= "testJoin";
String introduce = "\u6BCF\u65E5\u66F4\u65B0Java\u76F8\u5173\u6280\u672F\u6587\u7AE0";
String
result= (new StringBuilder()).append(testJoin).append(",").append(introduce).toString();

通过查看反编译以后的代码,可以发现,原来字符串常量在拼接过程中,是将String转成了StringBuilder后,使用其append方法进行处理的。

 

 

 

改动代码为如下:

 

 这样处理数据的时候就非常快,问题看似已经解决。

问题扩展:

我这里经过测试,发现只有请求我写的新系统时候,才会发生这种响应慢的问题。然后继续打断点调试。

发现同一个json数据结构体,其他系统在这里只需要遍历一次就可以。

 

 自我反思:

为什么只需要遍历一次? 数据传输的时候是一行? 为什么我的是多行? 同样是json体为什么我的就需要遍历多次?

 

排查继续:

检查使用的JSON序列化工具,发现其他系统用的是jackson,而我使用的是fastjson。 

 

 将这个配置注释掉,再次调用接口发现循环遍历的时候变成了一次。

继续反思:

springBoot项目中返回数据的时候我用到了@ResponseBody, 这个注解是用的那个JSON序列化工具?

这里就开始查询源码,自我debug过程不再论述,网上源码讲解很多,直接贴出来给大家参考。

https://www.cnblogs.com/HHR-SUN/p/11639801.html

https://www.jianshu.com/p/2f633cb817f5

核心点就是spring MVC有HttpMessageConverter这个消息转换器,我们的请求与返回数据的响应都经过这里,经过debug发现@ResponseBody默认采用的是jackson。

 

难道和这个序列化有关系? 

这个关键是HTTP获取流,还没有对此进行反序列化等操作。然后在一个接口中直接用fastjson转换了一下结果,发现数据返回并没有问题,也是遍历一次就可以。

 

最后:

上面引用了fastjson的时候做了一下配置,怀疑是某个配置造成。(这个 配置文件直接拷贝其他项目,具体配置并不了解。自己坑自己)

 

 

查找各配置含义:

 

 

怀疑是这个格式化原因,将其注释掉,再次调用接口,发现问题解决。

 

扩展:

 

 下面数据为格式化后的样子,比格式化前数据大了18%左右

 

 

总结

问题的排查必须要有从点到面的思考方式,解决问题的方式有很多,但是问题的出现可能是连锁反应,直有从头到尾,不错过任何细节才能发现真正的原因