alkis alkis - 4 months ago 25
Java Question

Increase heartbeat value in spring rabbit

I'm facing some problems with my setup and I'm trying to increase the heartbeat interval in order to test a possible fix.
I'm using

Spring boot 1.3.2.RELEASE
Spring rabbit 1.5.3.RELEASE


And the code instantiating the connection factory is the below

RabbitConnectionFactoryBean connectionFactoryBean = new RabbitConnectionFactoryBean();
connectionFactoryBean.setUseSSL(useSsl);
connectionFactoryBean.setHost(rabbitHostname);
connectionFactoryBean.setVirtualHost(rabbitVhost);
connectionFactoryBean.setUsername(rabbitUsername);
connectionFactoryBean.setPassword(rabbitPassword);
connectionFactoryBean.setConnectionTimeout(900000);
connectionFactoryBean.setRequestedHeartbeat(900);
connectionFactoryBean.afterPropertiesSet();

CachingConnectionFactory cf = new CachingConnectionFactory(connectionFactoryBean.getObject());
cf.setChannelCacheSize(40);
return cf;


The problem is that the heartbeat interval is not changing. I quick look in AMQConnection reveals the below

int heartbeat = negotiatedMaxValue(this.requestedHeartbeat,
connTune.getHeartbeat());


private static int negotiatedMaxValue(int clientValue, int serverValue) {
return (clientValue == 0 || serverValue == 0) ?
Math.max(clientValue, serverValue) :
Math.min(clientValue, serverValue);
}


The value coming from the server is 60. The method
negotiatedMaxValue
will not respect the client's preferences (cannot disable heartbeat nor increase it). Am I missing something?

Answer

You are correct. The AMQConnection will determine the heartbeat value based on that method and then sends that value with the TuneOk method to the server (https://www.rabbitmq.com/amqp-0-9-1-reference.html#connection.tune-ok). You can see it sends the result of the negotiatedMaxValue() a few lines down from where you see the call to the method:

_channel0.transmit(new AMQP.Connection.TuneOk.Builder()
    .channelMax(channelMax)
    .frameMax(frameMax)
    .heartbeat(heartbeat)
    .build());

It seems based on the logic of the code that you can only reduce the heartbeat but the maximum heartbeat will be whatever the server sends and can't be increased more than that. RabbitMQ documentation is a little vague on the specifics of being able to increase the heartbeat that the server initially sends but does say it can be overwritten: https://www.rabbitmq.com/heartbeats.html

I checked in the latest version of spring rabbit and it still has the same configuration so doesn't look like it is changing anytime soon.

Checking the RabbitMQ GitHub doesn't show any existing issues around setting the heartbeat value greater than the server's sent value. Maybe submit an issue there and see what the developers say? https://github.com/rabbitmq/rabbitmq-java-client/issues?utf8=%E2%9C%93&q=heartbeat