诊断Java代码中常见的数据库性能热点问题

发表于:2016-05-04来源:infoq作者:Andreas Grabner and点击数: 标签:数据库
当我在帮助一些开发者或架构师分析及优化Java应用程序的性能时,关键往往不在于对个别方法进行微调,以节省一或两微秒的执行时间。虽然对某些软件来说,微秒级的优化确实非常重

  当我在帮助一些开发者或架构师分析及优化Java应用程序的性能时,关键往往不在于对个别方法进行微调,以节省一或两微秒的执行时间。虽然对某些软件来说,微秒级的优化确实非常重要,但我认为这并非着眼点所在。我在2015年间对数百个应用进行了分析,发现多数性能与可伸缩性问题都来源于糟糕的架构决策、框架的错误配置、错误的数据库访问模式、过量的日志记录,以及由于内存过度消耗而导致的垃圾回收所带来的影响。

  在我看来,性能工程的根本在于通过大量的观察,将关键的架构指标、可伸缩性指标以及性能指标关联在一起。通过对每次构建的结果以及不同负载情况下的表现进行分析,以发现系统中的回归缺陷或瓶颈所在。以下图中的仪表板作为示例:

  (点击放大图像)

  通过将系统负载、响应时间与SQL语句的执行次数等指标相关联,可得出某些性能工程方面问题的根本原因。

  最上面一张图叫做“层分解”图表,它显示了你的应用中各个逻辑组件(例如Web Service、数据库访问、业务逻辑、Web服务器等等)的总体执行时间。红色部分所表示的是某个后端Web Service所花费的时间,很明显这里产生了一个组件热点。我们同时可以发现,该Web Service并没有承受异常的负载,因为从第二张图来看,当时应用程序所处理的请求数量这条线比较平稳。一般情况下,整体响应时间多数都耗费在数据层,但这并不代表数据库本身的速度缓慢!我了解,低效的数据库访问往往是造成性能不佳的主要原因,因此通常会结合分析SQL语句的执行次数。在这个示例中,已经能够很清楚地看到它与大多数响应时间的峰值是相关的。

  相关厂商内容

  一路走来技术人的创业故事

  未来物联网中智能硬件的角色

  人工智能的技术版图

  GMTC全球移动技术大会,8折优惠!

  滴滴出行iOS客户端架构演进之路

  相关赞助商

  ArchSummit深圳2016将于7月15-16在华侨城洲际大酒店举行,现价8折抢购,团购报名更多优惠!

  我所观察到最常见的问题模式就是糟糕的数据库访问模式,此外还有过于细粒度的服务调用、糟糕的共享数据访问共享、过度的日志记录,以及由内存泄露以及大量的对象创建所导致的垃圾回收影响或是应用程序的崩溃。

  可选的诊断工具

  在本文中,我将专注于探讨数据库方面的问题,因为我十分确信你的所有应用都是因这些访问模式中的某一种而产生问题的!你可以在市场上已有的各种性能诊断、追踪,或是APM工具之间随意选择,不过我所选择的是免费的Dynatrace Personal License。Java本身也提供了各种出色的工具,例如Java Mission Control等等。许多提供数据访问功能的框架也经常通过其日志输出提供各种诊断选项,例如Hibernate或Spring等等。

  在使用这些跟踪工具时,通常不需要对代码进行任何修改,因为他们都利用了JVMTI(JVM Tooling Interface)以捕获代码层面的信息,甚至能够跨远程的各层次进行调用追踪,这一点对于分布式、面向(微)服务的应用来说非常实用。你所要做的就是修改你的JVM启动命令行选项,以加载这些工具。某些工具的开发商还提供了与IDE的集成功能,你只需简单地表示“在运行时开启XYZ性能诊断功能”。我在YouTube上做了一个简单的视频指南,演示了如何对在Eclipse中启动的应用进行追踪。

  找出数据库的性能热点

  即使你已经发现造成应用整体响应时间过长的主要原因在于数据库,但也不要因此就轻率地指责数据库与DBA!造成数据库繁忙的原因可能有以下几种:

  对数据库的使用过于低效:错误的查询设计、糟糕的应用程序逻辑、对于数据访问框架的配置不正确

  糟糕的数据库设计与数据结构:表的关联、缓慢的存储视图、缺失的或错误的索引、过期的表统计信息

  不恰当的数据库配置,例如内存、磁盘、表空间、连接池等等

  在本文中,我将着重讲解如何在应用程序端将访问数据库所消耗的时间减至最低:

原文转自:http://www.infoq.com/cn/articles/Diagnosing-Common-Java-Database-Performance-Hotspots