开篇

 这篇文章是对过去一个星期困扰自己的性能问题排查解决的一个总结,希望对其他人能够有所帮助,也希望在百度或者google的搜索引擎中能够被检索,因为在我解决问题的过程中我也是花了好长时间才找到一个相关的文章,同样我会在 Stack Overflow上发布这个问题,希望能够帮到更多的人。

背景

 简单的系统架构图如下,核心代码在service action模块当中,其中service action是一个通过java的ExecutorService实现并发的多任务处理,在单个任务当中做的主要包括3大块:分别是大量for循环计算fastjson反序列化大量的Double.parsedouble计算

jdk1.7下Double.parseDouble性能问题排查
服务分层图.png

解决思路

 其实在整个问题排查过程中,我们也是摸着石头过河,把一个个的性能损耗的代码逐个排除。整个解决思路大概是下面这样一个过程:

  • 减少不必要的for循环,我们把从数据源头上限制了for循环次数,但优化效果有限。
  • 减少不必要的fastjson反序列化,但优化效果也同样有限。
  • 剩下的代码逻辑只有大量的并发的Double.parseDouble的计算逻辑,剩下的唯一怀疑对象。
  • dalelane的链接上找到了这个问题的原因,概括来说就是在jdk1.7下并发的大量Double.parseDouble操作会引起锁竞争引起连锁性能问题。
  • 这句话是为了SEO优化,本质上Double.parseDouble在单次调用下性能非常客观,但是在多线程并发调用的情况下会因为lock锁竞争机制导致速度非常慢,而且这个问题只在jdk1.7上才出现,在jdk1.8上已经修复解决了。
    jdk1.7下Double.parseDouble性能问题排查
    并发问题.png

    jdk1.7下Double.parseDouble性能问题排查
    解决方案.png

发现问题

 本质解决问题的前提是需要发现问题,而我之所以遇到这个问题是因为我想可视化内部系统调用耗时,也是出于这个目的我引入Hystrix这个熔断神器用来发现超时问题。
 众所周知dubbo服务可以在provider配置超时限制,但是从provider的角度来说很难知道自己内部的耗时详情,所以在dubbo的filter层当中引入Hystrix的超时机制,Hystrix设置超时后可以对外服务时候实现超时提前结束请求,内部其实还是在继续执行的,所以我详细记录了每个超时范围内的请求个数,从而可以明确的知道耗时情况,然后发现问题并准备解决。
 让整个执行过程可视化是一个很好且很实用的原则。


优化效果

 性能直接提升50%,以下图中可以看出耗时基本腰斩(40ms降到20ms),超时次数跌0.


jdk1.7下Double.parseDouble性能问题排查
image.png

参考链接

http://dalelane.co.uk/blog/?p=2936

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-01-21
  • 2021-10-12
  • 2021-11-08
  • 2021-10-28
  • 2021-06-05
  • 2021-12-14
猜你喜欢
  • 2022-02-10
  • 2021-08-23
  • 2021-08-17
  • 2021-08-13
  • 2022-12-23
  • 2022-12-23
  • 2021-06-21
相关资源
相似解决方案