Pika: What's the effect of parameter heartbeat in connection? - rabbitmq

I have search it in official docs and source code but it doesn't make sense.
I also try to set it to value such as 10 or 1 but it still shows heartbeat=60 in web console of rabbitmq management.

From RabbitMQ documentation:
The heartbeat timeout value defines after what period of time the peer
TCP connection should be considered unreachable (down) by RabbitMQ and
client libraries. This value is negotiated between the client and
RabbitMQ server at the time of connection. The client must be
configured to request heartbeats. In RabbitMQ versions 3.0 and higher,
the broker will attempt to negotiate heartbeats by default (although
the client can still veto them). The timeout is in seconds, and
default value is 60 (580 prior to release 3.5.5).
https://www.rabbitmq.com/heartbeats.html
Pika used to pick the minimum heartbeat value between server and client when negociating. This is no longer the case starting from 0.11. Pika picks the highest heartbeat value between client and server (and this is the norm in AMQP clients). This means that if you set a heartbeat value lower than 60 seconds, Pika will always pick RabbitMQ's value because it's higher. Try setting heartbeat to something higher than 60 seconds, and it should be visible in management console.
Though, if you really want to set the heartbeat value to something lower than 60 seconds (which is kind of counterproductive), you can still set the value in configuration.
Edit 2019-01-23: As of Pika 1.0, this behavior has changed again. Now, Pika picks the lowest heartbeat interval value between the client and the server if both the client and the server have specified a non-zero heartbeat interval value. If either the client or the server have not specified a heartbeat interval value or have specified zero, it takes the specified value if there is one, or zero otherwise (which means heartbeats are disabled). Still, it doesn't mean it's always a good idea to use low heartbeat intervals.

Related

mule 4 http listener - what is the use of ReadTimeout

Using mule 4.4 community edition running on premise
while configuring HTTP listener came across this property :
Checked online and documentation here
Maximum time in milliseconds that the listener must wait while receiving a message.
I tried changing it to 5000 ( 5 seconds ) and was waiting without making a request for more than a minute .
Then I invoked the listener and it worked fine so I am confused on what is the significance of this attribute ?
when should we use this value ? os this meant to act as a response timeout which consumer of http listener would get ?
Thanks
Read Timeout: (Number) Maximum time in milliseconds that the listener must wait while receiving a message. Default Value: 30000. Documentation is here
Read Timeout indicates once a TCP connection is opened, till how long the listener should wait to get the body.
From my understanding this is done sometimes by clients to keep the connection alive and to mitigate situations, where too many connections are opened and closed. Refer This
You can keep the default values in there and it won’t impact your implementation, given that you aren’t sending GB’s of data to your endpoints and not uploading any file using multi-part upload of HTML.
And if you are then you’ll need to tweak it a bit according to your needs

How to reduce the frequency of ActiveMQ KeepAlive messages

Whe have configured HTTP transport for ActiveMQ. However, we are noticing that there are thousands of KeepAlive messages. I understand that KeepAlive messages are used to control how "dead" connections are detected and purged by the Inactivity Monitor: http://activemq.apache.org/activemq-inactivitymonitor.html
<org.apache.activemq.command.KeepAliveInfo>
<commandId>0</commandId>
<responseRequired>false</responseRequired>
</org.apache.activemq.command.KeepAliveInfo>
From the documentation, it seems that Inactivity Monitor can be turned off, but what I am trying to figure out if there is a setting to "reduce" the amount of chatter on a line but not completely eliminate. I am OK with one message per second, for example, but we are getting thousands.
A transport connector has a paramater "wireFormat.maxInactivityDuration" that determines the maximum inactivity duration. To reduce the frequency of keepalives, increase this value. The default value is 30000 (30 seconds).
If the default value of 30 seconds is in practice, and you are getting thousands of keepalives per second, I would expect you have tens-of-thousands of connections.
Here is an example of specifying this paramater:
<transportConnectors>
<transportConnector name="openwire"
uri="tcp://0.0.0.0:61616?wireFormat.maxInactivityDuration=30000&wireFormat.maxInactivityDurationInitalDelay=10000"/>
</transportConnectors>
If the other end of the connection specifies a shorter duration than your end, the shorter duration will be used by both ends of the connection. There doesn't appear to be a setting for a "minumum inactivity duration", so you will have to live with that if a client chooses a very short duration.

How to set per-message expiration (TTL) in Celery?

It is possible to publish messages into a RabbitMQ queue with an expiration TTL: such messages will expire once the TTL is done and (if a dead-letter queue is setup,) removed to the dead-letter queue.
But is it possible to specify such per-message TTL using Celery?
Note that I'm not looking for a way to specify task-expiration but rather message expiration: I want my messages to spend (a configurable) amount of time in the queue before finally getting picked up # the dead-letter queue.
TIA.
Short introduction: Expiration vs Expires
RabbitMQ does support per-message TTL (as well as TTL for the queue), the behavior is documented here: https://www.rabbitmq.com/ttl.html#per-message-ttl-in-publishers. The trick is to set the expiration Message Property (https://www.rabbitmq.com/publishers.html#message-properties) when the message is published (in milliseconds).
Celery on the other hand allows you to set the expires parameter (https://docs.celeryproject.org/en/stable/reference/celery.app.task.html) in seconds or as a datetime. The difference from the native RabbitMQ functionality is that the message remains in the queue after expiration. The expired message is delivered to the worker, which then reads the expires header to determine that the message has expired and rejects the message.
tl;dr: expiration != expires
How to pass a message property in Celery
This method is not documented in Celery. I figured it out by trial and error because I wanted a native TTL myself.
The send_task method (celery.app.base.Celery.send_task), which is called for example by apply_async, accepts the **options parameter. All **options unknown to Celery are then passed in the celery.app.amqp.Queues->send_task_message( ... ) method as **kwargs and then as message properties.
So if we can set the message property, there is nothing easier than setting the native expiration:
my_awesome_task.apply_async(args=(11,), expiration=42)
Note that Celery automatically converts 42 seconds to 42000 milliseconds (which is correct).
Expiration (in properties) and Expires (in headers) can be combined, the two functionalities are not affected in any way.

What is a reasonable value for heartbeat in RabbitMQ?

RabbitMQ allows you to "heartbeat" a connection, i.e. from time to time the client and the server check (using empty messages) that the other party is still there and available. So far, so good.
Unfortunately, I was not able to find a place in the documentation where a suggestion is made what a reasonable value for this is. I know that you need to specify the heartbeat in seconds, but what is a real-world best practice value?
Obviously, it should not be too often (traffic), but also not too rare (proxies, …). Any suggestions?
Is 15 seconds fine? 30? 60? …?
This answer if for RabbitMQ < 3.5.5, for newer versions see the answer from #bmaupin.
It depends on your application needs. Out of the box it is 10 min for RabbitMQ. If you fail to ack heartbeat twice (20min of inactivity), connection will be closed immediately without sending any connection.close method or any error from the broker side.
The case to use heartbeat is firewalls that closes inactive for a long time connection or some other network settings that doesn't allow you to have waiting connections.
In fact, hearbeat is not a must, from RabbitMQ config doc
heartbeat
Value representing the heartbeat delay, in seconds, that the server sends in the connection.tune frame. If set to 0, heartbeats are disabled. Clients might not follow the server suggestion, see the AMQP reference for more details. Disabling heartbeats might improve performance in situations with a great number of connections, but might lead to connections dropping in the presence of network devices that close inactive connections.
Default: 580
Note, that having hearbeat interval too short may result in significant network overhead. Keep in mind, that hearbeat frames are sent when there are no other activity on the connection for a hearbeat time interval.
The RabbitMQ documentation now provides a recommended heartbeat timeout value between 5 and 20 seconds:
Setting heartbeat timeout value too low can lead to false positives (peer being considered unavailable while it really isn't the case) due to transient network congestion, short-lived server flow control, and so on. This should be taken into consideration when picking a timeout value.
Several years worth of feedback from the users and client library maintainers suggest that values lower than 5 seconds are fairly likely to cause false positives, and values of 1 second or lower are very likely to do so. Values within the 5 to 20 seconds range are optimal for most environments.
Source: https://www.rabbitmq.com/heartbeats.html#false-positives
In addition, as of RabbitMQ 3.5.5 the default heartbeat timeout value is 60 seconds (https://www.rabbitmq.com/heartbeats.html#heartbeats-timeout)

RabbitMQ consumer crash and consumer-count

If a consumer of a RabbitMQ crashes, with no graceful disconnection, will a subsequent declare-ok request fired several milliseconds later report a diminished consumer-count? Or is there an amount of time that needs to pass before the reported number will change?
declare-ok count all known consumers regardless their actual state.
See, in fact, some time after connection get dangled it still marked as alive (exact time depends on OS settings and whether do you use heartbeats and whether there are any network operation over that connection). In RabbitMQ management panel you may see connection and it channels with consumer tags listed some time after connection died.