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.
Install / Use
/learn @bloomberg/AmqpproxREADME
amqpprox
amqpprox is an AMQP 0.9.1 proxy server, it is designed for use in front of an AMQP 0.9.1 compliant message queue broker such as RabbitMQ.
Menu
- Rationale
- Documentation
- Features
- Getting Started
- Building
- Installation
- Contributions
- License
- Future Ideas and Direction
- Code of Conduct
- Security Vulnerability Reporting
Rationale
Commonly people use HAProxy software acting as a load balancer to spread load between multiple machines within a serving cluster and handle failures gracefully. With amqpprox we built a similar proxy, except tailored specifically for the AMQP 0.9.1 protocol. This brings benefits which cannot be achieved with layer 4 proxying alone.
This proxy and how we use it was first publicly outlined in this talk at RabbitMQ Summit 2019, then released & introduced in detail in this talk at RabbitMQ Summit 2021.
Key Advantages
- We can redirect different virtual hosts to different broker clusters
- We are able to understand/log AMQP 0.9.1 sessions passing through the proxy
- We can alter which brokers are connected to, in order to optimise network/datacenter cross-traffic.
- We can get detailed statistics without relying on the RabbitMQ broker itself
- We can easily have clients test connection failovers locally
Documentation
- Overall architecture and code walkthrough
- Session relationship between incoming and outgoing connections
- How AMQP handshaking works in the proxy
- Overview of the TLS options
Features
- [X] No dependencies: config is pushed into it, does nothing by default
- [X] Unix domain socket for control plane operations
- [X] Allow switching connections between farms per vhost
- [X] Load balancing between the farm members
- [X] Resources (vhosts) can be pointed at DNS farms, not just IPs
- [X] Statistics about each interaction
- [X] Able to easily test client failover by severing connections on demand
Getting Started
Quick Start
This guide assumes you have amqpprox building, and a RabbitMQ broker running on localhost:5672.
amqpprox can be started with a few command line arguments to start in a simple one mapping mode:
$ amqpprox --consoleVerbosity 5 --destinationDNS localhost --destinationPort 5672 --listenPort 5673
Starting amqpprox, logging to: 'logs' control using: '/tmp/amqpprox'
TRACE: Session cleanup starting
TRACE: Clean up finished with no sessions to clean up
...<snip>...
You can then connect your RabbitMQ client via localhost:5673 and amqpprox
will proxy all connections into 5673 to the running broker on 5672. Until
you make a connection you won't see much other than periodic cleanup trace, but
you can interact with it fully through the amqpprox_ctl interface.
This mode is designed for simple use cases where a user is using only one vhost or wants to do local-only testing.
Getting Started With amqpprox_ctl commands
amqpprox is the core proxy executable. By default it starts up with no mapped
vhosts/broker backends/listening ports/other configuration. amqpprox_ctl is
used to provide configuration before telling it to begin listening. See amqpprox_ctl documentation.
Start amqpprox
$ amqpprox --help
amqpprox AMQP v0.9.1 proxy:
This is a proxy program for AMQP v0.9.1, designed to sit in front of a RabbitMQ
cluster. Most options for configuring the proxy and introspecting its state are
available through the amqpprox_ctl program, begin by sending 'HELP' to it.
This program supports the following options to allow running multiple instances
on a machine and a simplified configuration mode. In the simplified
configuration mode the --listenPort, --destinationDNS and --destinationPort
must all be specified, and after which it immediately starts listening on all
interfaces for that port and sends all vhosts to the destination DNS entry.
More complicated configuration, such as sending different vhosts to different
destinations, necessitates the use of the amqpprox_ctl.
Although most configuration is injected by the amqpprox_ctl program, the
logging directories and the control UNIX domain socket are specified on this
program, to facilitate safely running multiple instances of amqpprox on a
single host.
:
--help This help information
--logDirectory arg (=logs) Set logging directory
--controlSocket arg (=/tmp/amqpprox) Set control UNIX domain socket location
--cleanupIntervalMs arg (=1000) Set the cleanup interval to garbage
collect connections
--listenPort arg (=0) Simple config mode: listening port
--destinationPort arg (=0) Simple config mode: destination port
--destinationDNS arg Simple config mode: destination DNS
address
-v [ --consoleVerbosity ] arg (=0) Default console logging verbosity (0 =
No output through to 5 = Trace-level)
$ amqpprox
Starting amqpprox, logging to: 'logs' control using: '/tmp/amqpprox'
amqpprox_ctl Example Usage
$ amqpprox_ctl --help
Usage: amqpprox_ctl <control_socket> ARGS
amqpprox responds to HELP
$ amqpprox_ctl /tmp/amqpprox HELP
AUTH (SERVICE hostname port target | ALWAYS_ALLOW | PRINT) - Change authentication mechanism for connecting clients
BACKEND (ADD name datacenter host port [SEND-PROXY] [TLS] | ADD_DNS name datacenter address port [SEND-PROXY] [TLS] | DELETE name | PRINT) - Change backend servers
CONN Print the connected sessions
DATACENTER SET name | PRINT
EXIT Exit the program gracefully.
FARM (ADD name selector backend* | PARTITION name policy | DELETE name | PRINT) - Change farms
HELP Print this help text.
LIMIT (CONN_RATE_ALARM | CONN_RATE) (VHOST vhostName numberOfConnections | DEFAULT numberOfConnections) - Configure connection rate limits (normal or alarmonly) for incoming clients connections
LIMIT (DATA_RATE_ALARM | DATA_RATE) (DEFAULT | VHOST vhostName) BytesPerSecond - Configure data rate limits or alarms for incoming client data
LIMIT DISABLE (CONN_RATE_ALARM | CONN_RATE | DATA_RATE_ALARM | DATA_RATE) (VHOST vhostName | DEFAULT) - Disable configured limit thresholds
LIMIT PRINT [vhostName] - Print the configured default or specific connection rate limits for specified vhost
LISTEN START port | START_SECURE port | STOP [port]
LOG CONSOLE verbosity | FILE verbosity
MAP (BACKEND vhost backend | FARM vhost name | UNMAP vhost | DEFAULT farmName | REMOVE_DEFAULT | PRINT) - Change mappings of resources to servers
MAPHOSTNAME DNS - Set up mapping of IPs to hostnames
SESSION id# (PAUSE|DISCONNECT_GRACEFUL|FORCE_DISCONNECT) - Control a particular session
STAT (STOP SEND | SEND <host> <port> | (LISTEN (json|human) (overall|vhost=foo|backend=bar|source=baz|all|process|bufferpool))) - Output statistics
STAT (DISABLE|ENABLE) per-source - Enable/Disable internal collection of per-source statistics. Applies to all send/listeners
TLS (INGRESS | EGRESS) (KEY_FILE file | CERT_CHAIN_FILE file | RSA_KEY_FILE file | TMP_DH_FILE file | CA_CERT_FILE file | VERIFY_MODE mode* | CIPHERS (PRINT | SET ciphersuite(:ciphersuite)*))
VHOST PAUSE vhost | UNPAUSE vhost | PRINT | BACKEND_DISCONNECT vhost | FORCE_DISCONNECT vhost
Configure amqpprox how to talk to an AMQP 0.9.1 backend called rabbit1, labelled as datacenter london-az1, running on localhost:5672 without TLS/Proxy Protocol.
$ amqpprox_ctl /tmp/amqpprox BACKEND ADD rabbit1 london-az1 localhost 5672
$ amqpprox_ctl /tmp/amqpprox BACKEND PRINT
rabbit1 (london-az1): localhost 127.0.0.1:5672
Configure amqpprox to map inbound connections for vhost-example to backend rabbit1
$ amqpprox_ctl /tmp/amqpprox MAP BACKEND vhost-example rabbit1
$ amqpprox_ctl /tmp/amqpprox MAP PRINT
"vhost-example" => Backend:rabbit1
amqpprox now understands one vhost mapping. Use LISTEN to start listening for connections on port 5673:
$ amqpprox_ctl /tmp/amqpprox LISTEN START 5673
An AMQP 0.9.1 client can now connect to vhost-example on port 5673 and amqpprox will forward to rabbit1 on port 5672.
Building
The default build uses the Conan package manager, make, cmake and will require a C++17 compiler. These should be installed prior to doing the native build, and conan will download the other dependencies during setup.
Once you have set up the build dependencies on your machine, the project should be buildable with the following commands:
make setup- This will initialise your Conan environment and create the build directory. It should only needs to be run the first time you are setting up a build, except when bumping the dependency versions.make init- This will do the cmake initialisation, so should be run when changing the files included in the project, or the build system.make- This will run an incremental build and unit-test
We also provide Dockerfiles for building and running in an isolated environment, these are directly analogous to the above commands. If you don't wish to get Conan set up on your build machine, this can be an alternative quick way to get going.
make docker-setupmake docker-initmake docker-buildmake docker-shell: Get an interactive shell within the buil
Related Skills
clearshot
Structured screenshot analysis for UI implementation and critique. Analyzes every UI screenshot with a 5×5 spatial grid, full element inventory, and design system extraction — facts and taste together, every time. Escalates to full implementation blueprint when building. Trigger on any digital interface image file (png, jpg, gif, webp — websites, apps, dashboards, mockups, wireframes) or commands like 'analyse this screenshot,' 'rebuild this,' 'match this design,' 'clone this.' Skip for non-UI images (photos, memes, charts) unless the user explicitly wants to build a UI from them. Does NOT trigger on HTML source code, CSS, SVGs, or any code pasted as text.
openpencil
2.1kThe world's first open-source AI-native vector design tool and the first to feature concurrent Agent Teams. Design-as-Code. Turn prompts into UI directly on the live canvas. A modern alternative to Pencil.
openpencil
2.1kThe world's first open-source AI-native vector design tool and the first to feature concurrent Agent Teams. Design-as-Code. Turn prompts into UI directly on the live canvas. A modern alternative to Pencil.
ui-ux-pro-max-skill
60.9kAn AI SKILL that provide design intelligence for building professional UI/UX multiple platforms
