国内一线架构师的Java性能优化思路

性能优化是一个老生常谈的问题了,典型的性能问题如页面响应慢、接口超时,服务器负载高、并发数低,数据库频繁死锁等。而造成性能问题又有很多种,比如磁盘I/O、内存、网络、算法、大数据量等等。我们可以大致把性能问题分为四个层次:代码层次、数据库层次、算法层次、架构层次。

下面我结合实际性能优化案例,和大家分享下性能调优的工具、方法和技巧

国内一线架构师的Java性能优化思路

心态

说到性能问题,你可能首先就想到的是麻烦或者头大,因为一般性能问题都比较紧急,轻则影响客户体验,重则宕机导致财务损失,而且性能问题比较隐蔽,不易发现。因此一时间无从下手,而这时我们就很容易从心底开始去排斥它,不愿接这烫手的山芋。

而恰巧,性能调优是体现程序员水平的一个重要指标。

因为处理bug、崩溃、调优、入侵等突发事件比编程本身更能体现平庸程序员与理想程序员的差距。当面对一个未知的问题时,如何定位复杂条件下的核心问题、如何抽丝剥茧地分析问题的潜在原因、如何排除干扰还原一个最小的可验证场景、如何抓住关键数据验证自己的猜测与实验,都是体现程序员思考力的最好场景。是的,在衡量理想程序员的标准上,思考力比经验更加重要。

所以,若你不甘平庸,请拥抱性能调优的每一个机会。当你拥有一个正确的心态,你所面对的性能问题就已经解决了一半。

技巧

拿到一个性能问题,不要忙着先上工具,先了解问题出现的背景,问题的严重程度。然后大致根据自己的经验积累作出预估。比如客户来了个性能问题说系统宕机了,已经造成资金损失了。这种涉及到钱的问题,大家都比较敏感,根据自己的level,决定是否要接这个锅。这不是逃避,而是自知之明。

了解问题背景之后,下一步就来尝试问题重现。如果在测试环境能够重现,那这种问题就很好跟踪分析。如果问题不能稳定重现或仅能在生产环境重现,那问题就相对比较棘手,这时要立刻收集现场证据,包括但不限于抓dump、收集应用程序以及系统日志、关注CPU内存情况、数据库备份等等,之后不妨再尝试重现,比如恢复客户数据库到测试环境重现。

不管问题能否重现,下一步,我们就要大致对问题进行分类,是代码层次的业务逻辑问题还是数据库层次的操作耗时问题,又或是系统架构的吞吐量问题。那如何确定呢?而我倾向于先从数据库动手。我的习惯做法是,使用数据库监控工具,先跟踪下Sql耗时情况。如果监控到耗时较长的SQL语句,那基本上就是数据库层次的问题,否则就是代码层次。若为代码层次,再研究完代码后,再细化为算法或架构层次问题。

确定问题种类后,是时候上工具来精准定位问题点了:

  • Sql耗时问题,推荐使用免费的Plan Explorer分析执行计划。
  • 代码问题定位,优先推荐使用VS自带的Performance Analysis,其次是RedGate的性能分析套件.NET Developer Bundle;然后还有Jet Brains的dotTrace — .NET performance profiler,dotMemory– .NET memory profiler;再然后就是反人类的Windbg;等等。

精准定位问题点后,就是着手优化了。相信到这一步,就是优化策略的选择了,这里就不展开了。

优化后,最后当然要进行测试了,毕竟优化了多少,我们也要做到心里有谱才行。

以上啰啰嗦嗦有点多,下面我们直接上案例。

代码优化案例

客户反馈销售订单100条分录行,保存进行可发量校验时,耗时7mins左右。

拿到这个问题后,本地重现后,监控sql耗时没有异常,那就着重分析代码了。因为可发量校验的业务逻辑极其复杂,又加上又直接再一个类文件实现该功能,3500+行的代码,加上零星注释,真是让人避之不及。逃避不是办法,还是上工具分析一把。

这次我选用的时VS自带的Performance Profiler,开发环境下极其强大的性能调优工具。针对我们当前案例,我们仅需要跟踪指定服务对应的dll即可,使用步骤如下:

  1. Analyze–>Profiler–>New Performance Session
  2. 打开Performance Explorer
  3. 找到新添加的Performance Session,右键Targets,然后选择Add Target Binary,添加要跟踪的dll文件即可
  4. 将应用跑起来
  5. 选中Performance Session,右键Attach对应进程即可跟踪分析性能了
  6. 在跟踪过程中,可随时暂停跟踪和停止跟踪
国内一线架构师的Java性能优化思路

跟踪结束后本案例跟踪到的采样结果如下图:

国内一线架构师的Java性能优化思路

同时Performance Profiler也给出了问题的建议,如下图:

国内一线架构师的Java性能优化思路

其中第1、4条大致说明程序I/O消耗大,第一代的GC上存在未及时释放的垃圾占比过高。而根据上图的采样结果,我们可以直接看出是由于再代码中频繁操作DataTable引起的性能瓶颈。走读代码发现的确如此,所有的数量统计都是在代码中循环遍历DataTable进行处理的。而最终的优化策略,就相当于一次大的重构,将所有代码中通过遍历DataTable的计算逻辑全部挪到SQL中去做。由于代码过多,就不再放出。

算法优化案例

某全流程跟踪报表超时。

这个报表是用来跟踪所有单据从下单到出库的业务流程数据流转情况。而所有的流程数据都是按照树形结果存储在数据库表中的,类似这样:

国内一线架构师的Java性能优化思路

图中的流程为:

销售合同–>销售订单–>发货通知单–>销售出库单

为了构造流程图,之前的处理方法是把流程数据取回来,通过代码构造流程图。这也就是性能差的原因。

而针对这种情况,就是考验我们平时经验积累了。对于树形结构的表,我们也是可以通过SQL来进行直接查询的,这就要用到了SQL Server的CTE语法来进行递归查询。

总结

性能调优是一个循序渐进的过程,不可能一蹴而就,重在平时的点滴积累。

总结下我的调优思路

  • 调整心态,积极应对
  • 了解性能背景, 收集证据, 尝试重现
  • 问题分类,先监控SQL耗时,大致确定是SQL或是代码层次原因
  • 使用性能分析工具,确定问题点
  • 调优测试

那如何学习才能快速入门并精通呢?

当真正开始学习的时候难免不知道从哪入手,导致效率低下影响继续学习的信心。

但最重要的是不知道哪些技术需要重点掌握,学习时频繁踩坑,最终浪费大量时间,所以有一套实用的视频课程用来跟着学习是非常有必要的。

为了让学习变得轻松、高效,今天给大家免费分享一套阿里架构师传授的一套教学资源。帮助大家在成为架构师的道路上披荆斩棘。

这套视频课程详细讲解了(Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构)等这些成为架构师必备的内容!

而且还把框架需要用到的各种程序进行了打包,根据基础视频可以让你轻松搭建分布式框架环境,像在企业生产环境一样进行学习和实践。

国内一线架构师的Java性能优化思路

后台私信回复“架构” 就可以马上免费获得这套价值一万八的内部教材!

最后,做一个爱思考,懂思考,会思考的程序员。


分享到:


相關文章: