GenericObjectPool [maxTotal=8, blockWhenExhausted=true, maxWaitDuration=PT-0.001S, lifo=true, fairness=false, testOnCreate=false, testOnBorrow=false, testOnReturn=false, testWhileIdle=false, durationBetweenEvictionRuns=PT-0.001S, numTestsPerEvictionRun=3, minEvictableIdleTimeDuration=PT30M, softMinEvictableIdleTimeDuration=PT-0.001S, evictionPolicy=org.apache.commons.pool2.impl.DefaultEvictionPolicy@2aa6311a, closeLock=java.lang.Object@61f39bb, closed=false, evictionLock=java.lang.Object@249e0271, evictor=null, evictionIterator=null, factoryClassLoader=java.lang.ref.WeakReference@4893b344, oname=org.apache.commons.pool2:type=GenericObjectPool,name=pool, creationStackTrace=java.lang.Exception
at org.apache.commons.pool2.impl.BaseGenericObjectPool.<init>(BaseGenericObjectPool.java:407)
at org.apache.commons.pool2.impl.GenericObjectPool.<init>(GenericObjectPool.java:147)
at org.apache.commons.pool2.impl.GenericObjectPool.<init>(GenericObjectPool.java:130)
at org.springframework.amqp.rabbit.connection.PooledChannelConnectionFactory$ConnectionWrapper.<init>(PooledChannelConnectionFactory.java:183)
at org.springframework.amqp.rabbit.connection.PooledChannelConnectionFactory.createConnection(PooledChannelConnectionFactory.java:140)
at org.springframework.amqp.rabbit.connection.AbstractRoutingConnectionFactory.createConnection(AbstractRoutingConnectionFactory.java:141)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.checkMismatchedQueues(AbstractMessageListenerContainer.java:1863)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:1407)
at org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry.startIfNecessary(RabbitListenerEndpointRegistry.java:289)
at org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry.start(RabbitListenerEndpointRegistry.java:239)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
at ...Application.main(Application.java:10)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
, borrowedCount=157, returnedCount=149, createdCount=8, destroyedCount=0, destroyedByEvictorCount=0, destroyedByBorrowValidationCount=0, activeTimes=StatsStore [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], size=100, index=49], idleTimes=StatsStore [[15001, 1, 14996, 29999, 14998, 1, 14998, 29999, 14999, 14999, 14998, 14999, 14999, 0, 14998, 0, 6520, 44999, 0, 14996, 15000, 14998, 14998, 14999, 14999, 14999, 14999, 15000, 0, 15002, 30005, 14994, 14994, 15004, 15004, 791, 14993, 1, 14997, 1, 14993, 0, 14999, 0, 14998, 0, 14999, 1, 14997, 0, 14998, 0, 14998, 0, 14999, 0, 10112]], size=100, index=57], waitTimes=StatsStore [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], size=100, index=57], maxBorrowWaitDuration=PT0.082S, swallowedExceptionListener=null, factoryType=null, maxIdle=8, minIdle=0, factory=org.springframework.amqp.rabbit.connection.PooledChannelConnectionFactory$ConnectionWrapper$ChannelFactory@53a665ad, allObjects={IdentityWrapper [instance=AMQChannel(amqp://guest@192.168.138.86:5672/,1)]=Object: AMQChannel(amqp://guest@192.168.138.86:5672/,1), State: ALLOCATED, IdentityWrapper [instance=AMQChannel(amqp://guest@192.168.138.86:5672/,6)]=Object: AMQChannel(amqp://guest@192.168.138.86:5672/,6), State: ALLOCATED, IdentityWrapper [instance=AMQChannel(amqp://guest@192.168.138.86:5672/,7)]=Object: AMQChannel(amqp://guest@192.168.138.86:5672/,7), State: ALLOCATED, IdentityWrapper [instance=AMQChannel(amqp://guest@192.168.138.86:5672/,4)]=Object: AMQChannel(amqp://guest@192.168.138.86:5672/,4), State: ALLOCATED, IdentityWrapper [instance=AMQChannel(amqp://guest@192.168.138.86:5672/,8)]=Object: AMQChannel(amqp://guest@192.168.138.86:5672/,8), State: ALLOCATED, IdentityWrapper [instance=AMQChannel(amqp://guest@192.168.138.86:5672/,2)]=Object: AMQChannel(amqp://guest@192.168.138.86:5672/,2), State: ALLOCATED, IdentityWrapper [instance=AMQChannel(amqp://guest@192.168.138.86:5672/,5)]=Object: AMQChannel(amqp://guest@192.168.138.86:5672/,5), State: ALLOCATED, IdentityWrapper [instance=AMQChannel(amqp://guest@192.168.138.86:5672/,3)]=Object: AMQChannel(amqp://guest@192.168.138.86:5672/,3), State: ALLOCATED}, createCount=8, idleObjects=[], abandonedConfig=null]
I am not yet able to provide a minimum working example to easily reproduce this behaviour. It requires an application that runs for some time and is loaded with requests. At some point, the RabbitHealthIndicator stops working, that is, the liveness/readiness endpoints time out.
The channel pool should not get exhausted.
Not yet available.
In what version(s) of Spring AMQP are you seeing this issue?
Tested with 2.4.3 and 2.4.8
Describe the bug
We have a Spring Boot application that uses a
PooledChannelConnectionFactoryand aCachingConnectionFactoryinside aSimpleRoutingConnectionFactory(the default connection used is thePooledChannelConnectionFactory, the other one is only used for few requests which where not used when experiencing the described problem). We noticed that after some time and loading the application with (HTTP) requests, the container is shut down because the/actuator/healthendpoint stops responding.We traced it down to the channel pool being exhausted, that is, this line (
PooledChannelConnectionFactory.java:196) waits forever:We are using the default
RabbitHealthIndicatorprovided by theorg.springframework.boot.actuate.amqppackage, which does the check by executing:The connection configuration is straight forward:
We have a RabbitListener for incoming messages:
And send outgoing messages using
rabbitTemplate.convertSendAndReceive().This is the state of the pool when it stops working:
To Reproduce
I am not yet able to provide a minimum working example to easily reproduce this behaviour. It requires an application that runs for some time and is loaded with requests. At some point, the
RabbitHealthIndicatorstops working, that is, the liveness/readiness endpoints time out.Expected behavior
The channel pool should not get exhausted.
Sample
Not yet available.