在某项目的第一轮性能测试的中,发现某协议响应时间很长,通过javamethod监控相关接口的调用耗时的时候监控结果如下:

onMessage是该协议的总入口,可以看到该协议平均耗时为352.11ms,观察其他耗时方法可以看到updateUserForeignId耗时307.75ms,

那么可以认为该方法的响应时间慢是该协议的最主要性能瓶颈,这时候我们应该看看该方法究竟做了哪些操作导致响应时间过长:

从监控中可以看到userStorage.updateUserForeignId方法耗时122.86ms,userStorage.updateForeignIdPegging方法耗时71.33ms,

这两个方法有成为了SessionProcessHelper.updateUserForeignId方法的主要耗时点,基于对代码的熟悉程度xxxStroge方法都是一些数据库的操作,

那么现在可以初步的认为数据库的相关操作可能是问题的根源所在,为了清楚的展示问题,我们先选择一个逻辑较简单的方法分析一下,从上面的方法监控里可以看到updateSession方法耗时34.88ms,查看该方法代码:

可以看到方法只是有一个简单的dao层的操作,通过查看dao层方法可知该方法仅仅是一个update操作,按常理来说这样的操作需要三十多毫秒的耗时,显然是偏长了,既然如此,

我们继续求根溯源利用哨兵的mqlcolletor来验证一下该方法底层的sql操作究竟耗时多少毫秒。此处省略通过dao层方法查找sql语句的过程,直接来看结果:

从这里可以看到底层sql响应时间是1.62ms,而dao层方法耗时高达34.88ms,这里显然有问题的,这里我们首先需要排查一下压测机,数据库的各资源指标是否到达瓶颈(在之前的性能测试中发现过类似的问题最后发现是数据库机器的磁盘util接近100%,

该机器性能较差导致出现该问题,后期更换数据库机器解决了问题),通过检查这些指标可以发现cpu,内存,网络,磁盘各项指标均保持在正常水平。

问题到这里,貌似没有什么进展了,这时候就到了jstack登场了。在Java应用的性能测试中,很多性能问题可以通过观察线程堆栈来发现,Jstack是JVM自带dump线程堆栈的工具,很轻量易用,并且执行时不会对性能造成很大的影响。

灵活的使用jstack可以发现很多隐秘的性能问题,是定位问题不可多得的好帮手。我们来jstack一下,查看在测试执行的过程中,各线程所做的操作和线程状态,可以看到以下状态:

在所有的24个线程中,多执行几次jstack可以发现大约有十个左右的线程处于waitting状态,该状态表明该线程正在执行obj.wait()方法,放弃了 Monitor,进入 “Wait Set”队列,为什么阻塞住呢,继续往下看堆栈信息,

可以看到该线程正在做borrowobject操作,可以大概看到这里是一个数据库连接池的相关操作,具体到究竟是干什么的可以查看一些数据库连接池的资料:dbcp源码解读与对象池原理剖析     https://blog.csdn.net/suixinm/article/details/41761019

简单的说一下,数据库连接的使用过程:创建一个池对象工厂, 将该工厂注入到对象池中, 当要取池对象, 调用borrowObject, 当要归还池对象时, 调用returnObject, 销毁池对象调用clear(), 如果要连池对象工厂也一起销毁, 则调用close()。

从这里可以很明显的看到该线程waitting的原因是没有获取到连接池里的连接对象,那么很容易就可以想象的到导致该问题的原因是数据库连接池比够用导致的,于是将连接池的大小从10修改到了50,继续执行一轮测试得到了以下结果:

可以看到updateSession方法从34.88ms下降到20.13ms,虽然耗时下降了14ms,但是距离sql耗时的1.64ms仍然有差距,沿着刚刚的思路,我们继续jstack一下,看看当前的线程状态又是如何:

在24个线程中平均下来会有十个左右的blocked状态,继续往下阅读可以发现,该线程是blocked在了log4j.Category.callAppenders上,显然可以发现这是个log4j的问题,那究竟为何会阻塞在这里呢,

查看资料可以找到callAppenders的源码(具体的log4j相关资料可以看这里:Log4j 1.x版引发线程blocked死锁问题):https://www.iteye.com/blog/zl378837964-2373591

/**Call the appenders in the hierrachy starting at

this.  If no appenders could be found, emit a

warning.

This method calls all the appenders inherited from the

hierarchy circumventing any evaluation of whether to log or not

to log the particular log request.@paramevent the event to log.*/public voidcallAppenders(LoggingEvent event) {int writes = 0;for(Category c = this; c != null; c=c.parent) {//Protected against simultaneous call to addAppender, removeAppender,...

synchronized(c) {if(c.aai != null) {

writes+=c.aai.appendLoopOnAppenders(event);

}if(!c.additive) {break;

}

}

}if(writes == 0) {

repository.emitNoAppenderWarning(this);

}

}

我们从上面可以看出在该方法中有个synchronized同步锁,同步锁就会导致线程竞争,那么在大并发情况下将会出现性能问题,同会引起线程BLOCKED问题。

那么如何优化log4j使其执行时间尽量短,防止线程阻塞呢,推荐一下我们组候姐的一篇文章:log4j不同配置对性能的影响

当前我们解决该问题的方式是去掉log4j配置文件中打印行号的选项,然后再执行一轮测试可以看到如下结果:

其实这个案例的优化主要体现在接口耗时上面的优化,从最初的接口耗时352ms优化到了109ms,性能提升了接近3倍,虽然用户量小的时候,体现不出打的性能瓶颈,如果并发量大,这种性能优化的效果还是很明显

其实性能优化的重点是分析解决性能瓶颈,而作为专业的性能测试需要辅助开发定位和性能瓶颈卡在哪里,进而指导开发解决问题

java 接口耗时分析_性能优化案例(2019-案例78)-接口性能耗时问题分析相关推荐

  1. 春节福利:《Oracle性能优化与诊断案例精选》电子版首次公开下载

    值此猪年春节到来之际,恩墨云服务团队恭祝大家新年快乐,心想事成.同时我们也为大家准备了一份新年礼物,首次公开Eygle和600主编的<Oracle性能优化与诊断案例精选>电子版下载. 本书 ...

  2. 《Oracle性能优化与诊断案例精选》——2.3 衣带渐宽终不悔

    本节书摘来自异步社区出版社<Oracle性能优化与诊断案例精选>一书中的第2章,第2.3节,作者:盖国强 , 李轶楠 ,更多章节内容可以访问云栖社区"异步社区"公众号查 ...

  3. 《Oracle性能优化与诊断案例精选》——2.5 回首向来萧瑟处,也无风雨也无晴...

    本节书摘来自异步社区出版社<Oracle性能优化与诊断案例精选>一书中的第2章,第2.5节,作者:盖国强 , 李轶楠 ,更多章节内容可以访问云栖社区"异步社区"公众号查 ...

  4. 《Oracle性能优化与诊断案例精选》——第2章 回首向来萧瑟处,也无风雨也无晴...

    第2章 回首向来萧瑟处,也无风雨也无晴 Oracle性能优化与诊断案例精选 --我的十年Oracle DBA奋斗路(侯圣文) 题记 迄今为止,我觉得这辈子最幸运的两件事,一件是遇见了我太太,另一件就是 ...

  5. 【性能优化方法论系列】三、性能优化的核心思想(3)

    性能优化方法论系列目录 <一.性能优化的本质> <二.性能优化方法论的思想源泉> <三.性能优化的核心思想(1)> <三.性能优化的核心思想(2)> & ...

  6. 性能优化系列(五)网络性能优化

    文章首发「Android波斯湾」公众号,更新地址:https://github.com/jeanboydev/Android-ReadTheFuckingSourceCode 移动互联网时代,用户对网 ...

  7. linux性能优化实战 倪朋飞,Linux性能优化实战:系统的swap变高(09)

    一.实验环境 1.操作系统 root@openstack:~# lsb_release -a No LSB modules are available. Distributor ID:Ubuntu D ...

  8. 前端性能优化(二)01-页面性能优化之浏览器——浏览器的主要作用 浏览器的组成结构

    前端性能优化(二)01-页面性能优化之浏览器--浏览器的主要作用 & 浏览器的组成结构 页面性能优化 前端性能优化可以分为两大部分:浏览器部分.代码部分. 浏览器部分又可以分为: 网络层面 浏 ...

  9. C++性能优化(一)——应用程序性能优化简介

    一.程序性能优化简介 1.程序性能优化简介 在计算机发展的早期阶段,硬件资源相对而言是非常昂贵的,CPU运行时间与内存容量给程序开发人员设置了极大限制.因此,早期的程序对运行性能和内存空间占用的要求是 ...

  10. 前台性能和服务器性能是什么,前端性能优化指南[2]--什么是Web性能?

    一个大型网站架构模型如下图所示,对一个网站的性能进行优化,可以分为 Web 前端性能优化.应用服务器端性能优化.存储服务器端性能优化三层.网站的整体性能,需要所有开发者一同来维护. 大型网站架构模型 ...

最新文章

  1. Windows Azure Service Bus (5) 主题(Topic) 使用VS2013开发Service Bus Topic
  2. Xshell连接Centos完整版(动态ip)
  3. 工作46:理解父子组件
  4. Python编程教程:面向对象之高级特性!
  5. 记录一下 orangepi zero wifi联网
  6. C/C++[结构体]
  7. 攻击局域网计算机,如何攻击局域网电脑
  8. 创业公司早期融资应该怎么写商业计划书
  9. 图形学基础|环境光遮蔽(Ambient Occlusion)
  10. Python获取外网ip
  11. Android:开发中,代码被横线划掉是什么意思
  12. unity3d的playmaker插件使用教程,五、进入区域改变平台颜色
  13. MySQL数据库监控与调优(2)
  14. 移动App性能测试包含哪些内容?App性能测试工具有哪些?
  15. 我的生词表(中文在上,英文在下)(A-Z排序)
  16. iOS-配置AppIcon
  17. 牛顿拉夫森法 matlab,【原创】牛顿-拉夫森迭代求非线性方程组
  18. 手淘搜索流量下降时如何提升?
  19. 真果科技董事长贾求真女士应邀出席2019APEC女性领导力论坛
  20. GeniE 实用教程(三)属性

热门文章

  1. 若依前后端分离项目图片上传后访问404问题
  2. [苹果开发者账号]04 申请苹果开发者账号 美国报税表
  3. [clear] python 种子转磁力链
  4. 提升企业网站用户体验 你不可不知的秘诀
  5. ubuntu20 关闭防火墙_ubuntu中如何关闭防火墙
  6. “让我帮你百度一下”源码
  7. 编写一个Linux虚拟网卡来实现类NVI
  8. 上海小伙三次成功创业,资产达上十亿被称为“创业神童”
  9. 动态规划-背包问题求解过程【代码 from eason】
  10. “毕竟,你胜利了......敬胜利者一杯。”