内网访问排版核料详情功能,用户反馈要等十几秒
排查 sql:sql 比较简单
排查内存计算:arthus trace 类名 方法名 总耗时2s
排查页面渲染是否缓慢:F12 查看接口 等待服务器响应 20s 下载时间 30s, 故不考虑渲染问题
排查请求响应日志打印:关闭请求响应日志拦截器 问题依然存在
本地还原数据 idea postman单独调接口:返回 12M ,耗时依然存在啊,跟页面无关
排查序列化问题:接口方法返回值改成 String, 把响应结果使用 ObjectMapper序列化成 json字符串(获取容器的 objectMapper) 不存在耗时,跟序列化貌似无关
排查框架问题,把接口方法复制到新的 springboot项目中,不存在问题,断定框架存在问题
排查拦截器、或过滤器问题:从 controller 方法的 return开始 debug ,经过层层 debug, 在RequestResponseBodyAdviceChain..beforeBodyWrite 发现长时间停顿,再次 debug 发现easy-trans拦截器,项目中开启了全局扫描,关闭easy-trans全局扫描:
easy-trans: is-enable-global: false
中间猜测有什么特殊注解,没想到没有注解光trans扫描就很耗时(项目体量大了,注解都敢用:接口日志注解。spring创建的bean多了,启动慢,@Data编译也慢)数据量、体量一大,什么问题都放大
问题解决
收获:使用arthus查看各个业务方法的耗时,不需要添加日志来实现
解决问题思路:不懂原理,了解信息不够,通过猜想,拼接基础知识,不断各种试验(歇一歇停一停就会有新思路),找到一个线索后,逐渐挖掘,一步步接近,拼接运气:easy-tran拦截器正好在controller方法结束时就调用,如果埋藏在各个拦截器中,通过debug很难找出来,springmvc源码不好debug。
新收获:RestController可直接返回string(手动序列化再返回),前端依然可以兼容
如果是string,springmvc 的converter发现string直接发送,不再json序列化