我花了很多时间试图弄清楚导致我的应用程序工作的原因很慢,也许有人会帮我检查问题所在。
版本:
spring mvc: 4.2.5.RELEASE
hibernate: 4.3.11.Final
spring-data-jpa: 1.8.2.RELEASE
wildfly: 10
PostgreSQL Server: 9.4
OS: Debian GNU/Linux 7.9 (wheezy)
Server configuration: VPS, 1 proc, 4GB RAM
关于我的应用
简单的网络应用程序,包含静态JSP
着陆页,信息页和重定向到私有区的登录信息。公共页面是静态的,在登录期间首先查询数据库,然后尝试获取已登录用户的内容。
有什么问题:
当我浏览如下配置的页面时:
<http auto-config="true">
<intercept-url pattern="/" access="permitAll"/>
<intercept-url pattern="favicon.ico" access="permitAll"/>
<intercept-url pattern="/login/**" access="permitAll"/>
<intercept-url pattern="/info" access="permitAll"/>
...
</http>
没有问题,一切都在他的飞行中加载,没有停顿。它工作顺利。 当我发布/登录(将我重定向到/ main)然后当我在每个配置如此的网站上导航时:
<intercept-url pattern="/main/**" access="hasRole('ROLE_USER')"/>
<intercept-url pattern="/statistic/**" access="hasRole('ROLE_USER')"/>
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
有时会有一些极端延迟甚至长达1分钟。
Hibernate配置
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- Configure the entity manager factory bean -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="pl.portal.model"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<!-- <prop key="hibernate.dialect">pl.portal.sql.ProjectPsqlDialect</prop> -->
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="hibernate.jdbc.use_streams_for_binary">false</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.characterSet">UTF-8</prop>
</props>
</property>
</bean>
任何人都可以给我一个提示如何确定造成延误的原因吗?在我的浏览器中检查webinspect - &gt; / admin,大小7,89KB,大小:54secons(每个js或css不能超过100ms)
EDIT2:
删除了线程转储的无效片段,粘贴了在应用程序上调用操作/admin
后启动的线程的完整转储。线程花了61s
答案 0 :(得分:2)
这种延迟可能有很多原因,下面列出了一些最常见的延迟。
网络延迟,因为您提到静态页面和页面资源(如CSS)的服务器响应时间以毫秒为单位。
对于其他方面,像 VisualVM 这样的远程管理系统是找出导致延迟的原因以及哪个进程占用大量CPU时间的最佳工具。您也可以选择 JProfiler 等商业资讯制作者,但VisualVm也可以完美地完成工作。
要连接到ViusalVM,您需要有权访问您的服务器,并在JAVA_OPTS或您选择的任何地方添加JMX options并重新启动Web应用程序。
等待锁定的线程 - 可能存在一段代码,其中有一个锁定静态字段的同步方法。如果该方法允许假设处理数据库查询大约需要5秒钟。排队等待10个请求。然后,最后一个请求将在50秒或更长时间内处理。
如何检测这种瓶颈情况?
您可以浏览代码并查找获取锁定的所有位置并添加一些调试日志。但是,如果问题不在您的代码中并且可能来自某些第三方库,该怎么办?
我曾经遇到过Logger(log4j库)在日志文件翻转时会阻塞所有线程(大约10秒)的情况。通过代码审查无法检测到这种情况。
救援人员。 VisualVM可能是检测线程锁定引起的延迟的最佳分析器。这是你可以做的。
答案 1 :(得分:0)
关于如何分析性能,您可以关注以下几个方面:
监视数据库是平面简单使用RDBMS监视工具,如Query Monitor for DB2或其他东西,具体取决于供应商。
分析BNetwork,有许多不同的工具,但您需要做的是弄清楚延迟是什么以及网络速度是什么。
我相信我们可以假设在你的情况下,网络是正常的,或者至少不是很有可能存在问题。
要分析的第三件事是您的应用程序层,这是您需要适当的分析工具的地方。您可以使用免费的visualVM并随附jdk或者您可以使用已支付的套件。但是你可以试用版本。
您还可以使用分析工具分析内存。
执行 CPU采样后,您将能够确定应用程序的哪些区域导致延迟。 Yourkit还能够从Application层侧监视已执行的SQL。这样,您将获得SQL速度+执行它的延迟+传输结果集的时间。
常见的性能调整选择是:
休眠。对集合加载使用批处理,不要加入关系而不是FetchStrategy.SELECT。
确保您不执行任何笛卡尔产品等。
答案 2 :(得分:0)
服务器配置:VPS,1 proc,4GB RAM
您是否可以访问服务器?尝试运行top命令并查看CPU使用情况。你只有一个触发器,可能还有一些巨大的触发器。
开始查找性能问题的典型方法:
条件1您可以使用探查器连接 做吧。 jvisualvm,jconsole,NetBeans Profiler,perf等。
您应该注意总CPU时间。
条件2您无法连接探查器
是的,在这里你可以使用jstack来获取线程转储。获取java进程ID的jps。
之前不要进行预先优化,测量性能。 :)
更新以获取新信息后的答案。
在线程转储中你可以看到很多“sun.nio.ch.EPollArrayWrapper.epollWait”,试着看一些链接:
也许是你的情况。 epoll有一个bug。但是现在也发生了类似的情况。
答案 3 :(得分:0)
根据我的经验,您可能遇到数据库锁定问题。有一个sql锁定你的表一段时间。您的代码正在等待,然后锁被释放,您的代码继续。您可以monitor db lock来查找代码挂起时哪个sql锁定您的表。