bloomberg / amqpprox

An AMQP 0.9.1 proxy server, designed for use in front of an AMQP 0.9.1 compliant message queue broker such as RabbitMQ.
Apache License 2.0
78 stars 16 forks source link

Add connection rate Limiting Support in amqpprox #83

Closed Chinmay1412 closed 2 years ago

Chinmay1412 commented 2 years ago

Currently, amqpprox doesn't impose any connections limit for connecting clients. This PR implements connection rate limit(allowed average connections per second) for connecting clients. The limit can be configured using new control command LIMIT. By default, amqpprox will not configure any limit for vhost. Using LIMIT control command, one will be able to configure connection rate limit per vhost or default connection rate limit for all the vhosts. After any configured limit, violating client connections will be closed with some async sleep(~750ms) during AMQP handshake. So the limited connections will not hit the broker in any way. At the moment, the PR only implements simple connection rate limit using fixed window protocol. The reason behind simple implementation is to consider the performance aspect during calculation. But in future, one can extend the connection limiter interface to implement more complex algorithm. The control command also allows to configure limit in alarm only mode. In alarm only mode, the violating client connection will not be closed. But amqpprox will log at warning level in case of any limit violation with AMQPPROX_CONNECTION_LIMIT as a substring, which can be used to set an early alarm for the clients. The primary purpose of the connection rate limit is to avoid the noisy neighbours affecting normal clients badly in shared environment and also preventing any kind of denial of service attack by creating exponential connections by any client.

Performance Tests

Testing by setting up amqpprox as per the performance tests README.md, and running the perf tester like:

$ ./amqpprox_perf_tester --address amqp://127.0.0.1:5673/rmq-lib --listen-address 0.0.0.0:5672 --clients 10000 --max-threads 100 --message-size 1 --num-messages 1

Results in seconds. Testing machine had 8 cores CPU and 32 GB RAM.

Test # No change(main branch) With the PR(without any limit) With the PR(with large limit (100000 connections/sec))
1 12.11 11.72 11.98
2 11.97 13.05 12.35
3 12.83 12.59 12.70

This shows there isn't any performance issue with this code change.