春兔 - 信号量许可证泄漏导致"No available channels"异常



我们使用CachingConnectionFactory为我们的消费者服务。随着每次连接断开,我都看到一个结帐许可证被收购并且永远不会发布。因此,假设我们使用默认缓存通道大小 25,下次,当连接在丢弃后恢复时,可用许可证的数量将为 24。一段时间后,导致许可证数量为0,从而导致异常AmqpTimeoutException("无可用通道">(。

我在版本 1.6.10-RELEASE、1.7.3-RELEASE 和 2.0.0-BUILD-SNAPSHOT 中观察到了这种行为。

是否有可能我们以错误的方式使用库,我们应该处理 checkoutPermit 的手动发布,可能是通过自己关闭频道?(releasePermitIfEssential在连接断开后永远不会被调用(

提前谢谢。


示例(使用 1.7.3-发布(

配置

@Configuration
public class Config {
@Bean
public CachingConnectionFactory cachingConnectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
connectionFactory.setUsername("username");
connectionFactory.setPassword("password");
connectionFactory.setVirtualHost("vhost");
connectionFactory.setChannelCheckoutTimeout(1200);
connectionFactory.setConnectionTimeout(1000);
connectionFactory.setPort(5672);
return connectionFactory;
}
@Bean
public SimpleMessageListenerContainer simpleMessageListenerContainer(CachingConnectionFactory cachingConnectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(cachingConnectionFactory);
container.setQueueNames("test.queue");
container.setMessageListener(new MessageListenerAdapter(new TestHandler()));
container.start();
return container;
}
}

处理程序(仅供测试(

public class TestHandler {
public String handleMessage(byte[] textBytes) {
String text = new String(textBytes);
System.out.println("Received: " + text);
return text;
}
}

我通过使用 RabbitMQ和我的应用程序之间的代理来测试连接丢弃,在那里我手动断开了与 RabbitMQ 的连接。

已确认。

这绝对是错误。当我们失去连接时,我们也失去了所有频道。因此,我们必须重置相关的许可证。

请提出具有正确描述的JIRA票证。

同时,我想作为一种解决方法,您不应该使用etChannelCheckoutTimeout(1200)并将其保留为0,默认值是什么:

/**
* Sets the channel checkout timeout. When greater than 0, enables channel limiting
* in that the {@link #channelCacheSize} becomes the total number of available channels per
* connection rather than a simple cache size. Note that changing the {@link #channelCacheSize}
* does not affect the limit on existing connection(s), invoke {@link #destroy()} to cause a
* new connection to be created with the new limit.
* <p>
* Since 1.5.5, also applies to getting a connection when the cache mode is CONNECTION.
* @param channelCheckoutTimeout the timeout in milliseconds; default 0 (channel limiting not enabled).
* @since 1.4.2
* @see #setConnectionLimit(int)
*/
public void setChannelCheckoutTimeout(long channelCheckoutTimeout) {

相关内容

最新更新