RabbitMQ影响JDBC连接池 - java

我有一个运行良好的Web servlet。我决定用RabbitMQ替换与后端服务器的TCP连接。在进行一些负载测试时,我注意到它很快开始失败,超时等待空闲的JDBC连接。

ERROR [http-bio-8080-exec-12] JDBCExceptionReporter.logExceptions(234) | Cannot get a connection, pool error Timeout waiting for idle object
DEBUG [http-bio-8080-exec-12] JDBCExceptionReporter.logExceptions(225) | Cannot open connection [???]
org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
    at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:114)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:85)
    at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
    at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
    at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:160)
    at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:81)
    at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:560)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:438)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:261)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at net.hedtech.degreeworks.security.service.ShpPassportService$$EnhancerBySpringCGLIB$$9c441f05.getAndCheckPassportForRequest(<generated>)
    at net.hedtech.degreeworks.security.spring.ShpPassportFilter.doFilter(ShpPassportFilter.java:124)
    at net.hedtech.degreeworks.security.spring.ShpPassportFilter$$FastClassBySpringCGLIB$$8067e598.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
    at com.sungardhe.degreeworks.util.SpringBeansProfiler.aroundAdvice(SpringBeansProfiler.java:92)
    at sun.reflect.GeneratedMethodAccessor167.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at net.hedtech.degreeworks.security.spring.ShpPassportFilter$$EnhancerBySpringCGLIB$$c08501d.doFilter(<generated>)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
    at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1174)
    at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)

在这一点上,我还没有实现任何合并。 RabbitMQ连接是所有会话线程之间共享的单例。将为每个请求打开和关闭通道。

我的研究尚未建立RabbitMQ和jdbc连接池之间的任何连接,但我必须承认,我对这两个都只有一个了解。

这是我正在使用的代码:

String requestQueueName = "dw-dev-prototype";

QueueingConsumer consumer;

Channel channel = null;
String correlationId = UUID.randomUUID().toString();
String thisResponse = null;
String totalResponse = "";
StringBuffer sbResponse;
// We will create a new reply queue for each request
String replyQueueName = "";

try
{
   // We will send the replyQueueName with the request so the server knows how to send the
   // response back to us
   channel = _connection.createChannel();
   replyQueueName = channel.queueDeclare().getQueue();
   consumer = new QueueingConsumer(channel);
   channel.basicConsume(replyQueueName, AUTO_ACKNOWLEDGE, consumer);
   BasicProperties props = new BasicProperties.Builder().correlationId(correlationId).replyTo(replyQueueName)
      .build();
   channel.basicPublish(NO_EXCHANGE, requestQueueName, props, sNameValuePairs.getBytes("UTF-8"));
}
catch (IOException e)
{
   log.error("New connection IOException: " + e.getMessage(), e);
   abortConnection(_connection, channel);
   throw new RuntimeException(e);
}

while (true)
{
   QueueingConsumer.Delivery delivery;
   try
   {
      // Get the next response
      delivery = consumer.nextDelivery();
      thisResponse = new String(delivery.getBody(), "UTF-8");
      // Ignore the response if it is not for our correlation-id
      else if (delivery.getProperties().getCorrelationId().equals(correlationId))
      {
         if (thisResponse.equals(this._serviceFinishedMsg))
         {
            // No more text for this response - we are done
            break;
         }
         else
         {
            totalResponse += thisResponse;
         }
      }
   }
   catch (ShutdownSignalException | ConsumerCancelledException | InterruptedException e)
   {
      log.error("Consumer exception: " + e.getMessage(), e);
      throw new RuntimeException(e);
   }
   catch (UnsupportedEncodingException e)
   {
      log.error("UnsupportedEncoding exception: " + e.getMessage(), e);
      throw new RuntimeException(e);
   }

}

// Close now that we are done
try
{
   if (channel != null && channel.isOpen())
   {
      channel.close();
   }
}
catch (IOException | TimeoutException e)
{
   log.error("Error closing channel or connection", e);
}

我在Tomcat容器中运行它。我正在使用Spring,但还没有使用Spring AMQP。

JDBC调用位于安全过滤器中,该过滤器在请求到达此方法之前运行。

关于如何解决此问题的任何提示都将受到欢迎。

提前致谢。

java大神给出的解决方案

您发起的调用调用了aop-> spring service-> hibernate。 Hibernate正在调用Commons dbcp并请求一个连接池。您可能耗尽了该池的连接,或者数据库变得无法访问。我会投票给前者。

将java melody集成到您的应用中,然后再次部署。监视连接池,并检查是否耗尽。如果你做...

考虑增加连接池限制
如果增加连接池限制没有帮助,则可能是dbcp池泄漏。研究是否将连接正确返回到池中。

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

如何修改休眠的SQL查询? - java

我有点好奇,有没有办法修改hibernate的核心,以便我可以自定义生成的SQL query。例如,在生成的查询中添加功能以使用connect by prior(oracle)或我要自定义的任何其他子句。 java大神给出的解决方案 起初,这样的问题总是在我心中敲响警钟。你被警告了...AFAIK,hibernate使用所谓的dialects进行特定的优化。…

用Java构建大批量数据处理工具 - java

Closed. This question needs to be more focused。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过editing this post专注于一个问题。 3年前关闭。 Improve this question 我正在尝试使用Java构建ETL工具。 ETL工具用于对大量数据(关系型和其他类型)进行批量读取,…

用Java封装对象? - java

private中的Java提供类级别的封装。可以封装一个对象吗?还是这样做徒劳?例如,如果我们将一个类定义为 public class Person { private String ssn; private ArrayList<Person> friends = new ArrayList<Person>(); public voi…

光学标记阅读器的开源库 - java

Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以使为on-topic。 6年前关闭。 Improve this question 我想要一个用于光学标记读取(OMR)的开源库,有没有这样的库?我想将此库与我的Java应用程序一起使用。…