最近高层来参观,有个页面是重点放在屏幕上的,但是已经好几个月没维护了,前端同学在调样式的时候发现响应时间很长,有两个异步请求都在30秒左右,如果在慢速网络情况下,40秒都有可能。于是开始排查。
但是,这个页面的逻辑我完全不清楚。
1、用firebug看了一下,发现一次页面请求,会发送多个http请求,是到一个接口,然后通过参数不同来调用不同的逻辑,哎呀,傻了,本来逻辑就不清楚,还是通过参数动态控制的;
2、找到代码,逐段分析,发现逻辑方法中初最后一行外,其余的全是内存操作,不可能耗时很长,只有最后一场是数据库的操作;
3、中间试过用Btrace的工具把调用的方法栈以及响应时间占比打印出来,这样就能很快的定位那个地方慢了,但是搞了半天,也没打印出栈信息出来,于是放弃使用这个高级货了。
4、进入最后一行代码的实现,发现全是DAO操作,心里大体有谱了,但是有好多DAO,是那个DAO方法慢了呢?
5、观察发现这些DAO是来自一个类,然后就用housemd来进行动态追踪,打印这个类的执行情况。
1
|
trace -d -t 60 IbatisNodeTransitDAO
|
这样在点击页面的过程中,打印出来这个类中各个方法的执行情况,
1
2
3
4
|
core/dao/ibatis/IbatisNodeTransitDAO.queryPredictWarnAllNodeTransitsLoadCount(PredictDataQueryTO, Double, Double) sun.misc.Launcher$AppClassLoader @63c78e57 2 328ms core.dao.ibatis.IbatisNodeTransitDAO @564a6f2
core/dao/ibatis/IbatisNodeTransitDAO.queryPredictWarnForcastRoutineByAreaBounds(PredictDataQueryTO) sun.misc.Launcher$AppClassLoader @63c78e57 5 <1ms core.dao.ibatis.IbatisNodeTransitDAO @564a6f2
core/dao/ibatis/IbatisNodeTransitDAO.queryPredictWarnLineCountByNodeTransitId(Long, String) sun.misc.Launcher$AppClassLoader @63c78e57 184 290ms core.dao.ibatis.IbatisNodeTransitDAO @564a6f2
core/dao/ibatis/IbatisNodeTransitDAO.queryPredictWarnNodeTransitsByAreaBounds(PredictDataQueryTO) sun.misc.Launcher$AppClassLoader @63c78e57 5 258ms core.dao.ibatis.IbatisNodeTransitDAO @564a6f2
|
6、在上面中,发现queryPredictWarnLineCountByNodeTransitId这个方法的平均响应时间很长,而且调用次数很多,然后就找到这个DAO对应的SQL,SQL如下:
1
2
3
4
5
6
7
8
9
|
select sum (ls.order_count) as lineCount
from
xxxxxx_table ls
where
ls.status = 1 and
( ls.record_date between #beginDate# and #endDate#) and
ls.to_transit_id = #transitId#
]]>
|
第一反应是没有加索引,在websqlplus上面,看了一下,这个表数据不多80W左右,然后造了一个数据,用explain select_statement来看了一下情况,然后type是all,也就是全表扫描,这时候基本清楚问题怎么解决了。
7、联系DBA添加索引,被DBA说了一顿,白天不能加,哀求白天,加上了。
由于status是个常量字段,不用添加,于是在record_date和to_transit_id搞了一个组合索引。
8、至此,问题解决。
总结:
1、灵活运用动态追踪工具,因为线上环境不可能像我们线下环境那样能够debug
2、快速阅读代码,定位可能存在的瓶颈(死循环、网络IO、数据库操作、大对象操作等)
相关推荐
在软件开发过程中,问题排查与分析是不可或缺的一部分。软件问题可能会导致各种严重的后果,比如系统崩溃、功能异常等。因此,能够准确且迅速地识别并解决问题,对于提高软件的稳定性和可靠性至关重要。 ##### 基本...
8. **备注**:备注栏通常用于记录额外的信息,如特殊处理的步骤、与上一版本的区别或者可能遇到的问题及解决方案,这些都是运维过程中积累的宝贵经验。 总之,等保2.0中的系统运维管理强调了对恶意代码库升级记录的...
在日常的软件开发与维护过程中,针对JVM(Java虚拟机)的性能调优和问题排查是非常关键的一环。本手册旨在提供一套全面且实用的JVM问题排查方法和技术,帮助开发者快速定位并解决JVM相关的性能瓶颈或异常情况。 ###...
4. **程序逻辑优化**:在代码层面避免可能导致死锁的操作,如一次性获取所有需要的锁。 **总结** 了解死锁的原因和排查方法对于后端开发者至关重要。虽然我们不需要深入研究锁的源码,但熟悉基本的死锁原理和排查...
Arthas是一款功能强大且灵活的在线问题排查工具,它可以帮助开发者快速定位和解决在线问题。本文将详细介绍Arthas在线问题排查思路,包括常见的排查场景、改进策略和排查思路。 常见的排查场景 在实际开发中,我们...
本文将详细介绍一次 Java 内存泄漏的排查解决过程,通过示例代码和实际案例,帮助读者更好地理解和排查 Java 内存泄漏。 一、问题描述 在本次值班中,我们的探测服务突然出现了大量的超时报警邮件,多数执行栈都在...
本文记录了一次线上容器因内存占用过高而自动扩容的过程。该事件发生在一个部署于腾讯TAF平台的Node.js服务上,该服务主要负责接口查询及使用socket.io进行通信。尽管服务功能简单且并未遇到大流量或高并发的压力,...
1. **日志记录与分析**:日志是定位问题的第一步,良好的日志记录习惯至关重要。通过日志,我们可以查看程序运行过程中的异常信息、错误堆栈和关键操作记录。学会分析日志,例如寻找错误信息、异常堆栈跟踪,有助于...
8. **学习和反思**:每次解决一个问题,都是一次学习的机会。分析导致问题的原因,思考如何避免类似问题再次发生。同时,反思调试过程,看看是否有更好的方法可以提升效率。 9. **团队合作**:在团队中,分享你的...
在IT行业中,日志记录是调试和监控应用程序的关键部分,特别是对于Java开发者而言,Log4j是一个非常常用的日志框架。当我们遇到“无法打出log4j日志的问题”,这通常是由于配置、环境或代码实现中的某些错误导致的。...
根据给定文件的信息,本文将围绕“错误的排查方法”这一主题进行展开,重点阐述如何正确地识别并解决出现的问题,以及在测试与调试过程中所采用的一些策略。 ### 错误排查的重要性和目的 错误排查是一项至关重要的...
记录异常日志和提供用户友好的错误信息,能提高用户体验并方便问题排查。 最后,代码重构和优化是持续改进代码质量的过程。通过提高代码可读性、可维护性和性能,可以使得代码更加简洁高效。工具如 PyCharm 的重构...
- **逐步排查代码问题:** 采用逐步调试的方式,逐一检查代码逻辑,有助于找出导致故障的代码段。 - **调试远程服务器程序:** 对于部署在远程服务器上的应用程序,可以通过远程调试工具进行问题定位和解决。 #### ...
在实际操作中,问题排查是一个迭代过程,可能需要反复使用这些工具并结合业务逻辑进行分析。记住,每次定位到问题后,都应该尝试修复并验证效果,然后再进行下一步,直到问题完全解决。 总的来说,面对Linux服务器...
这篇文章主要记录了一次排查Tomcat进程CPU占用过高的问题的过程。问题发生在Linux环境下,一个Tomcat Web服务的CPU占用率超过200%,导致请求无法响应。在排查过程中,作者首先通过`jps`命令找到JVM进程,接着使用`...
在本文档中,作者记录了一次在发布服务后遇到图形验证码乱码问题的排查过程。这个问题发生在将服务部署到新的CentOS7服务器上,并且在使用Nginx和JDK环境后出现。以下是对该问题及其排查步骤的详细分析: 首先,当...
"程序排查用信息调试器"是一款高效实用的调试助手工具,它能够帮助开发者在程序内部输出详细的信息,以便于分析和排查问题。这款工具以其强大的功能和易用性,受到了众多程序员的青睐。 首先,信息调试器的核心特性...
标题和描述中提到的事件是一次在线MySQL数据库发生的死锁问题,这突显了了解数据库加锁原理的重要性,而不仅仅是基础的CRUD操作。死锁是指两个或多个事务在执行过程中,因争夺资源而造成的一种相互等待的现象,若无...
【标题】"记录acm学习代码.zip" 暗示了这是一个包含与ACM(International Collegiate Programming Contest,国际大学生程序设计竞赛)相关的编程代码的压缩文件。在ACM竞赛中,参赛者需要解决一系列算法问题,这通常...