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

开篇

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

背景

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

服务分层图.png

解决思路

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

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

    解决方案.png

发现问题

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


优化效果

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


image.png

参考链接

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,715评论 19 139
  • Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难。随着10多年Java平台的改...
    程序员技术圈阅读 4,964评论 0 65
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 32,329评论 2 89
  • 转 # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    吕品㗊阅读 10,170评论 0 44
  • 文/白若狐 我做月子的时候,已经是春天了,但冬的寒冷还在苟延残喘。所以窗户外面的那几棵树还是可怜的举着光秃秃的枝丫...
    白若姝阅读 364评论 1 3

友情链接更多精彩内容