2017-07-27 79 views
0

我有一个使用默认嵌入式tomcat(使用tomcat jdbc连接池)运行的spring启动应用程序。这是生产和运行良好。我使用mysql作为我的数据库。Undertow与弹簧启动应用程序一起使用时的问题

我现在做一些压力测试在我的测试环境,并试图看看,如果我得到任何明显的好处,如果我从嵌入的Tomcat嵌入式暗潮切换。人们声称通过这样做可以显着提高吞吐量,这是由于进程请求处理的异步性质。

我知道如何排除tomcat并添加下载到启动应用程序。这样做后,我试图运行我的压力测试脚本来大致生成每秒500个请求,在此负载下运行5分钟并查看它的行为。当我这样做时,在最初的几秒钟之后,我开始间歇性地获取如下给出的jdbc异常。

org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection 
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431) ~[spring-orm-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) ~[spring-tx-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:426) ~[spring-tx-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:275) ~[spring-tx-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) ~[spring-data-jpa-1.10.2.RELEASE.jar!/:na] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.2.RELEASE.jar!/:4.3.2.RELEASE] 

这意味着JDBC连接不能获取。

注意:如果我删除嵌入式暗流,并再次嵌入的Tomcat添加到我的应用程序,然后同样的测试运行没有任何JDBC连接相关的异常精细。

我的底层Tomcat-jdbc-pool有100个数据库连接。对于错误,我尝试了100个工作线程和100个io线程。

我也尝试使用HikariCP而不是默认的tomcat-jdbc-pooling。我尝试使用maximumPoolSize = 100和connectionTimeOut = 60000的HikariCP。在此压力测试下,嵌入式Tomcat + HikariCP仍然运行良好。但是嵌入式Undertow + HikariCP给出了类似的例外。

因此,当我在图片中引入Undertow时会发生不同的事情。但我无法理解它。请注意,这些例外情况是间歇性的,但是在使用Undertow时我的压力测试的每次运行都会出现这种情况。

我通常搜索这样的问题。一般来说,我不会为Undertow找到这样的普通婴儿床。

任何分析情况的帮助都会节省很多时间。

回答

0

首先你可能会更好地改变一件事物,以减少潜在的问题。

Undertow - 100个IO线程太多了。你可能应该坚持使用默认值,我相信每个内核有1个IO线程。 IO线程仅用于管理打开的连接并处理任何非阻塞工作。 JDBC SQL查询处于阻塞状态,所以您需要确保阻塞的任何端点都将请求分派给工作线程。你可以使用BlockingHandler来做这件事,我不知道如何用Spring做。再次100个工作线程可能会有点过分,默认值会低得多,我相信20-30的范围。在切换到HikariCP之前,请确保它与现有的连接池正常工作。我建议只保留线程池的默认值来启动,并确保你正在调度到工作线程。

HikariCP-100连接对于HikariCP也非常重要,除非您有很多非常长时间的运行查询。更多信息about connection pool sizing

请勿尝试同时更改两者。在这种情况下追踪发生的事情将更加困难。

相关问题