2017-07-27 81 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

請勿嘗試同時更改兩者。在這種情況下追蹤發生的事情將更加困難。

相關問題