Spring / Hibernate应用程序的性能调优

对于大多数典型的Spring / Hibernate企业应用程序,应用程序性能几乎完全取决于其持久层的性能。

这篇文章将讨论如何确认我们是否存在“数据库绑定”应用程序,然后逐步讲解7个经常使用的“快速取胜”技巧,这些技巧可以帮助提高应用程序性能。

如何确认应用程序是“数据库绑定的”

为了确认应用程序是“数据库绑定的”,首先在某些开发环境中使用VisualVM进行监视以进行典型运行。 VisualVM是JDK附带的Java Profiler,可通过调用jvisualvm通过命令行jvisualvm

启动Visual VM后,请尝试以下步骤:

  • 双击正在运行的应用程序
  • 选择采样器
  • 单击Settings复选框
  • 选择Profile only packages ,然后输入以下软件包:
    • your.application.packages.*

典型的“数据库绑定”应用程序的CPU配置文件应如下所示:

application_profile

我们可以看到,客户端Java进程花费了56%的时间来等待数据库通过网络返回结果。

这是一个很好的信号,表明对数据库的查询使应用程序运行缓慢。 Hibernate反射调用中的32.7%是正常的,对此无能为力。

调整的第一步–获得基线运行

进行调整的第一步是为程序定义基线运行。 我们需要确定一组功能上有效的输入数据,以使程序通过类似于生产运行的典型执行。

主要区别在于基线运行应在更短的时间内运行,作为指导原则,执行时间约为5到10分钟是一个很好的目标。

什么是好的基线?

良好的基线应具有以下特征:

  • 在功能上是正确的
  • 输入数据类似于生产中的各种数据
  • 它在很短的时间内完成
  • 基线运行的优化可以推断为完整运行

获得一个良好的基准可以解决一半的问题。

是什么导致基准差?

例如,在用于处理电信系统中的呼叫数据记录的批处理运行中,采用前10000条记录可能是错误的方法。

原因是,前10000个可能主要是语音呼叫,但是未知的性能问题在于SMS流量的处理。 取得大批运行的第一笔记录会导致我们得出错误的基准,从而得出错误的结论。

收集SQL日志和查询时间

可以使用例如log4jdbc来收集执行时间已执行的SQL查询。 请参阅此博客文章,了解如何使用log4jdbc收集SQL查询-Spring / Hibernate使用log4jdbc 改进了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工作站中使用,例如使用Cybwin或包含bash命令行的Git 。

经常应用的快速获胜

Swift取得成功的波纹管确定了Spring / Hibernate应用程序中的常见性能问题及其相应的解决方案。

快速共赢的技巧1 –减少主键生成开销

在“插入密集型”过程中,主键生成策略的选择可能很重要。 生成ID的一种常见方法是使用数据库序列,通常每个表使用一个序列,以避免不同表上的插入之间发生争用。

问题在于,如果插入了50条记录,我们希望避免对数据库进行50次网络往返以获取50个ID,而使Java进程大部分时间处于挂起状态。

Hibernate通常如何处理?

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

  • 调用一次序列并获得1000(高值)
  • 计算50个id像这样:
    • 1000 * 50 + 0 = 50000

因此,从单个序列调用中生成了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批处理插入/更新

对于批处理程序,JDBC驱动程序通常提供一种优化措施,以减少名为“ JDBC批处理插入/更新”的网络往返。 使用这些选项时,插入/更新在发送到数据库之前会在驱动程序级别排队。

当达到阈值时,整批排队的语句将一次性发送到数据库。 这样可以防止驱动程序一个接一个地发送语句,这会导致多个网络往返。

这是激活批量插入/更新所需的实体管理器工厂配置:

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

仅设置JDBC批处理大小不起作用。 这是因为JDBC驱动程序仅在收到完全相同的表的插入/更新时才批处理插入。

如果收到对新表的插入,则JDBC驱动程序将首先刷新上一个表上的批处理语句,然后再开始对新表上的批处理语句进行处理。

如果使用Spring Batch,则隐式使用类似的功能。 通过这种优化,您可以轻松地购买30%40%来“插入密集型”程序,而无需更改任何代码。

快速共赢的技巧3 –定期刷新并清除休眠会话

当在数据库中添加/修改数据时,Hibernate在会话中保留一个已经存在的实体版本,以防万一在关闭会话之前再次对其进行了修改。

但是很多时候,一旦在数据库中完成了相应的插入操作,我们就可以安全地丢弃实体。 这样可以释放Java客户端进程中的内存,从而避免了由于长时间运行的Hibernate会话而导致的性能问题。

应该尽可能避免这样长时间运行的会话,但是如果出于某种原因需要它们,这就是控制内存消耗的方法:

entityManager.flush();
entityManager.clear();

flush将触发来自新实体的插入将被发送到数据库。 clear会从会话中释放新实体。

快速共赢的秘诀4 –减少Hibernate脏检查的开销

Hibernate内部使用一种称为脏检查的机制来跟踪已修改的实体。 此机制不是基于实体类的equals和hashcode方法。

Hibernate尽最大努力将脏检查的性能成本降到最低,并且仅在需要时才进行脏检查,但是该机制的确有成本,这在具有大量列的表中更为明显。

在应用任何优化之前,最重要的是使用VisualVM评估脏检查的成本。

如何避免脏检查?

在我们知道是只读的Spring业务方法中,脏检查可以像这样关闭:

@Transactional(readOnly=true)
public void someBusinessMethod() {....
}

避免进行脏检查的另一种方法是使用Hibernate Stateless Session,在文档中对此进行了详细介绍 。

快速共赢的秘诀5 –搜索“不良”查询计划

检查最慢查询列表中的查询,看看它们是否有好的查询计划。 最常见的“不良”查询计划是:

  • 全表扫描:通常由于索引缺失或表统计信息过时而在对表进行完全扫描时发生。
  • 完全笛卡尔连接:这意味着正在计算多个表的完全笛卡尔乘积。 检查是否缺少连接条件,或者是否可以通过将步骤分成几个步骤来避免这种情况。

快速共赢的秘诀6 –检查错误的提交间隔

如果您正在执行批处理,则提交间隔可能会对性能结果产生很大的影响,例如快10到100倍。

确认提交间隔是预期的间隔(对于Spring Batch作业,通常约为100-1000)。 经常发生此参数配置不正确的情况。

快速双赢的秘诀7 –使用二级和查询缓存

如果某些数据被认为可以进行缓存,那么请查看此博客文章,了解如何设置Hibernate缓存: Hibernate二级/查询缓存的陷阱

结论

为了解决应用程序性能问题,最重要的措施是收集一些度量标准,以找出当前的瓶颈。

如果没有一些度量标准,通常不可能在有用的时间内猜测出正确的问题原因是什么。

另外,通过使用Spring Batch框架,可以首先避免“数据库驱动”应用程序的许多但不是全部典型性能缺陷。

翻译自: https://www.javacodegeeks.com/2014/06/performance-tuning-of-springhibernate-applications.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的学习开发环境,呵呵!

今天到电子市场去&#xff0c;花了近700块&#xff0c;弄了块ARM的学习单板&#xff0c;再也不用去搞什么虚拟机了&#xff01; 简单的看了一下开发手册&#xff0c;还有点麻烦&#xff0c;可能得花点时间去把它搞清楚&#xff01; 但这块单板的功能还是很强的&#xff0c;基本…

Jsの练习-数组常用方法

1. join() 方法&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Comp…

新手学习笔记Spring AOP全自动编程

业务类 package oyb.service;public interface IUserService {public void add();public void delete(); } package oyb.service;public class UserServiceImpl implements IUserService {Overridepublic void add() {System.out.println("添加用户。。。。");}Overr…

9 个鲜为人知的 Python 数据科学库

除了 pandas、scikit-learn 和 matplotlib&#xff0c;还要学习一些用 Python 进行数据科学的新技巧。Python 是一种令人惊叹的语言。事实上&#xff0c;它是世界上增长最快的编程语言之一。它一次又一次地证明了它在各个行业的开发者和数据科学者中的作用。Python 及其库的整个…

Spring4:具有Java 8 Date-Time API的@DateTimeFormat

在Spring 3.0中作为Formatter SPI的一部分引入的DateTimeFormat批注可用于解析和打印Web应用程序中的本地化字段值。 在Spring 4.0中&#xff0c; DateTimeFormat批注可以直接与Java 8 Date-Time API&#xff08; java.time &#xff09;一起使用。 在Spring中&#xff0c;可以…

JSF中run项目时候Tomcat8启动不了的一种方法

把另一个博客内容迁移到这 我的问题是Tomcat是可以启动的 但是run那个jsp的时候七月 10, 2016 3:14:54 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property source to org.eclipse…

elasticsearch_dsl.exceptions.ValidationException: You cannot write to a wildcard index.

elasticsearch_dsl.exceptions.ValidationException: You cannot write to a wildcard index. 这里是因为版本不匹配的问题 查看es版本方法如下&#xff1a; 查看elasticsearch包与elasticsearch-dsl版本方法&#xff08;pip list&#xff09;如下&#xff1a; 因为我的es是5.1…

在Java中对Singleton类进行双重检查锁定

Singleton类在Java开发人员中非常常见&#xff0c;但是它给初级开发人员带来了许多挑战。 他们面临的主要挑战之一是如何使Singleton保持为Singleton&#xff1f; 也就是说&#xff0c;无论出于何种原因&#xff0c;如何防止单个实例的多个实例。 对Singleton进行双重检查锁定是…

wstngfw中使用Viscosity连接OpenV-P-N服务器

wstngfw中使用Viscosity连接OpenV-P-N服务器 在本例中&#xff0c;将假设以下设置&#xff1a; 站点 A站点 B名称Beijing Office&#xff08;北京办公室&#xff09;名称Shenzheng Office&#xff08;深圳办公室&#xff09;WAN IP192.168.10.46WAN IP192.168.20.46LAN 子网192…

开张了!

今天开张了&#xff0c;试试看&#xff01; Code1using System; 2using System.Collections.Generic; 3using System.Text; 4 5namespace Model 6{ 7 public enum SiteType 8 { System,External,All}; 9 [Serializable]10 class SiteInfo11 {12 public i…

dubbo和zookeeper的关系

转载前言&#xff1a;网络上很多教程没有描述zookeeper和dubbo到底是什么关系、分别扮演了什么角色等信息&#xff0c;都是说一些似是而非的话&#xff0c;这里终于找到一篇文章&#xff0c;比较生动地描述了注册中心和微服务框架之间的关系&#xff0c;以及他们之间的合作分工…

Flink学习(二)Flink中的时间

摘自Apache Flink官网 最早的streaming 架构是storm的lambda架构 分为三个layer batch layerserving layerspeed layer一、在streaming中Flink支持的通知时间 Flink官网写了个了解streaming和各种时间的博客 https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-1…

RSS阅读器使用:ROME,Spring MVC,嵌入式Jetty

在这篇文章中&#xff0c;我将展示一些创建Spring Web应用程序的准则&#xff0c;使用Jetty以及使用名为ROME的外部库运行RSS来运行它。 一般 我最近创建了一个示例Web应用程序&#xff0c;充当RSS阅读器。 我想检查ROME以阅读RSS。 我还想使用Spring容器和MVC创建最简单的视图…

HZOJ string

正解炸了…… 考试的时候想到了正解&#xff0c;非常高兴的打出来了线段树&#xff0c;又调了好长时间&#xff0c;对拍了一下发现除了非常大的点跑的有点慢外其他还行。因为复杂度算着有点高…… 最后正解死于常数太大……旁边的lyl用同样的算法拿了90分我却拿了个暴力的分40……

Unity3D入门其实很简单

在上次发布拙作后&#xff0c;有不少童鞋询问本人如何学习Unity3D。本人自知作为一名刚入门的菜鸟&#xff0c;实在没有资格谈论这么高大上的话题&#xff0c;生怕误导了各位。不过思来想去&#xff0c;决定还是写一些自己的经验&#xff0c;如果能给想要入门U3D的您一些启发&a…

4. HTML表单标签

表单是网页中最常见的元素&#xff0c;也是用户和我们交互的重要手段&#xff0c;在网站中的登录、注册、信息更新这些功能都是依赖表单实现的。在HTML中对于表单提供了一系列的标签&#xff0c;即输入框、下拉框、按钮、文本域&#xff0c;如下是一个最常见的表单结构内容&…

为Lucene选择快速唯一标识符(UUID)

大多数使用Apache Lucene的搜索应用程序都会为每个索引文档分配唯一的ID&#xff08;即主键&#xff09;。 尽管Lucene本身不需要这样做&#xff08;它可能不太在乎&#xff01;&#xff09;&#xff0c;但应用程序通常需要它以后通过其外部ID替换&#xff0c;删除或检索该文档…

ubuntu16.04设置静态ip

最近在课堂上&#xff0c;有很多同学反映在搭建环境的时候&#xff0c;虚拟机ip经常变&#xff0c;那么我们配置好的web服务可能就不能用了。下面讲一下如何在ubuntu上面设置静态ip 1&#xff1a;首先我们确认一下ubuntu的版本 cat /etc/issue 或者sudo lsb_release -a或者unam…

Maven常用的构建命令

Maven常用命令&#xff1a; Maven库&#xff1a; http://repo2.maven.org/maven2/ Maven依赖查询&#xff1a; http://mvnrepository.com/ 一&#xff0c;Maven常用命令&#xff1a; 1. 创建Maven的普通Java项目&#xff1a; mvn archetype:create-DgroupIdpackageName-Dartifa…

课时85.层叠性(掌握)

1.什么是层叠性&#xff1f; 层叠性就是CSS处理冲突的一种能力。 这个字体最终会变为红色 注意点&#xff1a; 层叠性只有在多个选择器选中“同一个标签”,然后又设置了“相同的属性”&#xff0c;才会发生层叠性。 CSS全称&#xff1a;Cascading StyleSheet 层叠样式表&am…