`

Spring/Hibernate_应用性能优化的7种方法

 
阅读更多

via: http://www.csdn.net/article/2015-10-27/2826041

 

 

 

对于大多数典型的 Spring/Hibernate 企业应用而言,其性能表现几乎完全依赖于持久层的性能。此篇文章中将介绍如何确认应用是否受数据库约束,同时介绍七种常用的提高应用性能的速成法

 

如何确认应用是否受限于数据库

确认应用是否受限于数据库的第一步,是在开发环境中进行测试,并使用 VisualVM 进行监控。VisualVM 是一款包含在 JDK 中的 Java 分析器,在命令行输入 jvisualvm 即可调用。启用 Visual VM 之后,尝试以下步骤:

双击你正在运行的应用

选择 Sampler

点击 Settings 复选框

选择Profile only packages,然后输入下列包:

your.application.packages.*

org.hibernate.*

org.springframework.*

your.database.driver.package, 比如 oracle.*

点击 Sample CPU

如果应用性能受限于数据库,其 CPU 分析结果看起来会像下图

 

我们看到,客户端 Java 进程花在等待数据库从网络中返回结果的时间占56%。

看到数据库查询是导致应用运行缓慢的原因,其实是好兆头。Hibernate 反射调用占比32.7%是正常情况,无法进一步优化。

 

性能调优第一步:定义基准运行

性能调优的第一步是为程序定义基准运行,我们要定义一组能有效执行的输入数据,让程序基准运行与生产环境下的运行差不多。

主要的区别在于基准运行的耗时要小很多。作为参考,5到10分钟的执行时间比较不错。

 

什么是好的基准?

好的基准应该具备以下特征:

功能正确

输入数据的种类与生产环境下相似

在短时间内执行完毕

基准运行的优化方案可以外推至完整运行

定义好的基准是成功解决问题的一半。

 

什么是不好的基准

例如,通过批量运行处理通讯系统的电话数据记录,选取10000条记录就是错误的做法。

原因是:前10000条记录可能多为语音电话,而未知的性能问题可能发生在短信流量的处理过程中。一开始如果基准不够好,就会导致错误的结论。

 

收集 SQL 日志与查询时间

 

SQL 查询的执行语句与其执行时间可以通过 log4jdbc等方式收集。详细了解如何使用 log4jdbc 收集 SQL 查询信息,点击文章使用 log4jdbc 优化 Spring/Hibernate 应用 SQL 日志。

 

查询的执行时间是从 Java 客户端收集的,该时间包含查询数据库的来回网络调用。SQL 查询的日志如下:

 

16 avr. 2014 11:13:48 | SQL_QUERY /* insert your.package.YourEntity */ insert into YOUR_TABLE (...) values (...) {executed in 13 msec}

预处理语句也是很重要的信息来源,它们常常会透露出常用的查询类型。了解更多的日志讯息,可以查看文章:Hibernate 为什么/在何处使用该 SQL 查询?

 

通过 SQL 日志可以了解哪些指标? 

SQL 日志可以回答下列问题: 

哪些是执行过的最慢查询?

哪些是最常用的查询?

生成主键的耗时是多少?

是否有数据适合缓存?

 

如何解析 SQL 日志

 

对于大量的日志文件,最可行的解析方式就是使用命令行工具,该方法的好处是非常灵活,只要写一小段脚本或命令,我们可以抽取出几乎大多数指标。只要你喜欢,任何命令行工具都适用。

如何你习惯了 Unix 命令行,bash 或是一个好选择。Bash 也可以在 Windows 工作站使用,Cygwin 或 Git 都包含了 bash 命令行。

 

常用的速成法

 

下面介绍的速成法能找出 Spring/Hibernate 应用中常见的性能问题,以及对应的解决方案。

 

速成法1——减少生成主键的代价

在插入操作频繁的进程中,主键的生成策略很重要。生成 id 的一种常见方法是使用数据库序列,通常一张表一个 id,从而避免在不同表间进行插入时的冲突。

问题在于,如果要插入50条记录,我们希望为了获取这50个 id,可以避免50趟查询数据库的来回网络调用,让 Java 进程不一直等待。

 

Hibernate 通常如何解决此问题?

Hibernate 提供了优化的 ID 生成器以避免此问题。也即,对于序列,会默认使用 HiLo id 生成器。以下是 HiLo 序列生成器的工作方式:

 

调用一次序列,获得 1000 (高值)

用以下方式计算50个 id

1000 * 50 + 0 = 50000

1000 * 50 + 1 = 50001

...

1000 * 50 + 49 = 50049, 达到低值 (50)

为新的高值1001调用序列,依次类推

因此一次序列调用,可生成50个键,从而减少数次来回网络调用导致的负担。

这些优化的键生成器默认在 Hibernate 4中开启。如要禁用,可将 hibernate.id.new_generator_mappings 设置为 false。

 

为什么生成主键仍是一个问题?

问题在于,如果你声明键生成策略为 AUTO,且未启用优化的键生成器,那么应用最后会面临大量的序列调用。

为了确保启用优化的键生成器,请将键生成策略改为 SEQUENCE 而非 AUTO。

@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "your_key_generator")

private Long id;

改变设定之后,在插入操作频繁的应用中能看到10%到20%的性能提升,而且几乎没有改动代码。

 

速成法2——使用 JDBC 批处理 inserts/updates

对于批处理程序,JDBC 驱动程序提供了旨在减少网络来回传输的优化方法:”JDBC batch inserts/updates“。使用该方法后,插入或更新会先在驱动层排队,然后再传送到数据库。

当达到阈值后,所有排队的语句都会一次性传给数据库。这可以避免驱动程序逐一传送语句,导致网络来回传送的负担。

经过以下配置,就能激活批处理 inserts/updates:

<prop key="hibernate.jdbc.batch_size">100</prop>  

<prop key="hibernate.order_inserts">true</prop>  

<prop key="hibernate.order_updates">true</prop>  

仅设置 JDBC 批处理大小并不够。因为 JDBC 驱动程序只会在收到对同一张表 insert/updates 时批处理这些语句。

如果收到对一张新表的插入语句,JDBC 驱动程序会先清除对前一张表的批处理语句,然后开始分批处理针对新表的 SQL 语句。

Spring Batch 内置了相似的功能。该优化能在插入操作频繁的应用中带来30%到40%的性能提升,而不用改动任何代码行。

 

速成法3——定期清理 Hibernate 会话

在向数据库添加或修改数据时,Hibernate 会在会话中保留一版已经存在的实体,以防在会话关闭之前这些实体再度被修改。

但是,多数情况下,一旦对应的插入操作已经在数据库中完成,我们就可以安心地丢弃那些实体。这会释放 Java 客户端进程中的内存,避免过久的 Hibernate 会话导致的性能问题。

这种长久的会话应该尽量避免。但如果出于某种原因不得不使用它们,以下是控制内存消耗的方法:

entityManager.flush();

entityManager.clear();

flush 会触使新实体中的插入语句传送至数据库。clear 则会释放会话中的新实体。

 

速成法4——减少 Hibernate dirty-checking(脏数据检查) 的代价

Hibernate 内部使用了一种机制用于追踪被修改的实体,名为 dirty-checking。该机制并不基于实体类中的 equals 和 hashcode 方法。

Hibernate 尽可能将 dirty-checking 的性能成本保持在最低值,只在需要时使用 dirty-check。但是该机制也有成本,在列数很多的表中该成本尤其可观。

在进行任何优化之前,最重要的是使用 VisualVM 测量 dirty-checking 的成本。

 

如何避免 dirty-checking ?

dirty-checking 可以通过以下方式禁用:

@Transactional(readOnly=true)

public void someBusinessMethod() {

....

}

禁用 dirty-checking 的另一种方式是使用 Hibernate 无状态会话,预知详情请查看文档。

 

速成法5——搜索”坏“查询计划

检查最慢查询列表,看看有没有好的查询计划。最常见的”坏“查询计划包括:

全表搜索:通常缺少一个索引或表统计过期时进行全表搜索。

全笛卡尔连接:意思是计算多张表的全笛卡尔乘积。检查一下缺少的连接条件,或拆分为几个步骤以简化查询。

 

速成法6——检查错误的提交间隔

如果你使用批处理程序,提交间隔会对性能造成十倍甚至百倍的影响。

请确保提交间隔是符合预期的(对于 Spring 批任务,通常是100到1000之间)。经常,该参数的配置不正确。

 

速成法7—— 使用二级查询缓存

如果一些数据可以缓存,则可以查看本文了解如何设置 Hibernate 缓存:Hibernate 二级/查询缓存的陷阱。

 

结论

解决应用性能问题的关键,在于通过收集一些指标发现当前的瓶颈。

没有一些测量指标,往往无法在短时间内找到真正的问题根源。

此外,很多典型的数据库驱动应用的性能陷阱,如果一开始就使用了 Spring Batch,就能够避免。

 

  • 大小: 42.4 KB
分享到:
评论

相关推荐

    Struts+Spring+Hibernate_upload_and_download.rar_Spring+Hibernate

    Struts、Spring 和 Hibernate 是Java开发中常用的三大框架,它们分别负责不同的职责,共同构建了企业级应用的基础架构。在“Struts+Spring+Hibernate_upload_and_download.rar_Spring+Hibernate”这个压缩包中,我们...

    spring_hibernate_annotation的三种实现

    Spring是一个全面的后端开发框架,提供依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)等特性,而Hibernate则是一个强大的对象关系映射(ORM)工具,简化了Java应用程序对数据库的操作。当结合使用时,...

    Spring_Hibernate_Struts2整合

    【Spring_Hibernate_Struts2整合】是Web开发中常见的技术栈整合,主要涉及Spring、Hibernate和Struts2这三个主流的Java EE框架。整合这三大框架可以让应用具备强大的数据持久化能力、灵活的业务逻辑处理以及高效的...

    FF.MSOL.SOA.rar_jpa hibernate_spring hibernate_spring mvc

    Hibernate是JPA的一个实现,它提供了更丰富的功能和更强大的性能优化选项。Hibernate不仅支持JPA规范,还增加了自己的API,如Criteria查询、HQL(Hibernate Query Language)等,使得数据库操作更加灵活和高效。此外...

    基于Spring_Hibernate_Flex架构的教学资源库设计与实现

    本文将介绍如何基于Spring、Hibernate和Flex这三个开源框架整合出一个新的Web应用开发模型,用于构建教学资源库系统。 #### 二、系统技术架构设计 ##### 2.1 数据库设计 系统采用了MySQL作为数据库管理系统。...

    Struts2+Spring+Hibernate_Demo

    Struts2+Spring+Hibernate(SSH)是一种经典的Java Web开发框架组合,被广泛应用于企业级应用的开发中,尤其在实现数据持久化、业务逻辑控制和视图展示方面有着显著的优势。这个名为"Struts2+Spring+Hibernate_Demo...

    基于Struts+Hibernate+Spring的Web_应用开发

    本实训指导书旨在帮助学生深入理解并掌握基于Struts、Hibernate与Spring三种技术的Web应用开发流程与技巧。通过分阶段的学习和实践,使学生能够熟悉这三种技术的基本原理与应用场景,并最终能够运用它们来构建一个...

    filesystem-master_java_springdatajpa_springboot_hibernate_文件服务器_

    Spring Data JPA提供了一种声明式的方式,通过简单的方法签名就能实现对数据库的CRUD(创建、读取、更新、删除)操作,减少了编写大量的SQL代码的需要。 **Spring Boot** Spring Boot是Spring框架的一个扩展,用于...

    spring/hibernate/mail/mysql-connector-java-5.1.22-bin.jar

    标题中的"spring/hibernate/mail/mysql-connector-java-5.1.22-bin.jar"提到了四个关键的Java技术框架或库,分别是Spring、...在实际开发中,我们还需要注意版本兼容性、安全性和性能优化等问题,确保应用的稳定运行。

    中国移动业务管理系统(struts_spring_hibernate)下载地址

    中国移动业务管理系统是一款基于Struts、Spring 和 Hibernate 这三大框架构建的企业级应用系统。该系统主要面向中国移动内部业务管理需求设计,涵盖了业务流程管理、客户关系管理、账务处理等多个方面,能够有效提升...

    gwt+spring+hibernate

    它将Java代码编译成优化过的JavaScript,使得开发者可以利用Java的强类型和丰富的库来构建高性能的浏览器端应用。GWT还提供了自动数据绑定、异步RPC通信和丰富的UI组件,简化了前端开发。 2. **Spring Framework**:...

    spring和hibernate整合的优化配置

    - **利用Spring提供的缓存管理机制**:Spring提供了对Hibernate一级缓存和二级缓存的支持,合理利用缓存可以显著提升应用性能。 - **性能调优**:通过对Hibernate配置参数进行调优,比如设置合理的缓存策略、调整...

    compass_hibernate_spring2.zip

    Compass 是一个全文搜索引擎,Hibernate 是一个流行的 Java ORM(对象关系映射)框架,而 Spring 是一个全面的企业级应用开发框架,尤其在依赖注入和事务管理方面表现卓越。这三者的结合可以实现高效的搜索功能以及...

    memcache也spring,hibernate的配置

    综上所述,这个项目展示了如何在Java环境下,利用Maven构建工具,将Memcached、Hibernate和Spring集成,实现高效的数据缓存策略,提升应用性能。对于开发人员来说,理解和掌握这些配置能帮助他们更好地优化大型...

    Hibernate/Spring/Structs2 In Action

    《Hibernate/Spring/Structs2 In Action》是一个涵盖了三个核心Java EE框架的综合学习资源,包括Spring、Hibernate和Struts2。这些框架是企业级Java应用程序开发中的关键组件,广泛用于构建可扩展、高效且易于维护的...

    非注解Springmvc+spring+hibernate 入门实例

    在IT行业中,Spring框架是Java企业级应用开发的首选框架,它提供了丰富的功能,包括依赖注入、面向切...在实践中,你可能会遇到如何处理异常、如何进行事务管理、如何优化查询性能等问题,这些都是进一步提升的关键点。

    java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider

    二级缓存是Hibernate性能优化的一种手段,它存储了之前查询过的对象,以便于快速访问,减少对数据库的直接查询。 这个问题可能是由以下几个原因引起的: 1. **缺失的依赖**:最常见的情况是项目的类路径或Maven/...

    轻量级Java EE企业应用实战_Struts 2_Spring3_Hibernate(第三版)

    此外,还会涉及测试策略、性能优化以及部署技巧,帮助读者理解如何在实际项目中应用这些技术。 这本书是Java EE开发者不可或缺的参考资料,无论你是初学者还是有经验的开发者,都能从中受益。通过深入学习和实践,...

    JSF+Hibernate_Spring

    3. **优化性能**:通过Spring的缓存支持,可以提高数据访问的效率。 4. **安全性和测试性**:Spring提供了安全框架和单元测试支持,增强了应用的安全性和可测试性。 在给定的文件列表中,`readme.txt`可能是项目...

Global site tag (gtag.js) - Google Analytics