Hibernate和Spring启动过多的数据库连接和150个请求/秒的高服务器负载

时间:2016-10-28 05:30:58

标签: java spring hibernate jpa spring-boot

我有春季启动应用程序,我正在使用JPA和hibernate与oracle数据库。在高吞吐量下,150个请求/秒的数据库停止允许数据库连接,并且数据库负载异常非常高。

这是我的数据库配置属性

spring.datasource.url=jdbc:oracle:thin:@<ip>:1521:<dbname>
spring.datasource.username=*******
spring.datasource.password=*******
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.initial-size=10
spring.datasource.maxActive=1200
spring.datasource.validationQuery=select 1 from dual
spring.jpa.hibernate.dialect = org.hibernate.dialect.Oracle10gDialect
spring.jpa.show-sql = true
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.datasource.pool-prepared-statements=true
spring.datasource.pool-prepared-statements-cache-size=250
spring.datasource.max-open-prepared-statements=250

spring.datasource.max-idle=50
spring.datasource.min-idle=10
spring.datasource.time-between-eviction-runs-millis=30000
spring.datasource.min-evictable-idle-time-millis=60000
spring.datasource.suspect-timeout=60
spring.datasource.log-abandoned=true

以下是我的例外

Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Could not open connection
    at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:286)
    at com.sun.proxy.$Proxy85.getConnection(Unknown Source)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139)
    at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228)
    ... 21 more
Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
    at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:392)
    at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:434)
    at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:687)
    at oracle.net.ns.NSProtocol.connect(NSProtocol.java:247)
    at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1102)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:320)
    ... 40 more
Caused by: java.net.SocketTimeoutException: connect timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:150)
    at oracle.net.nt.ConnOption.connect(ConnOption.java:133)
    at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:370)
    ... 45 more
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Could not open connection
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at net.bull.javamelody.MonitoringSpringInterceptor.invoke(MonitoringSpringInterceptor.java:73)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
    at com.sun.proxy.$Proxy133.updateDlrStatus(Unknown Source)
    at com.acl.otp.thread.DlrRequestHandler.updateDLRStatus(DlrRequestHandler.java:39)
    at com.acl.otp.thread.DlrRequestHandler.run(DlrRequestHandler.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Could not open connection
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1771)
    at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:64)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:170)
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380)
    ... 14 more
Caused by: org.hibernate.exception.JDBCConnectionException: Could not open connection
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:132)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:235)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)

2 个答案:

答案 0 :(得分:0)

您似乎正在重载数据库服务器/服务。

这没有一般的解决方案(没有“魔术子弹”),但你可以看看像:

  • 限制同时处理的请求数。
  • 使用分析器或其他监视来确定导致过多数据库负载的请求类型,并查看它们是否适合通过以下方式进行优化:
    • 优化SQL和/或数据库架构
    • 减少查询次数
    • 缓存常见查询的结果。
  • 增加前端和/或数据库可用的资源(核心,内存等);即获得更大/更快的机器。
  • 切换到本机SQL而不是使用JPA。 (至少对于使用最多的查询。)
  • 重新构建您的应用程序,以便可以“扩展”;例如使用非SQL数据库等复制前端和后端

请注意,这些都不能保证在所有情况下都能正常工作

答案 1 :(得分:0)

当达到数据库的最大连接数时,会发生与EntityManager相关的错误。解决这些类型的错误&#34;不要关闭会话工厂&#34;在休眠和关闭只会话(必须关闭)并确保&#34;连接池大小较小或以其他方式离开休眠默认连接池大小并使用单例设计模式创建sessionfactory对象&#34;。