<file_sep>---
id: classic-ha-queues
title: Classic Ha Queues (aka Mirrored Queues)
sidebar_label: Classic Ha Queues
---


TODO<file_sep>---
id: queue-host
title: Queue Host Awareness
---

TODO<file_sep>---
id: classic-vs-replicated
title: Classic vs Replicated Queues
---

TODO<file_sep>---
id: metrics
title: Metrics
---

Metric collection and monitoring are as important for publishers as they are for any other application or component in an application. Several metrics collected by RabbitMQ are of particular interest when it comes to publishers:

- Outgoing message rate
- Publisher confirmation rate
- Connection churn rate
- Channel churn rate
- Unroutable dropped message rate
- Unroutable returned message rate

The publishing and confirmation rates are mostly self-explanatory. The churn rates are so important because they help detect applications that do not use connections or channels optimally and thus offer sub-optimal publishing rates and waste resources.

Unroutable message rates can help detect applications that publish messages that cannot be routed to any queue. For example, this may suggest a misconfiguration.

Client libraries may also collect metrics. RabbitMQ Java client is one example. These metrics can provide insight into application-specific architecture (e.g. what publishing component publishes unrooutable messages) that RabbitMQ nodes cannot infer.<file_sep>---
id: channels
title: Channels
---

TODO<file_sep>---
id: federated-exchanges
title: Federated Exchanges
---

TODO<file_sep>---
id: queues
title: Queues
---
A queue stores messages in FIFO order until they can be delivered to a consumer. Messages are deleted either once the consumer acknowledges them or auto-acknowledgements are used. 

Likewise, publishers can request confirmation that their messages have been persisted to one or more queues (called Publisher Confirms). These publisher confirms and consumer acknowledgements form the basis of reliable messaging in RabbitMQ.

If there is currently no consumer then the message remains in the queue until consumption (see note).

> NOTE: Messages and queues can be configured to be durable or non-durable and even ephemeral with auto-delete features. See the Reliability Guide for an introduction to message durability.

## Queue Types

There are three types of queue available.

### Classic queue

This is an unreplicated queue that exists only on a single broker. Use this queue when you only have a single broker or high availability of the queue is not required. Classic queues offer the highest throughput and lowest latency of the queue types.


### Classic HA queue

This is a replicated queue that can exist across a cluster of brokers. It is designed to provide safety against data loss and provide high availability. See the High Availabilty page to learn more.

### Quorum queue

This is a replicated queue designed to replace Classic HA queues, based on the Raft protocol. It is the recommend queue type for when you need high availability of a queue and strong guarantees against data loss.


## Queue Configurations

### Limits

We can configure queues to not grow beyond a certain size or length via the use of policies. When a queue becomes "full" it will start either rejecting, discarding or moving messages into an overflow queue, according to what you configure it to do.

### Time-to-live (TTL)

Classic and Classic HA queues allow for messages to be discarded once they exceed a given time-limit

### Lazy Mode

Classic and Classic HA queues by default will try and keep messages in memory. This can cause memory issues when queues grow very large. When a queue is configured to be lazy it will remove messages from memory once successfully written to disk and lazily load them back into memory on demand. This lowers the memory footprint dramatically.<file_sep>---
id: robust-systems
title: Characteristics of Robust Systems
---

TODO<file_sep>---
id: safety-in-flight
title: Safety In-Flight
---

TODO<file_sep>---
id: client-libraries
title: Client Libraries
---

TODO<file_sep>---
id: start-rabbitmq
title: Start RabbitMQ
---

This series of Getting Started steps considers that you already
[installed RabbitMQ](../install/).

The very first thing will be to start RabbitMQ. Once this is done, we
will:
1.  use its CLI (command line interface) to verify it started
    successfully and
2.  ensure we can communicate with it.

## Starting the broker

The way to do it really depends on the method you used to install it.
This article will give a few common examples. For more informations,
please read the documentation of your package manager or deployment
tool. It is even possible that RabbitMQ was started for you already.

### If you use the generic-unix package

Starting RabbitMQ is as simple as running the rabbitmq-server(8) script,
located in `sbin`, in the directory created by decompressing the
generic-unix archive:

```sh
/path/to/rabbitmq_server-$version/sbin/rabbitmq-server
```

This command will display the following banner in the terminal:
```text

  ##  ##      RabbitMQ 3.8.2
  ##  ##
  ##########  Copyright (c) 2007-2019 Pivotal Software, Inc.
  ######  ##
  ##########  Licensed under the MPL 1.1. Website: https://rabbitmq.com

  Doc guides: https://rabbitmq.com/documentation.html
  Support:    https://rabbitmq.com/contact.html
  Tutorials:  https://rabbitmq.com/getstarted.html
  Monitoring: https://rabbitmq.com/monitoring.html

  Logs: /tmp/rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini.log
        /tmp/rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini_upgrade.log

  Config file(s): (none)

  Starting broker... completed with 0 plugins.
```

### On most Unix-like systems with a package manager

The package probably installed RabbitMQ as a service. Therefore, use the
tool on your system to start the corresponding service:

* On Linux distributions based on systemd:

    ```sh
    systemctl start rabbitmq-server
    ```

* On Linux distributions based on SysV init scripts:

    ```sh
    service rabbitmq-server start
    ```

* On FreeBSD:

    ```sh
    service rabbitmq start
    ```

### On Microsoft Windows

RabbitMQ is installed as a service which is started automatically. There
is nothing to do in particular.

## Checking the broker is running

### Using the command line interface

Now that RabbitMQ is supposedly running, you can use the CLI to query
its status:

```sh
rabbitmqctl status
```

This status command is quite verbose. Here is an example based on the
generic-unix-based RabbitMQ started earlier:
```text
Status of node rabbit@cassini ...
Runtime

OS PID: 19392
OS: FreeBSD
Uptime (seconds): 16
RabbitMQ version: 3.8.2
Node name: rabbit@cassini
Erlang configuration: Erlang/OTP 21 [erts-10.3.5.9] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:128] [hipe] [dtrace]
Erlang processes: 271 used, 1048576 limit
Scheduler run queue: 1
Cluster heartbeat timeout (net_ticktime): 60

Plugins

Enabled plugin file: /tmp/rabbitmq_server-3.8.2/etc/rabbitmq/enabled_plugins
Enabled plugins:


Data directory

Node data directory: /tmp/rabbitmq_server-3.8.2/var/lib/rabbitmq/mnesia/rabbit@cassini

Config files


Log file(s)

 * /tmp/rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini.log
 * /tmp/rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini_upgrade.log

(...)

Listeners

Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Interface: 0.0.0.0, port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
```

There are several CLI tools provided with RabbitMQ to interact with it:
* rabbitmqctl(8)
* rabbitmq-diagnostics(8)
* rabbitmq-plugins(8)
* rabbitmq-queues(8)
* rabbitmq-upgrade(8)

We will use some of them later in this guide.

### Using log files

The RabbitMQ log files location depends again on how you installed it.
The exact location is reported by `rabbitmqctl status` as seen above.

Common locations are:
* generic-unix package: `/path/to/rabbitmq_server-$version/var/log/rabbitmq`
* Linux/FreeBSD packages: `/var/log/rabbitmq`
* Microsoft Windows: `%APPDATA%\RabbitMQ\log`

Here is an example of the log file based on the generic-unix-based
RabbitMQ started earlier:

```sh
cat /tmp/rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini.log
```

```text
2020-02-13 20:17:38.236 [info] <0.259.0>
 Starting RabbitMQ 3.8.2 on Erlang 172.16.17.32
 Copyright (c) 2007-2019 Pivotal Software, Inc.
 Licensed under the MPL 1.1. Website: https://rabbitmq.com
2020-02-13 20:17:38.237 [info] <0.259.0>
 node           : rabbit@cassini
 home dir       : /home/dumbbell
 config file(s) : (none)
 cookie hash    : JD0UL5ltCvNhzE8sE1hEnw==
 log(s)         : /tmp/rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini.log
                : /tmp/rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini_upgrade.log
 database dir   : /tmp/rabbitmq_server-3.8.2/var/lib/rabbitmq/mnesia/rabbit@cassini
(...)
2020-02-13 20:17:38.438 [info] <0.595.0> started TCP listener on [::]:5672
2020-02-13 20:17:38.438 [info] <0.610.0> started TCP listener on 0.0.0.0:5672
2020-02-13 20:17:38.438 [info] <0.259.0> Running boot step cluster_name defined by app rabbit
2020-02-13 20:17:38.438 [info] <0.259.0> Running boot step direct_client defined by app rabbit
2020-02-13 20:17:38.438 [notice] <0.104.0> Changed loghwm of /tmp/rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini.log to 50
2020-02-13 20:17:38.519 [info] <0.8.0> Server startup complete; 0 plugins started.
```
<file_sep>---
id: delayed-messaging
title: Delayed Message Routing
---

TODO<file_sep>---
id: cluster-nodes
title: Cluster nodes
---

After tuning RabbitMQ to work well with your need, you probably want
to increase its reliability and fault tolerance by adding more nodes.
This tutorial will show you how to cluster three nodes and use a quorum
queue.

> **TODO**: Write this page.
<file_sep>---
id: microservice-frameworks
title: Microservice Frameworks
---

TODO<file_sep>---
id: rpc-routing
title: RPC / Reply To Queues
---

TODO<file_sep>---
id: sharding
title: Sharding
---

Explain Sharding Plugin, consistent hash exchange, random exchange

TODO<file_sep>---
id: index
title: Concepts
sidebar_label: Concepts Home
---

<div class="doc-tiles"></div>

*   [![](/img/concepts/communication-patterns.svg)](communication-patterns)
    ## [Communication Patterns](communication-patterns)
    Pub/Sub, Point-to-point, Request-Reply...

*   [![](/img/concepts/rabbitmq-way.svg)](rabbitmq-way)
    ## [The RabbitMQ Way](rabbitmq-way)
    Exchanges, queues, bindings...

*   [![](/img/concepts/reliable-messaging.svg)](reliable-messaging)
    ## [Reliable Messaging](reliable-messaging)
    Acknowledgements, durability...

*   [![](/img/concepts/high-availability.svg)](high-availability)
    ## [High Availability](high-availability)
    Clusters, replicated queues...

*   [![](/img/concepts/protocols.svg)](protocols)
    ## [Supported Protocols](protocols)
    MQTT, STOMP, AMQP 1.0...

*   [![](/img/concepts/streaming-across-clusters.svg)](streaming-across-clusters)
    ## [Cross-Cluster Streaming](streaming-across-clusters)
    Multi-cluster architectures, edge computing and more...
<file_sep>---
id: connections
title: Connections
---

TODO<file_sep>---
title: We love Free Software!
author: <NAME>
---

The RabbitMQ project and team relies a **lot** on Free and Open Source
Software! From [Erlang](https://www.erlang.org/), the programming
language RabbitMQ is written in to [Docusaurus](https://docusaurus.io/),
the static website generator, to [Git](https://git-scm.com/), [GNU
Make](https://www.gnu.org/software/make/) and all the tools that make
our developers' life as seemless as possible.

A huge Thank you to all the amazing people behind those projects!

![](https://fsfe.org/campaigns/ilovefs/artwork/graphics/ilovefs-banner-extralarge.png)
<file_sep>---
id: classic-queues
title: Classic Queues
---


TODO<file_sep># Testing Docusaurus for rabbitmq.com website

## How to run local webserver

```sh
cd website
yarn start
```
<file_sep>---
id: index
title: Welcome to RabbitMQ Docs
sidebar_label: Welcome to RabbitMQ Docs
---

<div class="doc-tiles"></div>

*   [![](/img/concepts/rabbitmq-way.svg)](intro)
    ## [Why use RabbitMQ?](intro)
    Get an overview of the benefit of using RabbitMQ.

*   [![](/img/overview/install.svg)](../install/)
    ## [Install](../install/)
    How install RabbitMQ<br/>
    (or simply test it without installing).

*   [![](/img/overview/getting-started.svg)](../getting-started/)
    ## [Getting started](../getting-started/)
    Getting started with all RabbitMQ important features!

*   [![](/img/overview/concepts.svg)](../concepts/)
    ## [Concepts](../concepts/)
    How message routing works in general.

*   [![](/img/overview/enterprise.svg)](../enterprise/)
    ## [Enterprise Edition](../enterprise/)
    The version of RabbitMQ with more advanced features.

*   [![](/img/overview/developer-guide.svg)](../developer-guide/)
    ## [Developer guide](../developer-guide/)
    Documentation of RabbitMQ targetted at developers.

*   [![](/img/overview/operations-guide.svg)](../operations-guide/)
    ## [Operations guide](../operations-guide/)
    Documentation of RabbitMQ targetted at admins.
<file_sep>---
id: work-orchestration
title: Work Orchestration Frameworks
---

TODO<file_sep>---
id: redhat
title: Install on Red Hat and derivatives
sidebar_label: Red Hat
---

> **TODO**: Write this page.
<file_sep>---
id: public-private-exchange
title: Public Message Exchange, Private Consumer Exchange
sidebar_label: Public-Private Exchange
---

TODO<file_sep>// vim:sw=2:et:

function add_main_menu_button() {
  var breadcrumb_el = document.createElement('div');
  breadcrumb_el.setAttribute("class", "navToggle");
  breadcrumb_el.setAttribute("id", "navigationToggler");
  breadcrumb_el.innerHTML =
    "<div class=\"hamburger-menu\">" +
    "<div class=\"line1\"></div>" +
    "<div class=\"line2\"></div>" +
    "<div class=\"line3\"></div></div>";

  var sibling = document.querySelectorAll('.navigationWrapper')[0];
  sibling.parentNode.insertBefore(breadcrumb_el, sibling);

  function createToggler(togglerSelector, targetSelector, className) {
    var toggler = document.querySelector(togglerSelector);
    var target = document.querySelector(targetSelector);

    if (!toggler) {
      return;
    }

    toggler.onclick = function(event) {
      event.preventDefault();
      target.classList.toggle(className);
    };
  }

  createToggler(
    '#navigationToggler',
    '.navigationWrapper',
    'navigationSliderActive');
}

window.onload = add_main_menu_button;
<file_sep>---
id: erlang
title: Erlang/OTP
---

RabbitMQ relies on the Erlang/OTP runtime to run. A specific version of
RabbitMQ will be able to run on a range of Erlang/OTP versions. This
page documents that range for each version of RabbitMQ.

## Current requirements

As of **RabbitMQ 3.7.19+**, the requirements are:

<div class="erlang-requirements"></div>

* ### Minimum
  21.3
* ### Maximum
  22.x

## Installing Erlang/OTP

### From a package or installer

Please refer to the the install guide of RabbitMQ for your environment,
referenced in the left sidebar: it explains how to install Erlang/OTP.

### From source (Unix-like only)

The easiest way to compile and install Erlang/OTP from source as an
unprivileged user is to use [kerl].

Here is a quick overview of its usage:

1.  Fetch the `kerl` CLI and make it executable:
    ```sh
    wget https://raw.githubusercontent.com/kerl/kerl/master/kerl
    chmod a+x kerl
    ```

2.  Build a specific version of Erlang:
    ```sh
    ./kerl build 22.2 22.2
    ```

3.  Install Erlang/OTP:
    ```sh
    ./kerl install 22.2 ~/kerl/22.2
    ```

4.  Add `~/kerl/$erlang_version` to your `$PATH`.

For more details, please read [kerl documentation].

[kerl]: https://github.com/kerl/kerl/
[kerl documentation]: https://github.com/kerl/kerl/blob/master/README.md

## Compatibility matrix

| RabbitMQ version | Min. required Erlang/OTP | Max. supported Erlang/OTP |
|------------------|--------------------------|---------------------------|
| 3.8.2  | 21.3 | 22.x |
| 3.8.1  | 21.3 | 22.x |
| 3.8.0  | 21.3 | 22.x |
| 3.7.24 | 21.3 | 22.x |
| 3.7.23 | 21.3 | 22.x |
| 3.7.22 | 21.3 | 22.x |
| 3.7.21 | 21.3 | 22.x |
| 3.7.20 | 21.3 | 22.x |
| 3.7.19 | **21.3** | 22.x |
| 3.7.18 | 20.3 | 22.x |
| 3.7.17 | 20.3 | 22.x |
| 3.7.16 | 20.3 | 22.x |
| 3.7.15 | 20.3 | **22.x** |
| 3.7.14 | 20.3 | 21.3.x |
| 3.7.13 | 20.3 | 21.3.x |
| 3.7.12 | 20.3 | 21.3.x |
| 3.7.11 | **20.3** | **21.3.x** |
| 3.7.10 | 19.3 | 21.x |
| 3.7.9 | 19.3 | 21.x |
| 3.7.8 | 19.3 | 21.x |
| 3.7.7 | 19.3 | **21.x** |
| 3.7.6 | 19.3 | 20.3.x |
| 3.7.5 | 19.3 | 20.3.x |
| 3.7.4 | 19.3 | 20.3.x |
| 3.7.3 | 19.3 | 20.3.x |
| 3.7.2 | 19.3 | 20.3.x |
| 3.7.1 | 19.3 | 20.3.x |
| 3.7.0 | 19.3 | 20.3.x |

## Support Erlang/OTP versions policy

[Starting in January 2019][erlang-support-policy-ann], RabbitMQ supports
two most recent Erlang/OTP release series.

When a new Erlang/OTP release series is published, support for up to
three release series is provided for a few months:
*   to allow RabbitMQ to stabilize on the new release, and
*   for end users to upgrade their copy of Erlang if they are using the
    minimum required version.

[erlang-support-policy-ann]: https://groups.google.com/d/msg/rabbitmq-users/G4UJ9zbIYHs/qCeyjkjyCQAJ
<file_sep>---
id: freebsd
title: Install on FreeBSD
sidebar_label: FreeBSD
---

> **TODO**: Write this page.
<file_sep>---
id: retry-messaging
title: Retry Message Routing
---

TODO<file_sep>---
title: This Month in RabbitMQ: January 2020
author: <NAME>
---

Introducing TGI RabbitMQ! Inspired by TGI Kubernetes, RabbitMQ engineer, <NAME> has begun a
series of tutorial videos. Tune in at the end of each month for the latest release. In January,
Gerhard covered [upgrading from 3.7 to 3.8](https://youtu.be/DynCqFtnSoY).
Star and watch the [repository](https://youtu.be/DynCqFtnSoY) for future episode updates.

Also, be sure to check out the [dashboards we’ve published to Grafana](https://grafana.com/orgs/rabbitmq). These are a great way to get started with the new [Prometheus and Grafana support in 3.8](https://www.rabbitmq.com/prometheus.html).

<!--truncate-->

## Project Updates

 * First public beta version of [Pivotal RabbitMQ for Kubernetes](https://network.pivotal.io/products/p-rabbitmq-for-kubernetes).
 * [Spring AMQP 2.2.3](https://github.com/spring-projects/spring-amqp/releases)
 * [Hop 3.6.0](https://groups.google.com/d/msg/rabbitmq-users/MEwbDJ8biRc/s4xLPpvYAwAJ) is released with new features and dependency upgrades. The HTTP client for the classic blocking client is now pluggable, making it possible to use OkHttp instead of Apache HTTPComponents.


## Community Writings and Resources

 * 1 Jan: <NAME> (@hsunryou) wrote about [installing RabbitMQ 3.8 on CentOS 8.0](https://blog.naver.com/hsunryou/221756168969)
 * 1 Jan: (@Cakazies1) published about [messaging in Golang with RabbitMQ](https://medium.com/@cakazies/messaging-golang-with-rabbitmq-2ed1ccf8314)
 * 4 Jan: <NAME> published a [beginners description](https://dev.to/deciduously/correct-a-beginner-about-buzzword-technologies-4bbe) of several “buzzword-y” technologies, including RabbitMQ, looking for feedback and corrections
 * 8 Jan: <NAME> (@SunnyPaxos) published a really interesting article about [how DigitalOcean re-architected a system](https://blog.digitalocean.com/from-15-000-database-connections-to-under-100-digitaloceans-tale-of-tech-debt/) that had grown to 15,000 database connections because they were using MySQL as an event queue, to using RabbitMQ
 * 8 Jan: <NAME> (@rmoff) wrote about [Streaming messages from RabbitMQ into Kafka](https://rmoff.net/2020/01/08/streaming-messages-from-rabbitmq-into-kafka-with-kafka-connect/) with Kafka Connect
 * 9 Jan: <NAME> (@DormainDrewitz) published a list of the [top 10 RabbitMQ Influencers](https://content.pivotal.io/blog/top-rabbitmq-influencers-of-2019) of 2019
 * 9 Jan: <NAME> (@szymonmentel) published a [5 minute video overview of RabbitMQ](https://youtu.be/ViJNPnZPJn4) along with a [post with notes and links](https://szkolarabbita.pl/rabbitmq-klaster-w-5-minut/) to try it yourself (in Polish)
 * 9 Jan: <NAME> (@iandarigun) published the first part of an [introduction to RabbitMQ (in Portuguese)](https://medium.com/dev-cave/rabbit-mq-parte-i-c15e5f89d94)
 * 10 Jan: <NAME> (@GSantomaggio) added Helm support for [his RabbitMQ Operator for Kubernetes](https://github.com/Gsantomaggio/rabbitmq-operator#install-the-rabbitmq-operator-with-helm3)
 * 12 Jan: <NAME> (@pawel_duda) wrote about [why queues can be empty after a restart](https://devmeetsbiz.business.blog/2020/01/12/rabbitmq-queue-empty-after-a-restart-why-even-though-its-durable/) and what to do about it
 * 13 Jan: <NAME> (@marcin_elem84) wrote about [confirming messages in RabbitMQ](https://czterytygodnie.pl/potwierdzanie-wiadomosci-rabbitmq/) (in Polish)
 * 13 Jan: <NAME> (@DavideGuida82) wrote about using the [Outbox pattern with RabbitMQ](https://www.davideguida.com/improving-microservices-reliability-part-2-outbox-pattern/) to improve microservices reliability
 * 15 Jan: <NAME> (@MikeMoelNielsen) published a [video on using a RabbitMQ PerfTest](https://youtu.be/MEdPLX-PCn8 ) (performance testing tool)
 * 15 Jan: <NAME> (@iandarigun) published the second part of [an introduction to RabbitMQ in Portuguese](https://medium.com/dev-cave/rabbitmq-parte-ii-fa61a469ba2)
 * 16 Jan: <NAME> (@TejadaRenzo) published about [using Docker Compose with RabbitMQ](https://renzotejada.com/blog/docker-compose-para-rabbitmq/) (in Spanish)
 * 17 Jan: Linux Conference Australia 2020 published a talk by <NAME> (@rafaelma_) on what goes on behind the scenes of an ELK system, including the role of RabbitMQ ([video](https://youtu.be/4X0bmnb4tVI), [slides](https://e-mc2.net/behind-scenes-elk-system))
 * 17 Jan: <NAME> (@lillajja) wrote up the [Annual RabbitMQ Report 2020](https://www.cloudamqp.com/blog/2020-01-17-annual-rabbitmq-report-2020-by-cloudamqp.html) from CloudAMQP
 * 17 Jan: <NAME> (@SamProgramiz) published an [introduction to AMQP 0.9.1](https://medium.com/@samuelowino43/advanced-message-queueing-protocol-ampq-0-9-1-617209d2d6ec), which is one of the protocols supported in RabbitMQ
 * 18 Jan: <NAME> wrote up [installing RabbitMQ on Windows](https://beetechnical.com/windows/rabbitmq-installation-on-windows/)
 * 25 Jan: <NAME> published an introduction to [using RabbitMQ with Node.js](https://medium.com/@klogic/introduction-to-rabbitmq-with-nodejs-3f1ab928ed50)
 * 27 Jan: <NAME> (@recursivecodes) published about [getting started with RabbitMQ in Oracle Cloud](https://blogs.oracle.com/developers/getting-started-with-rabbitmq-in-the-oracle-cloud)
 * 27 Jan: <NAME> (@recursivecodes) also published a video about how to install and [run RabbitMQ in Oracle Cloud](https://youtu.be/9kVBZ5MQV6I)
 * 27 Jan: <NAME> wrote an explainer about [RabbitMQ as a Service Bus in the context of ASP.NET Core](https://www.c-sharpcorner.com/article/rabbitmq-service-bus/)
 * 28 Jan: <NAME> (@rseroter) wrote about trying out the new [replicated, durable quorum queues in RabbitMQ 3.8](https://seroter.wordpress.com/2020/01/28/lets-try-out-the-new-durable-replicated-quorum-queues-in-rabbitmq/)
 * 28 Jan: <NAME> published about [using the Outbox pattern with RabbitMQ at Trendyol](https://medium.com/trendyol-tech/outbox-pattern-story-at-trendyol-fcb35fe056d7)
 * 29 Jan: L<NAME> (@lillajja) wrote about [message priority in RabbitMQ](https://www.cloudamqp.com/blog/2020-01-29-message-priority-in-rabbitmq.html)
 * 30 Jan: <NAME> (@T00MEKE) published about [setting up a RabbitMQ cluster in Kubernetes](https://nick.barrett.org.nz/setting-up-rabbitmq-ha-in-kubernetes-with-external-https-and-amqps-access-1ce1f3632dd2) with external HTTPS and AMQPS access
 * 30 Jan: <NAME> (@lillajja) wrote about [RabbitMQ and Erlang upgrades](https://www.cloudamqp.com/blog/2020-01-30-rabbitmq-erlang-upgrades.html)
 * 31 Jan: Georgy @georgysay wrote about [using RabbitMQ with .NET Core](https://habr.com/ru/post/486416/) (in Russian)
 * 31 Jan: <NAME> (@gerhardlazu) published the first episode of TGI RabbitMQ on [how to upgrade from RabbitMQ 3.7 to 3.8](https://youtu.be/DynCqFtnSoY)


## Ready to learn more?

 * 13 Feb, online: Free webinar on How to [Build Reliable Streaming Pipelines with RabbitMQ and Project Reactor](https://content.pivotal.io/rabbitmq/feb-13-how-to-build-reliable-streaming-pipelines-with-rabbitmq-and-project-reactor-webinar?utm_campaign=reactor-streaming-webinar-blog&utm_source=rabbitmq&utm_medium=website)
 * 20 Feb, online: Hashitalks 2020 features a talk on [Securing RabbitMQ with Vault](https://events.hashicorp.com/hashitalks2020) by <NAME> (@devops_rob)
 * 28 Feb, online: TGIR S01E02: Help! RabbitMQ ate my RAM!
 * 5-6 Mar, San Francisco: [Code BEAM SF](https://codesync.global/conferences/code-beam-sf/) which features these talks on RabbitMQ:
   * A Novel Application Of Rabbitmq For The Reliable Automated Deployment Of Software Updates with <NAME> (@brc859844) and <NAME>
   * How RabbitMQ simplifies routing in a microservices architecture with <NAME> and <NAME>
 * On-demand, online at LearnFly: [Learn RabbitMQ Asynchronous Messaging with Java and Spring](https://www.learnfly.com/learn-rabbitmq-asynchronous-messaging-with-java-and-spring)
 * On-demand, online at Udemy: [RabbitMQ: Messaging with Java, Spring Boot And Spring MVC](https://www.udemy.com/rabbitmq-messaging-with-java-spring-boot-and-spring-mvc/)
 * Online, $40 buys you early access to Marco Behler’s course, [Building a Real-World Java and RabbitMQ Messaging Application](https://www.marcobehler.com/courses/30-building-a-real-world-java-and-rabbitmq-messaging-amqp-application)
 * Online, Pluralsight course: [RabbitMQ by Example](https://www.pluralsight.com/courses/rabbitmq-by-example) gets good reviews
 * Online: Luxoft is offering a [RabbitMQ course in Russian](https://www.luxoft-training.ru/kurs/platforma_obmena_soobshcheniyami_rabbitmq.html)
 * Various: South Africa: [Jumping Bean offers RabbitMQ training](https://www.jumpingbean.co.za/rabbitmq)
<file_sep>---
id: point-to-point
title: Point-to-Point
---

TODO<file_sep>---
id: configure-queue-length-limit-policy
title: Configure queue length limit policy
---

Beside the configuration settings you discovered in the previous step,
you can use policies to fine-tune the behavior of RabbitMQ, at runtime
and on a per-queue basis for instance.

We will take the example of configuring a length limit to a queue for
this demonstration.

> **TODO**: Write this page.
<file_sep>---
id: build
title: Build RabbitMQ
---

> **TODO**: Write this page.
<file_sep>---
id: streaming-across-clusters
title: Streaming Across Clusters
---

RabbitMQ offers multiple features for streaming messages between separate instances or clusters. There are multiple usecases for cross-cluster streaming that RabbitMQ support natively.

## Cases for Cross-Cluster Streaming

### Edge computing

RabbitMQ instances or clusters can be deployed to edge locations to provide both low-latency messaging for local systems and a routing backbone that routes or replicates messages to a centralised cluster in a data center.

![](/img/docs/concepts/cross-cluster-streaming-edge.svg)

### Peer-to-Peer Clusters

Peer clusters can route messages to each other to allow for message processing on both sides.

![](/img/docs/concepts/cross-cluster-streaming-peers.svg)

### Hot Standby

Messages can be streamed from an active cluster to a standby cluster so that in the event of a disaster, applications be be switched over to the hot-standby.

### Blue/Green Deployments

Consumers and publishers can be migrated from one cluster to another without message loss by streaming messages from the existing primary cluster to a new cluster that will soon become the primary.

### Consumer Load Distribution

Messages of a single queue can be distributed via streaming across counterpart queues on multiple clusters so that consumption load is spread out.

## Features

### Federation

Federation allows for the streaming of messages across multiple RabbitMQ instances or clusters. It is different to replicated queues (Quorum/Classic HA queues) in that it can link separate clusters across a WAN that would not be viable for a replicated queue. Clusters can be of different Erlang/RabbitMQ versions.

There are two type of federation:

- exchange federation
- queue federation

The two satisfy different use cases but both rely on concept of linking two RabbitMQ clusters together.

#### Upstream and Downstream clusters

Federation involves linking two or more clusters into an upstream-downstream relationship. Messages are published to an upstream cluster and those messages can be routed to local queues on the upstream as normal and additionally be configured to be streamed to the downstream cluster

![](/img/docs/concepts/federation-upstream-downstream.svg)

These upstream-downstream pairings can be combined to form many type of graph (hub and spoke, DAG, ring etc).

![](/img/docs/concepts/federation-upstream-downstream-dag.svg)

#### Exchange Federation

We can perform message routing to a downstream cluster using federated exchanges. 

- Routing option #1 - we want all messages published to exchanges in the upstream, to be routed to the downstream.
- Routing option #2 - we want all messages published to a particular exchange in the upstream, to be routed to the downstream.
- Routing option #3 - we want to route only a subset of messages published to a particular exchange(s) based on things like routing keys and headers.

A federated exchange can be a fanout, topic, direct or header exchange just like a normal exchange and we can express routing logic across clusters in the usual way we do so within a single cluster.

![](/img/docs/concepts/federated-exchange.svg)

The normal usecases are:

- Hub and Spoke pattern. Stream messages from multiple regional clusters to a central cluster where you want to process some particular type of message only or have some central auditing.
- Edge/Data Center pattern. Local RabbitMQ clusters serve local systems in an edge location and benefit from low latency. Those messages are in turn (selectively) streamed to clusters in either regional datacenters or a single global data center, when there is connectivity.
- Peer Clusters pattern. Messages published to two regional clusters and must be processed on both clusters. Each cluster plays the role of upstream and downstream, allowing local consumers to consume both locally published messages and message published to the peer cluster.


#### Queue Federation

Queue federation is not about routing but about distributing messages to be consumed across more than one cluster. It allows us to use the competing consumer pattern on a single queue, but across multiple clusters.

The way it works is that a federated queue is created on the downstream cluster which links it to a queue on the upstream. Messages will be streamed from the upstream queue to the downstream queue as long as there is a consumer on the downstream queue with enough capacity. It is a best effort approach to spread load of a single queue across multiple clusters.

![](/img/docs/concepts/federated-queue.svg)

For example:

- 1,2,3,4,5 arrive at upstream
- 1,2,3 are consumed from the upstream queue by a local consumer
- 4,5 are streamed to the downstream queue
- 6,7,8 arrive at the upstream
- 4,5 are consumed on the downstream queue by a local consumer
- 6,7 are consumed from the upstream queue by a local consumer
- 8 is streamed to the downstream queue
- 8 is consumed from the downstream queue by a local consumer

The normal usecases are:

- distribute consumption workload across multiple clusters
- blue-green deployments where consumers need to be migrated to a new cluster and not process the same message twice.

#### Federation Topologies

We can create federation topologies where one downstream cluster is the upstream of another. We can form Hub and Spoke,  Directed Acyclic Graphs (DAG), rings or whatever you want. Typically, it is recommended to keep federation topologies simple.

### Shovel

Shovels can be used to stream messages from one cluster to another, or one vhost to another. 

A shovel is an Erlang process that will consume messages from an exchange or queue on one cluster, and publish them to an exchange or queue on another cluster. It is basically, a well written consumer/publisher application that is hosted within the cluster and uses RabbitMQ's reliable messaging features to provide an At-Least-Once delivery guarantee of streamed messages.

The shovel processes will start-up when the cluster starts and can survive the loss of a broker, performing fail-over to another broker.

![](/img/docs/concepts/shovel.svg)

It has similarities with Exchange Federation but with some key differences:

- Nomenclature changes from upstream/downstream to source/destination.
- Supports AMQP 1.0. In fact the source could be AMQP 0.9.1 and the destination be AMQP 1.0 or vice-versa.
- Supports different streaming sources/destinations:
  - source exchange -> destination exchange
  - source queue -> destination exchange
  - source exchange -> destination queue
  - source queue -> destination queue
- Can be used to stream messages between vhosts on the same cluster

Often both Exchange Federation and Shovel can be a candidate for the same usecase.<file_sep>---
id: pub-sub-fanout
title: Publish-Subscribe with the Fanout exchange
sidebar_label: Pub-Sub with Fanout
---

TODO<file_sep>---
id: confirms
title: Publisher Confirms
---

Ensuring data safety is a collective responsibility of applications, client libraries and RabbitMQ cluster nodes. Messages can be lost in-flight between a publisher and broker.

A message could be lost:

- while in an outgoing or incoming buffer
- while being transmitted over the wire
- while being written to disk
- while being processed by the channel

Publisher confirms are an acknowledgement mechansim that offers At-Least-Once guarantees.

## Basic.ack, basic.nack, basic.return

Confirms come is as either:

- basic.ack: the message has been safely stored by the broker
- basic.nack: some kind of failure occurred and the message has not been safely stored by the broker
- basic.return: the message was unroutable (see the [Unroutable section](#mandatory-flag))

## Strategies for Using Publisher Confirms

Publisher confirms provide a mechanism for application developers to keep track of what messages have been successfully accepted by RabbitMQ. There are several commonly used strategies for using publisher confirms:

- **Streaming**: publish messages continuously, and process incoming confirms continuously. Limiting the number of unconfirmed messages (aka in-flight messages) to predetermined amount.
- **Batching**: publish a batch of messages at a time and wait for all outstanding confirms before sending the next batch.
- **Publish-and-wait**: publish one message at a time, waiting for the confirm before sending the next. This option is **highly** discouraged due to its highly negative impact on publisher throughput.

### Streaming Confirms

Most client libraries usually provide a way for developers to handle individual confirmations as they arrive from the server. The confirms will arrive asynchronously. Since publishing is also inherently asynchronous in AMQP 0-9-1, this option allows for safe publishing with very little overhead. The algorithm is usually similar to this:

- Enable publisher confirms on a channel
- For every published message, add a map entry that maps current sequence number to the message
- When a positive ack arrives, remove the entry
- When a negative ack arrives, remove the entry and schedule its message for republishing (or something else that's suitable)

In the RabbitMQ Java client, confirm handler is exposed via the ConfirmCallback and ConfirmListener interfaces. One or more listeners have to be added to a channel.

### Batch Publishing

This strategy involves publishing batches of messages and awaiting for the entire batch to be confirmed. Retries are performed on batches.

- Enable publisher confirms on a channel
- Send messages of a batch one after the other until all have been sent.
- Wait for all outstanding confirms
- When all confirms come in positive, publish the next batch
- If there are negative confirms or timeout hits, republish the entire batch or only the relevant messages

Some clients provide convenience API elements for waiting for all outstanding confirms. For example, in the Java client there is Channel#waitForConfirms(timeout).

Since this approach involves waiting for confirms, it will have negative effects on publisher throughput. The larger the batch, the smaller the effect will be.

### Publish-and-Wait

This strategy can be considered an anti-pattern and is documented primarily for completeness. It involves publishing a message and immediately waiting for the outstanding acknowledgement to arrive. 

This approach will have a very significant negative effect on throughput and is not recommended.

## Mandatory flag

A publisher can request to be notified if a published message was not routed to any queues. It does this by setting the the `mandatory` flag to true. If the message cannot be routed to any queue then the publisher is warned via an additional confirm message called basic.return which is sent to the publisher after a basic.ack.

The possible causes of an unroutable message are:

- message sent to the default exchange but no queue matches the routing key
- message sent to an exchange with no bindings
- message sent to an exchange with bindings, but no bindings match that particular message.<file_sep>---
id: reliable-messaging
title: Reliable Messaging
---

Reliable messaging is about strong guarantees that published messages get delivered to consumers in the face of failures such as TCP connection failures and even the loss of a broker.

There is a chain of responsibility from publisher to broker to consumer and both RabbitMQ and the clients need to behave correctly in order to achieve reliability.

## Guarantees 

With messaging systems we tend to talk about either At-Most-Once or At-Least-Once processing guarantees. Additionally we care about ordering guarantees.

### At-Most-Once Guarantee

The At-Most-Once guarantee says that messages might get lost, but a message will never get processed more than once. RabbitMQ offers this guarantee when:
- publishers do not use Publisher Confirms
- consumers use Auto Acknowledgement mode
- messages are stored in a classic queue with a non-redundant storage device

This is a best effort, highest performance option that is good when you don't care if some messages get lost but do care about low latency and high throughput.

### At-Least-Once Guarantee

The At-Least-Once guarantee says that no message will get lost, but might end up being processed by a consumer more than once. We attain this guarantee by ensuring:

- publishers use Publisher Confirms
- consumers use manual consumer acknowedgements correctly
- messages are replicated across multiple brokers or durable, fault tolerant storage is used. 

> RAID arrays or cloud block storage (like EBS on AWS) offer replication at the storage layer.

This guarantee offers safety first and usually results in lower throughput and higher latencies.

## Publisher Confirms

In order to not lose a message in-transit between a publisher and a broker, we use an acknowledgement mechansim called Publisher Confirms. Once a broker has safely written a message to disk (and possibly replicated), it will notify the publisher that it now has taken responsibility for that message.

Until this confirm has been received by the publisher, it cannot assume that the message is safe and remains the publisher's responsibility.

## Consumer Acknowledgements
 
In order not to lose a message in-transit between a broker and a consumer, we use Consumer Acknowledgements. If we want At-Least-Once processing guarantees, the consumer should send an acknowledgement **after** it has safely completed processing the message.

If there is an error while processing the message, then the message can be redelivered for another attempt at processing it.

If the consumer acknowledges a message on receipt, but before processing it, then an error during processing will essentially cause the message to have been lost. It will not be redelivered and will end up having never been successfully processed.

## Replicated Queues

Both Classic HA queues and Quorum queues offer replication of messages over multiple brokers so that in the event of the loss of a broker, no confirm messages are lost and the queue remains operational.

## Durable, Fault Tolerant Storage

Using a storage device that provides redundancy in the case of failure is also a good option. It does not offer high availability by itself as the loss of the broker will cause all hosted queues to be offline. But it can provide data safety.

RAID arrays and cloud block storage are both good options.<file_sep>---
id: integrations
title: Integrations
---

TODO<file_sep>---
id: index
title: Enterprise Edition
---

TODO<file_sep>---
id: troubleshooting
title: Publisher Troubleshooting
sidebar_label: Troubleshooting
---

This section covers a number of common issues with publishers, how to identify and address them. Failures in distributed systems come in many shapes and forms, so this list is by no means extensive.

## Connectivity Failures

Like any client, a publisher has to successfully connect and successfully authenticate first.

The number of potential connectivity issues is pretty broad and has a dedicated guide.

## Authentication and Authorisation

Like any client, a publisher can fail to authenticate or don't have the permissions to access their target virtual host, or publish to the target exchange.

Such failures are logged by RabbitMQ as errors.

See the sections on troubleshooting of authentication and authorisation in the Access Control guide.

## Connection Churn

Some applications open a new connection for every message published. This is highly inefficient and not how messaging protocols were designed to be used. Such condition can be detected using connection metrics.

Prefer long lived connections when possible.

## Connection Interruption

Network connections can fail. Some client libraries support automatic connection and topology recovery, others make it easy to implement connection recovery in application code.

When connection is down, no publishes will go through or be internally enqueued (delayed) by clients. In addition, messages that were previously serialised and written to the socket are not guaranteed to reach the target node. It is therefore critically important for publishers that need reliable publishing and data safety to use Publisher Confirms to keep track of what publishes were confirmed by RabbitMQ. Messages that were not confirmed should be considered undelivered after a period of time. Those messages can be republished if it's safe to do so for the application. This is covered in tutorial 7 and the Data Safety section in this guide.

See Recovery from Network Connection Failures for details.

## Routing Issues

A publisher can be successfully connected, authenticated and granted the permissions to publish to an exchange (topic, destination). However, it is possible that such messages would not be routed to any queues or consumers. This can be due to

- A configuration mismatch between applications, e.g. topics used by the publishers and consumers do not match
- Publisher misconfiguration (exchange, topic, routing key are not what they should be)
- For AMQP 0-9-1, missing bindings on the target exchange
- A resource alarm is in effect: see the section below
- Network connection has failed and the client did not recover: see the section above

Inspecting the topology and metrics usually helps narrow the problem quickly. For example, the individual exchange page in management UI can be used to confirm that there is inbound message activity (ingress rate above zero) and what the bindings are.

In the following example the exchange has no bindings, so no messages will be routed anywhere:

An exchange without bindings

Bindings can also be listed using rabbitmq-diagnostics:

```
# note that the implicit default exchange bindings won't
# be listed as of RabbitMQ 3.8

rabbitmq-diagnostics list_bindings --vhost "/"
=> Listing bindings for vhost /...

In the example above the command yields no results.
```

Starting with RabbitMQ 3.8, there's a new metric for unroutable dropped messages:

Unroutable message metrics diagram

In the example above, all published messages are dropped as unroutable (and non-mandatory). See the Unroutable Message Handling section in this guide.

Cluster-wide and connection metrics as well as server logs will help spot a resource alarm in effect.

## Resource Alarms

When a resource alarm is in effect, all connections that publish will be blocked until the alarm clears. Clients can opt-in to receive a notification when they are blocked. Learn more in the Resource Alarms guide.

## Protocol Exceptions

With some protocols, such as AMQP 0-9-1 and STOMP, publishers can run into a condition known as a protocol error (exception). For example, publishing to a non-existent exchange or binding an exchange to an non-existent exchange will result in a channel exception and will render the channel closed. Publishing is not possible on a closed channel. Such events are logged by the RabbitMQ node the publisher was connected to. Failed publishing attempts will also result in client-side exceptions or errors returned, depending on the client library used.

## Concurrent Publishing on a Shared Channel

Concurrent publishing on a shared channel is not supported by client libraries. Learn more in the Concurrency Considerations section.<file_sep>---
id: index
title: The Basics
---

## The Basics

Publishers publish to a destination that varies from protocol to protocol:

- In AMQP 0-9-1, publishers publish messages to exchanges.
- In AMQP 1.0, publishing happens on a link.
- In MQTT, publishers publish to topics. 
- STOMP supports a variety of destination types: topics, queues, AMQP 0-9-1 exchanges. 

This is covered in more details in the protocol-specific differences section.

A message is sent down a channel established between the publisher and a broker. On the broker side, the channel process will determin the destination queue(s) by looking up the exchange and its bindings. The message will then be forwarded on to any matching queues.

## Publisher Lifecycle

Publishers are often long lived: that is, throughout the lifetime of a publisher it publishes multiple messages. Opening a connection or channel (session) to publish a single message is not optimal.

Publishers usually open their connection(s) during application startup. They often would live as long as their connection or even application runs.

Publishers can be more dynamic and begin publishing in reaction to a system event, stopping when they are no longer necessary. This is common with WebSocket clients used via Web STOMP and Web MQTT plugins, mobile clients and so on.

## Protocol Differences

The process of publishing messages is quite similar in every protocol RabbitMQ supports. All four protocols allow the user to publish a message which has a payload (body) and one or more message properties (headers).

All four protocols also support an acknowledgement mechanism for publishers which allows the publishing application to keep track of the messages that have or haven't been successfully accepted by the broker, and continue publishing the next batch or retry publishing the current one.

The difference typically have more to do with the terminology used than the semantics. Message properties also vary from protocol to protocol.
AMQP 0-9-1

### AMQP 0-9-1

In AMQP 0-9-1, publishing happens on a channel using routing rules determined by an exchange. The broker channel process uses a routing topology set up by defining bindings between one or more queues and the exchange, or source exchange and destination exchange. Successfully routed messages are stored in queues.

The role of each entity is covered in the AMQP 0-9-1 concepts guide.

### AMQP 1.0

In AMQP 1.0 publishing happens within a context of a link.

### MQTT 3.1

In MQTT 3.1.1, messages are published on a connection to a topic. Topics perform both routing and storage. In RabbitMQ, a topic is backed by a queue internally.

When publisher chooses to use QoS 1, published messages are acknowledged by the routing node using a PUBACK frame, the publisher acknowledgement mechanism in MQTT 3.1.

Publishers can provide a hint to the server that the published message on the topic must be retained (stored for future delivery to new subscribers). Only the latest published message for each topic can be retained.

Other than closing the connection, there is no mechanism by which the server can communicate a publishing error to the client.

See the MQTT and MQTT-over-WebSockets guides to learn more.

### STOMP

STOMP clients publish on a connection to one or more destinations which can have different semantics in case of RabbitMQ.

STOMP provides a way for the server to communicate an error in message processing back to the publisher. Its variation of publisher acknowledgements is called receipts, which is a feature clients enable when publishing.

See the STOMP guide, STOMP-over-WebSockets and the STOMP 1.2 spec to learn more.<file_sep>---
id: index
title: Exchange Types
---

## Exchange Types

### Default Exchange

### Fanout Exchange

### Direct Exchange

### Topic Exchange

### Header Exchange

### Other Exchange Types

## Exchange Arguments

### Auto-Delete<file_sep>---
id: docker
title: Run using Docker
sidebar_label: Docker
---

> **TODO**: Write this page.

<file_sep>---
id: precompiled
title: Run from precompiled binaries
sidebar_label: Precompiled binaries
---

We provide precompiled binaries for both Unix-like systems and Microsoft
Windows.

## Get Erlang/OTP

RabbitMQ relies on the Erlang/OTP runtime to run.

Please refer to the [Erlang/OTP requirements and install guide](erlang)
to learn about:
* what version of Erlang/OTP to get
* how to install it

## Get and run RabbitMQ

Once the appropriate version of Erlang/OTP is available on your
operating system, it is very easy to run RabbitMQ as an unprivileged
user to play with it.

### Unix-like systems

1.  Download the [`generic-unix` archive]:
    ```sh
    wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.2/rabbitmq-server-generic-unix-3.8.2.tar.xz
    ```

2.  Unpack the archive:
    ```sh
    tar xf rabbitmq-server-generic-unix-3.8.2.tar.xz
    ```

3.  Start RabbitMQ:
    ```sh
    ./rabbitmq_server-3.8.2/sbin/rabbitmq-server
    ```

    RabbitMQ will print the following banner:
    ```text

      ##  ##      RabbitMQ 3.8.2
      ##  ##
      ##########  Copyright (c) 2007-2019 Pivotal Software, Inc.
      ######  ##
      ##########  Licensed under the MPL 1.1. Website: https://rabbitmq.com

      Doc guides: https://rabbitmq.com/documentation.html
      Support:    https://rabbitmq.com/contact.html
      Tutorials:  https://rabbitmq.com/getstarted.html
      Monitoring: https://rabbitmq.com/monitoring.html

      Logs: .../rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini.log
            .../rabbitmq_server-3.8.2/var/log/rabbitmq/rabbit@cassini_upgrade.log

      Config file(s): (none)

      Starting broker... completed with 0 plugins.
    ```

[`generic-unix` archive]: https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.2/rabbitmq-server-generic-unix-3.8.2.tar.xz

### Microsoft Windows

> **TODO**: Write this section.
<file_sep>---
id: macos
title: Install on macOS
sidebar_label: macOS
---

> **TODO**: Write this page.
<file_sep>---
id: index
title: Welcome to the Developer Reference
sidebar_label: Introduction
---

TODO<file_sep>---
id: index
title: Queues
---

## Basics

## Queue Properties<file_sep>---
id: dynamic-shovels
title: Dynamic Shovels
---

TODO<file_sep>---
id: sharding
title: Sharding / Hash Based Routing
---

TODO<file_sep>---
title: Simplifying rolling upgrades with feature flags
author: <NAME>
---

In this post we will cover **<a href="https://next.rabbitmq.com/feature-flags.html">feature flags</a>**, a new subsystem in RabbitMQ 3.8. Feature flags will allow a rolling cluster upgrade to the next minor version, without requiring all nodes to be stopped before upgrading.

<!--truncate-->

## Minor Version Upgrades Today: RabbitMQ 3.6.x to 3.7.x

It you had to upgrade a cluster from RabbitMQ 3.6.x to 3.7.x, you probably had to use one of the following solutions:

* Deploy a new cluster alongside the existing one (this strategy is known as the [blue-green deployment](blue-green-deployment.html)), then migrate data &amp; clients to the new cluster
* Stop all nodes in the existing cluster, upgrade the last node that was stopped first, then continue upgrading all other nodes, one-by-one

Blue-green deployment strategy is low risk but also fairly complex to automate. On the other hand, a cluster-wide shutdown affects availability. Feature flags are meant to provide a 3rd option by making rolling cluster upgrades possible and reasonably easy to automate.

## The Feature Flags Subsystem

Feature flags indicate a RabbitMQ node's capabilities to its cluster peers. Previously nodes used versions to assess compatibility with cluster versions. There are many ways in which nodes in a distributed system can become incompatible, including Erlang and dependency versions. Many of those aspects are not reflected in a set of version numbers. Feature flags is a better approach as it can reflect more capabilities of a node, whether it is a particular feature or internal communication protocol revision. In fact, with some message protocols RabbitMQ supports clients have a mechanism for clients to indicate their capabilities. This allows client libraries to evolve and be upgraded independently of RabbitMQ nodes.

For example, RabbitMQ 3.8.0 introduces a new queue type, <a href="https://next.rabbitmq.com/quorum-queues.html">quorum queues</a>. To implement them, an internal data structure and a database schema were modified. This impacts the communication with other nodes because the data structure is exchanged between nodes, and internal data store schema is replicated to all nodes.

Without the feature flags subsystem, it would be impossible to have a RabbitMQ 3.8.0 node inside a cluster where other nodes are running RabbitMQ 3.7.x. Indeed, the 3.7.x nodes would be unable to understand the data structure or the database schema from 3.8.0 node. The opposite is also true. That's why RabbitMQ today prevents this from happening by comparing versions and by denying clustering when versions are considered incompatible (the policy considers different minor/major versions to be incompatible).

New in RabbitMQ 3.8.0 is the feature flags subsystem: when a single node in a 3.7.x cluster is upgraded to 3.8.0 and restarted, it will not immediately enable the new features or migrate its database schema because the feature flags subsystem told it not to. It could determine this because RabbitMQ 3.7.x supports no feature flags at all, therefore new features or behaviours in RabbitMQ 3.8.0 cannot be used before all nodes in the cluster are upgraded.

After a partial upgrade of a cluster to RabbitMQ 3.8.0, all nodes are acting as 3.7.x nodes with regards to incompatible features, even the 3.8.0 one. In this situation, quorum queues are unavailable. Operator must finish the upgrade by upgrading all nodes. When that is done, the operator can decide to enable the new feature flags provided by RabbitMQ 3.8.0: one of them enables quorum queues. This is done using RabbitMQ CLI tools or <a href="https://www.rabbitmq.com/management.html">management UI</a> and supposed to be performed by deployment automation tools. The idea is that the operator needs to confirm that her cluster doesn't have any remaining RabbitMQ 3.7.x nodes that might rejoin the cluster at a later point.

Once a new feature flag is enabled, it is impossible to add a node that runs an older version to that cluster.

## Demo with RabbitMQ 3.8.0

Let's go through a complete upgrade of a RabbitMQ 3.7.x cluster. We will take a look at the feature flags in the process.

We have the following 2-node cluster running RabbitMQ 3.7.12:

<img style="border: solid 1px #75757f;" src="https://www.rabbitmq.com/img/blog/feature-flags/01-list-of-nodes-on-node-A-running-3.7.x.png" alt="" />

We now upgrade node A to RabbitMQ 3.8.0 and restart it. Here is what the management overview page looks like after the node is restarted:

<img style="border: solid 1px #75757f;" src="https://www.rabbitmq.com/img/blog/feature-flags/02-list-of-nodes-on-node-A-running-3.8.x.png" alt="" />

We can see the difference of versions in the list of nodes: their version is displayed just below their node name.

The list of feature flags provided by RabbitMQ 3.8.0 is now available in the management UI on node A:

<img style="border: solid 1px #75757f;" src="https://www.rabbitmq.com/img/blog/feature-flags/03-list-of-feature-flags-on-node-A-running-3.8.x.png" alt="" />

This page will not exist on node B because it is still running RabbitMQ 3.7.12.

On node A, we see that the `quorum_queue` feature flag is marked as `Unavailable`. The reason is that node B (still running RabbitMQ 3.7.12) does not known about `quorum_queue` feature flag, therefore node A is not allowed to use that new feature flag. This feature flag cannot be enabled until all nodes in the cluster support it.

For instance, we could try to declare a quorum queue on node A, but it is denied:

<img style="border: solid 1px #75757f;" src="https://www.rabbitmq.com/img/blog/feature-flags/04-quorum-queue-declare-denied-on-node-A-running-3.8.x.png" alt="" />

After node B is upgraded, feature flags are available and they can be enabled. We proceed and enable `quorum_queue` by clicking the `Enable` button:

<img style="border: solid 1px #75757f;" src="https://www.rabbitmq.com/img/blog/feature-flags/05-quorum_queue-feature-flag-enabled-on-node-B-running-3.8.x.png" alt="" />

Now, we can declare a quorum queue:

<img style="border: solid 1px #75757f;" src="https://www.rabbitmq.com/img/blog/feature-flags/06-quorum-queue-declare-accepted-on-node-A-running-3.8.x.png" alt="" />

## To Learn More

The <a href="https://next.rabbitmq.com/feature-flags.html">Feature Flags subsystem documentation</a> describes in greater details how it works and what operators and plugin developers should pay attention to.

Note that feature flags are not a guarantee that a cluster shutdown will never be required for upgrades in the future: the ability to implement a change using a feature flag depends on the nature of the change, and is decided on a case-by-case basis. Correct behaviour of a distributed system may require that all of its components behave in a certain way, and sometimes that means that they have to be upgraded in lockstep.

Please give feature flags a try and let us know what you think on the <a href="https://groups.google.com/forum/#!forum/rabbitmq-users">RabbitMQ mailing list</a>!
<file_sep>---
title: RabbitMQ 3.8.2 release
author: <NAME>
---

The RabbitMQ team is pleased to announce the release of RabbitMQ 3.8.2.

This is a maintenance release. Release notes can be found in the [change
log](/changelog.html). RabbitMQ 3.7 series will [go out of support on
March 31, 2020](/versions.html).

This release [requires Erlang/OTP 21.3](/which-erlang.html).

Binary builds and packages of the new release can be found on
[GitHub](https://github.com/rabbitmq/rabbitmq-server/releases/),
[Package Cloud](https://packagecloud.io/rabbitmq) and
[Bintray](https://bintray.com/rabbitmq/).
See [RabbitMQ downloads](/download.html) page for installation guides.

We encourage all users of earlier versions of RabbitMQ to upgrade to
this latest release.

As always, we welcome any questions, bug reports, and other
feedback on this release, as well as general suggestions for
features and enhancements in future releases. Contact us via the
[rabbitmq-users](https://groups.google.com/forum/#!forum/rabbitmq-users)
Google group.
<file_sep>---
id: throttling
title: Publisher Throttling and Resource Alarms
sidebar_label: Publisher Throttling
---

When a cluster node has a [resource alarm](?) in effect, all connections in the cluster that attempt to publish a message will be blocked until all alarms across the cluster clear.

When a connection is blocked, no more data sent by this connection will be read, parsed or processed on the connection. When a connection is unblocked, all client traffic processing resumes.

Compatible AMQP 0-9-1 clients will be notified when they are blocked and unblocked.

Writes on a blocked connection will time out or fail with an I/O write exception.<file_sep>---
id: debian
title: Install on Debian and Ubuntu
sidebar_label: Debian
---

## Provide Erlang/OTP

Erlang/OTP packages in the official Debian and Ubuntu repositories are
often too old for RabbitMQ's [Erlang/OTP version requirements](erlang).

There are several providers of recent Erlang/OTP releases. Each one has
its own section.

If you already have Erlang available as a Debian package, you can [skip
to the next section](#install-rabbitmq).

### RabbitMQ repository [recommended]

The RabbitMQ team provides its own Erlang/OTP packages for Debian &
Ubuntu. This is the recommended repository.

#### Configure the repository

1.  Add the repository to the sources list after replacing
    [`$distribution`](#erlangotp-supported-debian-and-ubuntu-distributions)
    and [`$component`](#erlangotp-repository-components-available):
    ```sh
    sudo cat <EOF >/etc/apt/sources.list.d/rabbitmq-erlang.list
    deb http://dl.bintray.com/rabbitmq-erlang/debian $distribution $component
    EOF
    ```
2.  Install `apt-transport-https` to allow apt-get(8) to use the added
    repository:
    ```sh
    sudo apt-get install apt-transport-https
    ```

3.  Add the [PGP key used to sign the repository][PGP signing key]:
    ```sh
    wget -O- https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc | \
    sudo apt-key add -
    ```

4.  Refresh the APT package index:
    ```sh
    sudo apt-get update
    ```

### Erlang Solutions

> **TODO**: Write this section

## Install RabbitMQ

1.  Add the repository to the sources list after replacing
    [`$distribution`](#supported-debian-and-ubuntu-distributions)
    and [`$component`](#rabbitmq-repository-components):
    ```sh
    sudo cat <EOF >/etc/apt/sources.list.d/rabbitmq-erlang.list
    deb http://dl.bintray.com/rabbitmq/debian $distribution $component
    EOF
    ```
2.  Install `apt-transport-https` to allow apt-get(8) to use the added
    repository:
    ```sh
    sudo apt-get install apt-transport-https
    ```

3.  Add the [PGP key used to sign the repository][PGP signing key]:
    ```sh
    wget -O- https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc | \
    sudo apt-key add -
    ```

4.  Refresh the APT package index:
    ```sh
    sudo apt-get update
    ```

5.  Install the `rabbitmq-server` package:
    ```sh
    sudo apt-get install rabbitmq-server
    ```

## Start RabbitMQ

As per de Debian Policy, RabbitMQ is started automatically when the
package is installed.

Depending on the version of Debian/Ubuntu you use, you can start,
restart and stop it using either SysV init scripts or systemd.

### Start service with systemd

```sh
systemctl start rabbitmq-server
systemctl restart rabbitmq-server
systemctl stop rabbitmq-server
```

### Start service with SysV init script

```sh
service rabbitmq-server start
service rabbitmq-server restart
service rabbitmq-server stop
```

## Supported Debian and Ubuntu distributions

The repository supports several distributions of Debian and Ubuntu:

| Distribution| Value of `$distribution` in the sources.list |
|-----------------------|-----------|
| Debian Jessie (8)     | `jessie`  |
| Debian Stretch (9)    | `stretch` |
| Debian Buster (10)    | `buster`  |
| Debian Sid (unstable) | `buster`  |
| Ubuntu 16.04          | `xenial`  |
| Ubuntu 18.04          | `bionic`  |
| Ubuntu 19.04          | `bionic`  |
| Ubuntu 19.10          | `bionic`  |

## Repository components available

### RabbitMQ repository components

The repository uses components to allow to "pin" to a RabbitMQ release
series without pininng a specific version.

The following components are available:

| Component | What it provides |
|-----------|------------------|
| `main` | All packages |
| `rabbitmq-server` | All `rabbitmq-server` packages |
| `rabbitmq-server-v3.6.x` | All `rabbitmq-server` 3.6.x packages |
| `rabbitmq-server-v3.7.x` | All `rabbitmq-server` 3.7.x packages |
| `rabbitmq-server-v3.8.x` | All `rabbitmq-server` 3.8.x packages |

### Erlang/OTP repository components

The repository uses components to allow to "pin" to an Erlang/OTP
release series without pininng a specific version.

The following components are available:

| Component | What it provides |
|-----------|------------------|
| `main` | All versions of the Erlang/OTP and Elixir packages |
| `erlang` | All versions of the Erlang/OTP packages |
| `erlang-19.x` | All Erlang/OTP 19.x packages |
| `erlang-20.x` | All Erlang/OTP 20.x packages |
| `erlang-21.x` | All Erlang/OTP 21.x packages |
| `erlang-22.x` | All Erlang/OTP 22.x packages |

[PGP signing key]: https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
<file_sep>---
id: windows
title: Install on Microsoft Windows
sidebar_label: Microsoft Windows
---

> **TODO**: Write this page.
<file_sep>---
id: avoiding-overload
title: Avoiding Overload
---

Talk about features such as queue limit policies.

TODO<file_sep>---
id: federated-queues
title: Federated Queues
---

TODO<file_sep>---
id: consume-message
title: Consume a message
---

In the previous step, we published a message after writing a small
Python AMQP 0-9-1 program. Our next goal is to consume that message
using another Python program.

> **TODO**: Write this page.
<file_sep>---
id: safety-at-rest
title: Safety At-Rest
---

TODO<file_sep>---
id: use-perftest
title: Run PerfTest
---

When you want to quickly test a RabbitMQ node or cluster, you can use
PerfTest to easily publish and consume arbitrary messages without having
to develop your own client.

> **TODO**: Write this page.
<file_sep>---
id: index
title: Introduction
---

One reason for choosing RabbitMQ is its powerful routing capability. In this set of guides will look at some archetypical routing scenarios and some more creative examples that demonstrate what you can do with RabbitMQ.

1. Point-to-point
2. Publish-subscribe with fanout exchange
3. Publish-subscribe with topic, direct, header exchanges
4. Multi-Layered Routing
5. Public Message Exchange, Private Consumer Exchange
6. Sharding / Hash Based Routing
7. Ephemeral infrastructure
8. Class of Service / Priority Routing
9. RPC / Reply To Queues
10. Delayed Message Routing
11. Retry Message Routing<file_sep>---
id: quorum-queues
title: Quorum Queues
---


TODO<file_sep>---
id: query-queue-infos
title: Query queue informations
---

The previous steps allowed us to publish to and consume messages from
RabbitMQ, using two independent programs.

Now that messages are flowing through RabbitMQ, it is important to
observe and monitor it to ensure everything is healthy. The first tool
we will explore is the CLI: we will use it to query various informations
of a queue.

> **TODO**: Write this page.
<file_sep>---
id: multi-layered-routing
title: Multi-Layered Routing
---

TODO<file_sep>---
title: Moving website to Docusaurus
author: <NAME>
---

We finally moved from a home-grown website almost-static engine to an
open-source generator called [Docusaurus](https://docusaurus.io/).

We are happy with the change!

It even supports Erlang hilighting:

```erlang
hello_world() ->
    io:format("Hello World!~n").
```
<file_sep>---
id: index
title: Consumers
---

## Basics

<file_sep>---
id: stream-processing
title: Stream Processing Frameworks
---

TODO<file_sep>---
id: intro
title: Introduction to RabbitMQ
---

## Messaging that just works

RabbitMQ is an open source messaging system that supports a variety of messaging use cases including:

- Microservice asynchronous communication
- Publish/Subscribe
- Point-to-point communication
- Work queues
- Request/Reply mechanism without the need for service discovery
- IOT communications via MQTT
- Web frontend-backend communication via STOMP
- High availability

See our [Concepts](concepts/index.md) page to learn more about general messaging patterns and the RabbitMQ building blocks that enable you to build the messaging architecture that you need.

## Why RabbitMQ?

There are many choices out there, so what makes RabbitMQ a great choice?

### Simple to deploy, simple to run.

Unlike many other messaging systems, RabbitMQ is a single, integrated system, without dependencies on external consensus services such as Etcd or Apache ZooKeeper. It is not complex to operate and does not require a dedicated operations teamto run it.

It deploys on all major Linux distributions, Windows and has first class Kubernetes support.

### Supports many protocols, many languages and use cases

RabbitMQ natively supports AMQP 0.9.1 but also supports:

- AMQP 1.0
- MQTT
- STOMP

It has client libraries in most programming languages.

### Integrated UI out-of-the-box and integrations with Grafana and Prometheus

RabbitMQ has a web user interface and API out-of-the-box simplying usage. You don't need to rely on third party web consoles or be forced to use the CLI tooling.

### Extremely flexible, supporting architectures that evolve

They call RabbitMQ the Swiss army knife of messaging. It supports many use cases meaning you don't need to deploy multiple messaging solutions to support your architecture. As your architecture changes, RabbitMQ is flexible enough to support your changing needs.

### Battle tested

RabbitMQ has been used in production for over 10 years and is one of the most widely deployed messaging systems in the world today.

### Open Source

RabbitMQ is open source and we welcome contributions. Please check out our [Be a Contributor](contribution/index.md) page to learn more.

We also have various ways for the community to engage:

- [RabbitMQ Users Google Group aka the mailing list](https://groups.google.com/forum/#!forum/rabbitmq-users)
- [GitHub Discussions](https://github.com/rabbitmq/discussions)
- [Slack channel](https://rabbitmq-slack.herokuapp.com/)

### Commercial Support

For those that need it, we offer commericial support and also an enterprise version of RabbitMQ which ships with extra features important for the enterprise.
<file_sep>---
id: alternate-exchange
title: Alternate Exchanges
---

TODO<file_sep>---
id: failures
title: Types of Publisher Failure
---

## Connection failures

Network connection between clients and RabbitMQ nodes can fail. How applications handle such failures directly contributes to the data safety of the overall system.

### Heartbeats

It can take time to detect the loss of a TCP connection so in order to speed up connection loss detection, an explicit [heartbeat](?) can be configured when opening the connection.

### Connection Recovery

Several RabbitMQ clients support automatic recovery of connections and topology (queues, exchanges, bindings, and consumers): Java, .NET, Bunny are some examples.

Other clients do not provide automatic recovery as a feature but do provide examples of how application developers can implement recovery.

The automatic recovery process for many applications follows the following steps:

- Reconnect to a reachable node
- Restore connection listeners
- Restore channel listeners
- Re-open channels
- Restore channel listeners
- Restore channel basic.qos setting, publisher confirms and transaction settings

After connections and channels are recovered, topology recovery can start. Topology recovery includes the following actions, performed for every channel:

- Re-declare exchanges (except for predefined ones)
- Re-declare queues
- Recover all bindings
- Recover all consumers

## Confirm timeouts

When a confirm is not received after a configured time period the publisher must choose whether it should send the mesage again or not. Resending corresponds with At-Least-Once guarantees while not sending could result in the message being lost (at-most-once).

## Non-existent exchange

An attempt to publish to a non-existent exchange will result in a channel-level exception with the code of 404 Not Found and render the channel it was attempted on to be closed.

## Unroutable

If the publisher has set the [mandatory flag](confirms#mandatory-flag) then it will be notified if the message could not be routed to a queue. If the flag is not set then the message is silently dropped.

## Queue Full

A queue can have a [length or size limit](?) applied. When at that limit, a queue will either:

- reject the message (when [reject-publish](?) has been configured).
- accept the message but drop the oldest message (when [drop-head](?) has been configured and no [deadletter exchange](?) has been configured).
- accept the message but eject the oldest message from the queue and forward it to the configured deadletter exchange (when [drop-head](?) has been configured and also a [deadletter exchange](?) has been configured).

## Channel process crash

Channel process crashes are extremely rare and result in the loss of the channel. A new channel must be reopened. 

## Blocked Connection (publisher throttling)

When a RabbitMQ broker is being overloaded by publishers, it uses a [flow control mechanism to throttle publishers](throttling). When a connection is blocked, no messages can be sent down any open channels.
    
## Notes on Exception Handling

Publishers generally can expect two types of exception:

- A network I/O exception due to a failed write or timeout
- An acknowledgement delivery timeout

Note that "exception" here means an error in the general sense; some programming languages do not have exceptions at all so clients there would communicate the error differently. The discussion and recommendations in this section should apply equally to most client libraries and programming languages.

The former type of exception can occur immediately during a write or with a certain delay. This is because certain types of I/O failures (e.g. to high network congestion or packet drop rate) can take time to detect. Publishing can continue after the connection recovers but if the connection is blocked due to an alarm, all further attempts will fail until the alarm clears. This is covered in more details below in the [Publisher Throttling page](throttling).

The latter type of exception can only happen when the application developer provides a timeout. What timeout value is reasonable for a given application is decided by the developer. It should not be lower than the effective heartbeat timeout.<file_sep>---
id: index
title: Policies
---

## Basics

## Setting policies<file_sep>#!/bin/sh
# vim:sw=4:et:

# This is a script to quickly get a running RabbitMQ node as an
# unprivileged user, based on the generic-unix archive.

set -u

LATEST_BRANCH=3.8

main() {
    downloader --check
    need_cmd mktemp
    need_cmd erl

    local _ansi_escapes_are_valid=false
    if [ -t 2 ]; then
        if [ "${TERM+set}" = 'set' ]; then
            case "$TERM" in
                xterm*|rxvt*|urxvt*|linux*|vt*)
                    _ansi_escapes_are_valid=true
                ;;
            esac
        fi
    fi

    # 1. Create temporary directory (for download & Erlang build)
    local _dir
    _dir="$(mktemp -d 2>/dev/null || ensure mktemp -d -t rabbitmq)"

    # 2. Query latest RabbitMQ version.
    if $_ansi_escapes_are_valid; then
        printf "\033[1minfo:\033[0m querying latest ${LATEST_BRANCH}.x version\n" 1>&2
    else
        printf '%s\n' "info: querying latest ${LATEST_BRANCH}.x version" 1>&2
    fi
    local _tags_api=https://api.github.com/repos/rabbitmq/rabbitmq-server/git/matching-refs/tags/v${LATEST_BRANCH};
    local _tags_list="${_dir}/tags.json"
    ensure downloader "$_tags_api" "$_tags_list"

    local rmq_version=$(ensure awk '
/"ref":/ {
    tag = $0;
    sub(/.*\/tags\/v/, "", tag);
    sub(/".*$/, "", tag);
    if (tag ~ /^[0-9]+\.[0-9]+\.[0-9]+$/) {
        latest = tag;
    }
}
END {
    print latest;
}' "${_tags_list}")
    if $_ansi_escapes_are_valid; then
        printf "\033[1minfo:\033[0m latest ${LATEST_BRANCH}.x version: ${rmq_version}\n" 1>&2
    else
        printf '%s\n' "info: latest ${LATEST_BRANCH}.x version: ${rmq_version}" 1>&2
    fi

    local gen_unix_dir=rabbitmq_server-$rmq_version
    local gen_unix_file=rabbitmq-server-generic-unix-$rmq_version.tar.xz
    local gen_unix_url=https://github.com/rabbitmq/rabbitmq-server/releases/download/v$rmq_version/$gen_unix_file

    local _file="${_dir}/${gen_unix_file}"
    local _rmqdir="${_dir}/$gen_unix_dir"

    # 3. Download RabbitMQ.
    local _url="${gen_unix_url}"
    if $_ansi_escapes_are_valid; then
        printf "\033[1minfo:\033[0m downloading generic-unix archive\n" 1>&2
    else
        printf '%s\n' 'info: downloading generic-unix archive' 1>&2
    fi

    ensure mkdir -p "$_dir"
    ensure downloader "$_url" "$_file"

    # 4. Unpack RabbitMQ.
    if $_ansi_escapes_are_valid; then
        printf "\033[1minfo:\033[0m unpacking generic-unix archive\n" 1>&2
    else
        printf '%s\n' 'info: unpacking generic-unix archive' 1>&2
    fi
    cd "$_dir"
    tar xf "$_file"

    # 5. Enable the management plugin.
    if $_ansi_escapes_are_valid; then
        printf "\033[1minfo:\033[0m enabling management web UI\n" 1>&2
    else
        printf '%s\n' 'info: enabling management web UI' 1>&2
    fi
    ensure "$_rmqdir"/sbin/rabbitmq-plugins \
        --quiet \
        enable \
        --offline \
        rabbitmq_management >/dev/null

    # 6. Start RabbitMQ.
    cat <<EOF

,---------------------------------------------------------------------
| RabbitMQ is installed in:
| $_rmqdir
| 
| Configuration files:
| $_rmqdir/etc
| 
| Log files:
| $_rmqdir/var/log/rabbitmq
| 
| Once RabbitMQ has started below:
| 
|   * You can stop it by typing Ctrl+C in this terminal, or by running:
|     $_rmqdir/sbin/rabbitmqctl stop
| 
|   * You can restart it later by running:
|     $_rmqdir/sbin/rabbitmq-server
| 
|   * You can enable and disable plugins using:
|     $_rmqdir/sbin/rabbitmq-plugins
| 
|   * The management web UI is available at:
|     http://localhost:15672
| 
|     Login: guest
|     Password: <PASSWORD>
\`--------------------------------------------------------------------

EOF

    if $_ansi_escapes_are_valid; then
        printf "\033[1minfo:\033[0m starting RabbitMQ\n" 1>&2
    else
        printf '%s\n' 'info: starting RabbitMQ' 1>&2
    fi
    exec "$_rmqdir"/sbin/rabbitmq-server
}

# --------------------------------------------------------------------
# Code taken from Rustup installeri script.
# See:
#   https://www.rust-lang.org/learn/get-started
#   https://sh.rustup.rs.
# --------------------------------------------------------------------

say() {
    printf 'get-rabbitmq: %s\n' "$1"
}

err() {
    say "$1" >&2
    exit 1
}

need_cmd() {
    if ! check_cmd "$1"; then
        err "need '$1' (command not found)"
    fi
}

check_cmd() {
    command -v "$1" > /dev/null 2>&1
}

# Run a command that should never fail. If the command fails execution
# will immediately terminate with an error showing the failing
# command.
ensure() {
    if ! "$@"; then err "command failed: $*"; fi
}

# This wraps curl or wget. Try curl first, if not installed,
# use wget instead.
downloader() {
    local _dld
    if check_cmd curl; then
        _dld=curl
    elif check_cmd wget; then
        _dld=wget
    elif check_cmd fetch; then
        _dld=fetch
    else
        _dld='curl, wget or fetch' # to be used in error message of need_cmd
    fi

    if [ "$1" = --check ]; then
        need_cmd "$_dld"
    elif [ "$_dld" = curl ]; then
        if ! check_help_for curl --proto --tlsv1.2; then
            echo "Warning: Not forcing TLS v1.2, this is potentially less secure"
            curl --silent --show-error --fail --location "$1" --output "$2"
        else
            curl --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2"
        fi
    elif [ "$_dld" = wget ]; then
        if ! check_help_for wget --https-only --secure-protocol; then
            echo "Warning: Not forcing TLS v1.2, this is potentially less secure"
            wget "$1" -O "$2"
        else
            wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2"
        fi
    elif [ "$_dld" = fetch ]; then
        fetch -o "$2" "$1"
    else
        err "Unknown downloader"   # should not reach here
    fi
}

check_help_for() {
    local _cmd
    local _arg
    local _ok
    _cmd="$1"
    _ok="y"
    shift

    # If we're running on OS-X, older than 10.13, then we always
    # fail to find these options to force fallback
    if check_cmd sw_vers; then
        if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then
            # Older than 10.13
            echo "Warning: Detected OS X platform older than 10.13"
            _ok="n"
        fi
    fi

    for _arg in "$@"; do
        if ! "$_cmd" --help | grep -q -- "$_arg"; then
            _ok="n"
        fi
    done

    test "$_ok" = "y"
}

main "$@" || exit 1
<file_sep>---
id: deadletter-exchange
title: Deadletter Exchanges
---


TODO<file_sep>---
id: routing
title: Message Routing
---

RabbitMQ's powerful routing is one of its killer features. Other messaging systems are based on topics where messages go into a topic and out of a topic. Message ordering across topics is not possible.

RabbitMQ has a different model. Publishers and consumers are decoupled so that any consumer can receive any combination of events in temporal order. Publishers simply name an exchange, add some optional meta-data and no more. This flexibility creates evolutionary architectures that are easy to change.

## Messages

A publisher sends a message payload, such as a JSON document, alongwith:

- an exchange name
- an optional routing key (a string value)
- message properties
- message headers

The channel process on the broker routes the message to queues based on the type of exchange and any queue bindings that exist.

> Remember that exchanges and bindings are meta-data, they consistute the logical routing. Under the hood, messages flow from publisher channel to queue to consumer channel.

## Exchange Types

There are five standard exchange types:

- Default exchange (for point-to-point messaging)
- Fanout (broadcast)
- Topic (routing based on wildcard matching of routing key)
- Direct (routing based on exact match of routing key)
- Headers (routing based on message headers)

There are more exchange types that are covered in the Advanced Routing page.

> The topic, direct and headers exchange can be thought of as filters. Every queue binding is evaluated to see if the message should be routed to that queue or filtered out.

### Default Exchange

When no exchange name is given, the assumed exchange is the amq.default exchange. The message is routed to a queue that matches the routing key. This is the only exchange that gives the publisher the power to choose the destination queue.

For example, the eCommerce site sends a command to the Accounts service to create an account.

![Default exchange](/img/docs/concepts/exchange-default.png)

### Fanout exchange

Use this exchange when you want multiple queues to receive every message without any conditional per-queue filtering. This is classic, simple publish-subscribe.

For example, both the three different services all want to consume all events. Each service has its own queue and each queue is bound to the fanout exchange.

![Fanout exchange](/img/docs/concepts/exchange-fanout.png)

### Topic exchange

This exchange will route messages based on wildcard matching of the routing key. A routing key can be comprised of a single word, or multiple words separated by dots, such as order.placed. 

The available wildcards are:

- \* wildcard that spans one word only
- \# wildcard that spans one or more words

For example, we have the following events: 

- order.placed
- order.cancelled
- order.billing.complete
- order.billing.failed
- order.shipping.complete
- order.shipping.failed
- account.created
- account.deleted

We can create bindings with the following binding keys:

- order.placed - exact match
- order.*.complete - all messages related to a completed sub process of orders
- \*.shipping.\* - all messages related to shipping
- order.# - all messages related to orders

This allows for publish-subscribe where each subscribing service filters out the messages it doesn't care about.

![Topic exchange](/img/docs/concepts/exchange-topic.png)

### Direct exchange

This exchange is a routing rule like the topic exchange except that it only supports exact match on routing keys. It has slightly higher performance than the topic exchange which would be the reason why you might choose it over the more flexible topic exchange.

![Direct exchange](/img/docs/concepts/exchange-direct.png)

### Header exchange

This exchange allows for bindings to filter messages according to headers. A binding can specify one or more headers and their match value. Additionally it specifies whether ALL or ANY of the headers must match.

For example, if we have the custom headers:

- department
- service-level

We could specify a match on one, both or either.

- Match department=sales
- Match both department=sales and service-level=gold
- Match either department=sales or service-level=gold

This exchange is useful when you cannot express all routing within a routing key.

![Headers exchange](/img/docs/concepts/exchange-headers.png)<file_sep>---
id: outbox-pattern
title: Outbox Pattern
---

TODO<file_sep>---
id: shovels
title: Shovels
---

TODO<file_sep>---
id: connections
title: Connections and Channels
---

Clients should open long-lived connections to get the best performance out of RabbitMQ. Once a connection is opened, the second step is to open a **channel**. A channel can be thought of as a virtual connection that multiplexes into a single AMQP connection. It allows a client to open multiple virtual connections with low overhead.

Establishing an AMQP connection and channel is expensive and requires many roundtrips, therefore it is highly advisable to create long lived connections and channels. Creating a connection per message published is extremely inefficient and will yield very low throughput.<file_sep>// vim:sw=2:et:
/**
 * Copyright (c) 2020-present, Pivotal Software, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const React = require('react');

const BlogSidebar = require('../../core/BlogSidebar.js');
const Md = require(`${process.cwd()}/core/Md.js`);

class HomeHero extends React.Component {
  render() {
    return (
      <div id='hero'>
        <div id='hero-pipeline-webinar' className='container'>
          <div className='text'>
            <h1>Streaming Pipelines</h1>
            <h2>A webinar on using RabbitMQ and Project Reactor</h2>
            <h2>Feb 13 | <a href="https://content.pivotal.io/rabbitmq/feb-13-how-to-build-reliable-streaming-pipelines-with-rabbitmq-and-project-reactor-webinar?utm_campaign=reactor-streaming-webinar-banner&amp;utm_source=rabbitmq&amp;utm_medium=website">Register today</a></h2>
          </div>
        </div>
      </div>
    );
  }
}

class Intro extends React.Component {
  render() {
    var blogSidebarConfig = this.props.config;
    blogSidebarConfig.blogSidebarTitle = {default: 'Updates'};
    blogSidebarConfig.blogSidebarCount = 5;

    return (
      <div id='intro'>
        <Md id='description'>
{`
# RabbitMQ is the most widely deployed open source message broker.

With tens of thousands of users, RabbitMQ is one of
the most popular open source message brokers. From
[T-Mobile](https://www.youtube.com/watch?v=1qcTu2QUtrU) to
[Runtastic](https://medium.com/@runtastic/messagebus-handling-dead-letters-in-rabbitmq-using-a-dead-letter-exchange-f070699b952b),
RabbitMQ is used worldwide at small startups and large enterprises.

RabbitMQ is lightweight and easy to deploy on premises and in the
cloud. It supports multiple messaging protocols. RabbitMQ can be
deployed in distributed and federated configurations to meet high-scale,
high-availability requirements.

RabbitMQ runs on many operating systems and cloud environments,
and provides a [wide range of developer tools for most popular
languages](/devtools.html).

See how other people are using RabbitMQ:

<div id="UfEmbeddedHub1501190831892"></div>
<script>window._ufHubConfig = window._ufHubConfig || [];window._ufHubConfig.push({'containers':{'app':'#UfEmbeddedHub1501190831892'},'collection':'453624','openLink':function(url){window.open(url);},'lazyloader':{'itemDisplayLimit':3,'maxTilesPerRow':3,'maxItemsTotal':3},'tileSize':'small','enablePageTracking':false,'baseUrl':'https://content.pivotal.io/','filesUrl':'https://content.cdntwrk.com/','generatedAtUTC':'2017-07-27 21:26:47'});</script>
<script>(function(d,t,u){function load(){var s=d.createElement(t);s.src=u;d.body.appendChild(s);}if(window.addEventListener){window.addEventListener('load',load,false);}else if(window.attachEvent){window.attachEvent('onload',load);}else{window.onload=load;}}(document,'script','https://content.pivotal.io/hubsFront/embed_collection'));</script>
<p id='morelinkafterufembed'><a href='https://content.pivotal.io/rabbitmq'>More <span className="link-arrow"></span></a></p>
`}
        </Md>
        <div id='news'>
          <div id='updates'>
            <BlogSidebar
              language="en"
              config={blogSidebarConfig}
            />
            <p><a href='/blog/'>More updates<span className='link-arrow'></span></a></p>
          </div>
          <div id='twitterfeed'>
            <h2>Tweets</h2>
            <a className="twitter-timeline" href="https://twitter.com/RabbitMQ" data-chrome="noheader nofooter noborders transparent noscrollbar" data-tweet-limit='2'></a>
            <script src="//platform.twitter.com/widgets.js" charSet="utf-8"></script>
            <p><a href='https://twitter.com/RabbitMQ'>More tweets<span className='link-arrow'></span></a></p>
          </div>
        </div>
      </div>
    );
  }
}

class Features extends React.Component {
  render() {
    return (
      <div id='features' className='home-section-container'>
        <div className='home-section'>
          <h1>RabbitMQ Features</h1>
          <div className='tiles'>
            <Md className='tile'>
{`
![Asynchronous Messaging](/img/features/messaging.svg)

## Asynchronous Messaging

Supports [multiple messaging protocols](/protocols.html),
[message queuing](/tutorials/tutorial-two-python.html),
[delivery acknowledgement](/reliability.html),
[flexible routing to queues](/tutorials/tutorial-four-python.html),
[multiple exchange type](/tutorials/amqp-concepts.html).
`}
            </Md>
            <Md className='tile'>
{`
![Developer Experience](/img/features/monitor.svg)

## Developer Experience

Deploy with [BOSH, Chef, Docker and Puppet](/docs/install/). Develop
cross-language messaging with favorite programming languages such
as: Java, .NET, PHP, Python, JavaScript, Ruby, Go, [and many
others](/devtools.html).
`}
            </Md>
            <Md className='tile'>
{`
![Distributed Deployment](/img/features/network.svg)

## Distributed Deployment

Deploy as [clusters](/clustering.html) for high availability and
throughput; [federate](/federation.html) across multiple availability
zones and regions.
`}
            </Md>
            <Md className='tile'>
{`
![Enterprise & Cloud Ready](/img/features/clouds.svg)

## Enterprise &amp; Cloud Ready

Pluggable [authentication](/authentication.html),
[authorisation](/access-control.html) supports [TLS](/ssl.html) and
[LDAP](/ldap.html). Lightweight and easy to deploy in public and private
clouds.
`}
            </Md>
            <Md className='tile'>
{`
![Tools & Plugins](/img/features/tools.svg)

## Tools & Plugins

Diverse array of [tools and plugins](/devtools.html) supporting
continuous integration, operational metrics, and integration to other
enterprise systems. Flexible [plug-in approach](/plugins.html) for
extending RabbitMQ functionality.
`}
            </Md>
            <Md className='tile'>
{`
![Management & Monitoring](/img/features/gauge.svg)

## Management & Monitoring

HTTP-API, command line tool, and UI for [managing and
monitoring](/management.html) RabbitMQ.
`}
            </Md>
          </div>
        </div>
      </div>
    );
  }
}

class GetStarted extends React.Component {
  render() {
    return (
      <div id='getstarted' className='home-section-container'>
        <div className='home-section'>
          <h1>Get Started</h1>
          <div className='tiles'>
            <div className='tile'>
              <a className='btn btn-secondary' href='/docs/install/'>Download + Installation</a>
              <p>Servers and clients for popular operating systems and languages</p>
            </div>
            <div className='tile'>
              <a className='btn btn-primary' href='/docs/getting-started/'>RabbitMQ Tutorials</a>
              <p>Hands-on examples to get you started with RabbitMQ</p>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

class Support extends React.Component {
  render() {
    return (
      <div id='support' className='home-section-container'>
        <div className='home-section'>
          <h1>RabbitMQ Commercial Services</h1>
          <Md id='commercial-items'>
{`
<img src="/img/commercial/commercial-distribution-phone.svg" id='commercial-distribution-phone' />

## Commercial Distribution

Pivotal Software offers a [range of commercial offerings for
RabbitMQ](https://pivotal.io/rabbitmq).
This includes a distribution called [Pivotal RabbitMQ](https://network.pivotal.io/products/pivotal-rabbitmq),
a version that deploys in [Pivotal Platform](https://pivotal.io/platform/services-marketplace/messaging-and-integration/rabbitmq),
and a forthcoming [version for Kubernetes](https://content.pivotal.io/blog/introducing-rabbitmq-for-kubernetes).
These distributions include all of the features of the open source
version, with some additional management features. Support agreements
are part of the commercial licensing.

<img src="/img/commercial/support-and-hosting-phone.svg" id='support-and-hosting-phone' />

## Support + Hosting

Pivotal Software provides [support for open source
RabbitMQ](https://pivotal.io/rabbitmq), available for a subscription
fee. The following companies provide technical support and/or cloud
hosting of open source RabbitMQ:
[CloudAMQP](https://www.cloudamqp.com/),
[Erlang Solutions](https://www.erlang-solutions.com/products/rabbitmq.html),
[AceMQ](https://acemq.com/rabbitmq/),
[Visual Integrator, Inc](http://www.visualintegrator.com/rmq/) and
[Google Cloud Platform](https://console.cloud.google.com/launcher/details/click-to-deploy-images/rabbitmq).
RabbitMQ can also be deployed in AWS and Microsoft Azure.

<img src="/img/commercial/testing-phone.svg" id='testing-phone' />

## Training

The following companies provide free, virtual, or instructor-led courses
for RabbitMQ:
[Pivotal Software](https://academy.pivotal.io/store-catalog),
[Erlang Solutions](https://www.erlang-solutions.com/products/rabbitmq.html),
[Visual Integrator, Inc](http://www.visualintegrator.com/rmq/) and
[LearnQuest](https://www.learnquest.com/course-detail-v3.aspx?cnum=rabbitmq-e1xc).
`}
          </Md>
          <div id=''>
          </div>
        </div>
      </div>
    );
  }
}

class Community extends React.Component {
  render() {
    return (
      <div id='community' className='home-section-container'>
        <div className='home-section'>
          <div className='tiles'>
            <Md className='tile'>
{`
# Community

<a class="btn btn-primary" href="https://groups.google.com/forum/#!forum/rabbitmq-users">Mailing List</a>
<a class="btn btn-secondary" href="https://rabbitmq-slack.herokuapp.com/">Slack Channel</a>

Meet your fellow Rabbits to share stories, advice, and get help.

## Issues & Bug Reports

Start by searching the [Mailing
List](https://groups.google.com/forum/#!forum/rabbitmq-users) archive
and known issues on [Github](https://github.com/rabbitmq?q=rabbitmq).
It’s very likely fellow users have raised the same issue.

## Contributions

RabbitMQ welcomes contributions from the community. Please see our
[Contributors Page](/github.html) to learn more.
`}
            </Md>
            <Md className='tile'>
{`
# Contact Us

## Commercial inquiries
[Pivotal Sales](mailto:<EMAIL>) |
[Pivotal Support](https://support.pivotal.io)

## Other inquiries
[Contact us](/contact.html)

## Report a security vulnerability
[<EMAIL>](mailto:<EMAIL>)

## Social media
[YouTube](https://www.youtube.com/channel/UCSg9GRMGAo7euj3baJi4dOg) |
[Twitter](https://twitter.com/RabbitMQ)
`}
            </Md>
          </div>
        </div>
      </div>
    );
  }
}

class Index extends React.Component {
  render() {
    const {config: config, language = ''} = this.props;

    return (
      <div id="homepage">
        <HomeHero config={config} language={language} />
        <Intro config={config} language={language} />
        <Features config={config} language={language} />
        <GetStarted config={config} language={language} />
        <Support config={config} language={language} />
        <Community config={config} language={language} />
      </div>
    );
  }
}

module.exports = Index;
<file_sep>---
id: index
title: Introduction
---

TODO<file_sep>---
id: use-management-ui
title: Use the management web UI
---

In addition to the CLI we discovered in the previous step, RabbitMQ
provides a web UI to learn about a particular node's configuration, load
and health.

> **TODO**: Write this page.
<file_sep>---
id: index
title: Messaging the RabbitMQ Way
---

In this guide we'll look at the various components of AMQP 0-9-1 such as exchanges, bindings, queues and how they are combined to produce different messaging patterns.

The simplest thing to remember is that:

1. Publishers open long lived connections to a RabbitMQ broker and send messages down a channel.
2. The channel on the broker side routes messages to queues based on routing rules determined by the exchange, exchange to queue bindings and message properties.
3. Messages are stored in queues in FIFO order and remain there until they can be delivered to a consumer.
4. Consumers subscribe to queues over long lived connections and get delivered messages in FIFO order.

## Logical Routing Architecture

![Logical routing architectyre](/img/docs/concepts/logical-routing.png)

## Physical Routing Architecture

In reality, exchanges are not things but simply meta-data that determine message routing. The real flow is publisher channel to queue to consumer channel.

![Physical routing architectyre](/img/docs/concepts/physical-routing.png)

Understanding the physical message flow can help you as you learn more about RabbitMQ clustering and performance.

Most diagrams will use the logical routing style to simplify things.<file_sep>---
id: publish-message
title: Publish a message
---

Now that RabbitMQ is running, we will publish our first message.

RabbitMQ supports several protocols to publish and consume messages and
client libraries are available for dozen of programming languages and
environments. For this tutorial, we will be using a Python AMQP 0-9-1
client library.

> **TODO**: Write this page.

<!--DOCUSAURUS_CODE_TABS-->

<!--Python-->
```python
#!/usr/bin/env python

# This client uses the Pika, an AMQP 0-9-1 client library.
import pika

# Open a connection, then a channel on that connection.
connection = pika.BlockingConnection(
    pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

# Declare a queue named "hello".
channel.queue_declare(queue='hello')

# Publish a message using the channel previously opened.
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')

print(" [x] Sent 'Hello World!'")

# Close the connection, which implicitly closes the channel.
connection.close()
```

<!--Java-->
```java
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.nio.charset.StandardCharsets;

public class Send {
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");

        /* Open a connection, then a channel on that connection. */
        try (Connection connection = factory.newConnection();
            Channel channel = connection.createChannel()) {

            /* Declare a queue named "hello". */
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);

            /* Publish a message using the channel previously opened. */
            String message = "Hello World!";
            channel.basicPublish(
              "", QUEUE_NAME, null,
              message.getBytes(StandardCharsets.UTF_8));

            System.out.println(" [x] Sent '" + message + "'");
        }

        /* The connection is closed, as well as the channel, when they
         * go out of scope. */
    }
}
```

<!--.NET-->
```csharp
using System;
using RabbitMQ.Client;
using System.Text;

class Send
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using(var connection = factory.CreateConnection())
        using(var channel = connection.CreateModel())
        {
            channel.QueueDeclare(
              queue: "hello",
              durable: false,
              exclusive: false,
              autoDelete: false,
              arguments: null);

            string message = "Hello World!";
            var body = Encoding.UTF8.GetBytes(message);

            channel.BasicPublish(
              exchange: "",
              routingKey: "hello",
              basicProperties: null,
              body: body);
            Console.WriteLine(" [x] Sent {0}", message);
        }

        Console.WriteLine(" Press [enter] to exit.");
        Console.ReadLine();
    }
}
```

<!--END_DOCUSAURUS_CODE_TABS-->
<file_sep>---
id: index
title: Introduction
---

Reliability Guide
            - Intro
            - Characteristics of Robust Systems
            - Safety In-Flight
            - Safety At-Rest
            - Avoiding Overload
            - Understanding Flow Control
            - Outbox pattern<file_sep>---
id: safety-vs-performance
title: Safety vs Performance
---

TODO<file_sep>---
id: opensuse
title: Install on OpenSUSE and SLES
sidebar_label: OpenSUSE
---

> **TODO**: Write this page.
<file_sep>---
id: federation
title: Federation
---

TODO<file_sep>---
id: pub-sub-others
title: Publish-Subscribe with the Topic, Direct and Header exchanges
sidebar_label: Pub-Sub with Other Exchanges
---

TODO<file_sep>---
id: ephemeral-infrastructure
title: Ephemeral Exchanges and Queues
---

TODO<file_sep>---
id: high-availability
title: High Availability
---

High availability is the ability of a system to handle failures and remain available/functioning. RabbitMQ must be run as a cluster with the use of replicated queues to achieve true high availability.

## Replicated Queues

RabbitMQ has two types of replicated queue:

- Quorum queues
- Classic HA queues

Today we recommend the usage of Quorum queues as they have stronger durability and availability than Classic HA queues. 

Quorum queues use the battle-tested Raft protocol for message replication across multiple brokers. In a three node cluster, a single broker can be lost without message loss or unavailability. In a five node cluster up to two brokers can be lost.

## Redundant storage + Automated Deployment

Redundant storage offers data safety but not high availability by itself. However, in the event of a broker loss it would be possible to deploy a new broker and attach the storage device. When fully automated this could result in only minutes of downtime once the incident has been detected.<file_sep>---
id: hub-and-spoke
title: Hub and Spoke Topologies
---

TODO<file_sep>---
id: communication-patterns
title: Communication Patterns
---

## Communication Patterns Overview

There are many communications styles to choose from and RabbitMQ supports them all. We'll be teasing apart the following definitions and the impact they have on software architectures:

- Synchronous vs Asynchronous
- RPC vs Durable Messaging
- Point-to-point vs publish-subscribe

> NOTE: Synchronous / asynchronous communication != language threading model (like async/await, futures etc).
>
> They are separate concepts! Read on to understand why.

## Synchronous vs Asynchronous Communication

![Synchronous messaging comic strip](/img/docs/concepts/strip-sync-async.png)

### Synchronous

Communication is **synchronous** when Service A makes a request to Service B and waits for a response. Service A might be using async/await or a future so it doesn't block, but that is an internal implementation detail, the fact is that one application is waiting for a response to its request to another service.

HTTP example:

1. Service A makes a call to the HTTP API of Service B. 
2. Service A waits for a response.
3. Service B processes the request and sends an HTTP response to Service A.
4. Service A resumes execution of that thread/continuation.

Messaging example:

1. Service A sends Service B a message.
2. Service A waits for a response message in a reply queue.
3. Service B processes the request and sends a response to the indicated reply queue.
4. Service A consumes the message and resumes execution of that thread/continuation.

Synchronous communications require both services A and B to up and available. Uptime of a service is directly corelated to the uptime of its downstream synchronous communication dependencies.

### Asynchronous

Communication is **asynchronous** when either:

- Service A makes a request to Service B but does not wait around for a response. A response may come back at some indeterminate point in the future and even via a different communications channel.
- Service A makes a request to Service B and does not expect a response at all - fire-and-forget.

HTTP example:

1. Service A makes an HTTP POST call to Service B to process an order. Service B responds immediately with an HTTP 200, confirming it has received the request (but not processed it yet).
2. Service A continues to serve other requests.
2. Service B processes the order.
4. Service B makes call to Service A to confirm the order has been processed.
5. Service A executes some logic, such an notifying the customer that the order has been processed.

> Note that in this example, in a scaled out service, the instance of Service A that made the request may not be the one that processes the response.

Messaging example:

1. Service A sends a ProcessOrder message to the messaging system. Messaging system confirms receipt.
2. Service A continues to serve other requests.
3. Messaging system delivers the message to Service B.
4. Service B processes the order.
5. Service B sends an OrderProcessed to the messaging system. Messaging system confirms receipt.
6. Messaging system delivers the message to Service A.
7. Service A executes some logic, such an notifying the customer that the order has been processed.

> Note that for Service A to work, it does not need Service B to be up. Meanwhile Service B does not need Service A to be up in order to process the order and notify Service A that it has done so. Uptime now is now only coupled to the reliability of the messaging system itself.

## RPC vs Durable Messaging

### Remote Procedure Call (RPC)

RPC is like calling a function, only the call is made over the network. Examples of RPC are:

- HTTP
- TCP

RPC is a synchronous communications style and therefore requires both endpoints to be up. This style of programming is most comfortable for programmers as it mimicks the normal way that a programmer writes code. It also has excellent support in modern programming languages and frameworks with support for multiple data serialization formats:

- JSON
- XML
- Binary serialization like Protocol Buffers, Thrift

RPC requires Service A to know the address of Service B so it can make a call to it. This problem is either solved by a classic configuration system or by a service discovery mechanism such as Consul or service names in Kubernetes.

RPC calls can combine into a wide and/or deep call graph which can lead to some downsides.

![RPC call graph](/img/docs/concepts/call-graph.png)

The major downside of RPC is coupling which affects:

- uptime
- failure rate
- latency

**Service uptime** of Service A is tied to the uptime of all its dependencies. 

- Service A -> B, C, D, E all with 95% uptime = 77% uptime for Service A
- Service A -> B, C, D, E all with 99% uptime = 95% uptime for Service A

**Failure rates** of an operation in Service A that requires 5 synchronous calls is multiplied by the failure rates of each downstream operation.

**Latency spikes** are more likely as we increase the number of synchronous calls to downstream dependencies. If all services have the following latency profile: p50=5ms, p99.9=100ms, p99.999=5s

Dependencies | Latency | Every X Operations
--|--|--
1 | 5s | 10000
1 | 100ms | 1000
5 | 5s | 2000
5 | 100ms | 200
10 | 5s | 1000
10 | 100ms | 100
20 | 5s | 500
20 | 100ms | 50

Tail latencies that individually are rare events become more common place as our call graph grows.

Many of these drawbacks may be mitigated and bounded given enough infrastructure, expertise and operational excellence, but at some dollar cost.

### Durable Messaging

Moving to an asynchronous model can avoid many of the issues caused by too heavy a reliance on a synchronous communications architecture.

A messaging system naturally supports asynchronous communication but adds additional benefits:

- Unavailability of downstream services does not necessarily affect the availability of Service A.
- Latency spikes in downstream services does not affect the latency profile of Service A.
- Processing failures don't necessarily affect the operations of Service A.
- The messaging system can absorb traffic spikes that might have caused downstream systems to crash under the load. 

It also brings its own challenges and downsides.

The programming model may be less straight forward as the asynchronous style can require more indirection. Rather than waiting for the order to be processed by Service B, Service A may need to let the caller know the order has been received and notify later when the OrderProcessed event is received.

An operation that is now comprised of multiple independent asynchronous operations can be more hard to troubleshoot/detect when things go wrong and more difficult to resolve. But there are tools available such as:

- deadletter queues
- poisonous message queues
- message retries

### A mix of both

In all likelihood we shouldn't try to force the usage of only synchronous RPC or asynchronous message passing in our architecture but use a blend of both. 

![A mix of both](/img/docs/concepts/mixing-sync-and-async.png)

Authentication is an example of what naturally fits RPC. Sending an email notification is an example of what naturally fits an asynchronous operation. There may be a large gray area in the middle where both are candidates, each with their pros and cons.

## Point-to-point vs Publish-Subscribe

### Point-to-point

Point-to-point communications can be performed in either a synchronous or asynchronous style. What makes point-to-point is that as a single operation there is one service talking to just one other service. Service A knows it wants to talk to Service B and makes a request to it, either directly via a protocol such as HTTP or via messaging system that supports it.

The downsides of point-to-point are the extra coupling it brings, especially if we have multiple services which need to be communicated with to perform an action. For example, to create an order in Service A today we make the following point-to-point communications:

1. Notify Inventory service
2. Notify shipping service
3. Call notification service to send a confirmation email

Tomorrow we add communications to the Customer Care service, the Invoice service, the Marketing Campaign service and each time it means changing the code in Service A.

The usual reasons for point-to-point communications are:

- RPC
- Commands (a service tells another service to do something)

### Publish-Subscribe

Publish-Subscribe is an asynchronous style where the publisher of a message does not know (or generally care) who will consume the message. A single message could be delivered to a single service, 10, 1000 or no services at all. The point is that the publisher simply sends a message and forgets about it. Independently any number of services can subscribe to the messages they care about.

Service A publishes the OrderCreated event, and the following services subscribe to that event:

- Notifications service (so that it can send a confirmation email)
- Inventory service (so that it can update its stock)
- Shipping service (so that is can begin an internal workflow to prepare the order)

When Service A publishes an OrderCreated event, that event automaticvally gets forwarded to all three services. 

Tomorrow when we add three new subscribers, it does not require any code changes to Service A.

![Publish-Subscribe](/img/docs/concepts/pub-sub.png)

Publish-subscribe is most often used to broadcast events. An event is simply a fact about something that has happened in the system. Events can cause a chain reaction of activity where more events are emitted and reacted to.<file_sep>---
id: consumers
title: Consumers
---
Consumers subscribe to a queue using either auto-acknowledgement or manual acknowledgement mode and also optionally define a prefetch value.

## Acknowledgements and Prefetch

Once a channel has been established between a broker and a consumer, the consumer subscribes to a queue. The channel process on the broker will then start pushing messages from the queue down the channel to the consumer.

Because RabbitMQ uses a push model, it needs a back-pressure mechanism to control the flow of messages, to prevent overpowering the consumer. That mechanism is the combination of message acknowledgements and prefetch.

The prefetch is the number of unacknowledged messages the channel will allow at any one time. For example, with a prefetch of 5:

- broker pushes 1, 2, 3, 4, 5
- consumer acknowledges 1
- broker pushes 6
- consumer acknowledges 2, 3, 4
- broker pushes 7, 8, 9

At all times, there are no more than 5 unacknowledged messages on the channel. Higher prefetches yield higher throughputs but also have downsides, see the TODO page for a deeper dive.

A consumer can configure auto-acknowledgement mode which means a message will be automatically acknowledged upon sending the message. This is an unsafe setting that can result in message loss, but provides higher throughput. It is not generally recommended.

## Competing Consumers

We can scale out consumption of a queue if a single consumer cannot handle the load by itself. We simply add more consumers to the queue in question and they will all get a portion of messages delivered to them.

We call multiple consumers on a single queue **competing consumers** because each consumer competes to consume the same set of messages. With three consumers subscribed to a single queue, each should get delivered about 1/3 of the messages.

![Competing consumers](/img/docs/concepts/queues-competing-consumers.png)

## Non-competing Consumers

When you want three consumers to each process every single message of an exchange, then you need three queues. You tend to need this when you have multiple different services all needing to consume the same messages.

![Non-competing consumers](/img/docs/concepts/queues-non-competing-consumers.png)

## Scaling Consumers Independently

One of RabbitMQ's super powers is the way that it decouples both publishers from consumers, but also different consumers from each other.

In other messaging systems that are based on topics, you must scale out the topic itself according to the needs of the slowest consumer. With RabbitMQ each subscribing service gets its own queue and can add as many consumers as it desires, independently of other subscribed services.

![Independent consumer scaling](/img/docs/concepts/queues-any-num-of-consumers.png)<file_sep>// vim:sw=2:et:
/**
 * Copyright (c) 2020-present, Pivotal Software, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const React = require('react');
import { readFileSync } from 'fs';

const renderMarkdown = require('../node_modules/docusaurus/lib/core/renderMarkdown.js');

class Md extends React.Component {
  content() {
    if (this.props.file) {
      var data = readFileSync(this.props.file, 'utf8');
      return renderMarkdown(data);
    } else {
      return React.Children.map(this.props.children, child => {
        if (typeof child === 'string') {
          return renderMarkdown(child);
        }

        return child;
      });
    }
  }

  render() {
    const Container = this.props.container;
    if (this.props.id && this.props.className) {
      return <Container
               id={this.props.id}
               className={this.props.className}
               dangerouslySetInnerHTML={{__html: this.content()}} />;
    } else if (this.props.id) {
      return <Container
               id={this.props.id}
               dangerouslySetInnerHTML={{__html: this.content()}} />;
    } else if (this.props.className) {
      return <Container
               className={this.props.className}
               dangerouslySetInnerHTML={{__html: this.content()}} />;
    } else {
      return <Container
               dangerouslySetInnerHTML={{__html: this.content()}} />;
    }
  }
}

Md.defaultProps = {
  container: 'div',
};

module.exports = Md;
<file_sep>---
id: index
title: Operations Guides
---

- Reference
    - Installation
        - All Packages and Repositories
        - Debian and Ubuntu
        - RHEL, CentOS, Fedora
        - Windows
        - Generic UNIX Binary Build
        - MacOS via Standalone Binary Build
        - MacOS via Homebrew
        - Amazon EC2
        - Solaris
        - Configuration Management Tools
        - Docker
        - Kubernetes
        - Package Signatures
        - Supported Erlang/OTP Versions
        - Supported RabbitMQ Versions
        - Changelog
        - Snapshot (Nightly) Builds
    - Upgrades and OS Patching
        - Full Cluster Upgrade/Restart
        - Rolling Upgrades/Restarts
        - Rolling Back?
    - Configuration
        - Reference
        - File and Directory Locations
        - Environment Variables
        - Runtime Parameters
    - CLI Tools
        - Overview
        - rabbitmqctl
        - rabbitmqadmin
        - rabbitmqqueues
    - Multi DC and Multi-Cluster
        - Intro
        - Federation
        - Shovel
        - Securing Multi-Cluster Communications
    - Monitoring/Observability
        - Management UI and HTTP API
        - Logging
        - Metrics
        - Health Checks
        - Prometheus Support
        - InfluxDB Support
        - Grafana
        - Troubleshooting guidance
        - Client Connections
        - AMQP 0-9-1 Channels
        - Internal Event Exchange
        - Per Virtual Host Limits
        - Message Tracing
        - Capturing Traffic with Wireshark
    - Security
        - Authentication and Authorisation
            - Authentication and authorisation Backends
            - Authentication Mechanisms
            - Virtual Hosts
            - Credentials and Passwords
            - LDAP
            - x509 Certificate-based Authentication
            - Validated User ID
            - Authentication Failure Notifications
        - Networking and TLS
            - Client Connections
            - Networking
            - Troubleshooting Network Connectivity
            - Using TLS for Client Connections
            - Using TLS for Inter-node Traffic
            - Troubleshooting TLS
- Guides
    - Production and Day Two Guides
        - Production Checklist
        - Monitoring with Prometheus and Grafana
        - Monitoring with Elastic
        - Disaster Recovery Strategies
        - Troubleshooting Guide
    - Reliability Guide
        - Intro
        - Safety At-Rest
        - Avoiding Overload
        - Understanding Flow Control
        - Multi-DC Failovers??
    - Performance Guide
        - Intro
        - Queue Types and Performance
        - CPU
        - Memory 
        - Disk
        - Network
        - Docker
    - Upgrade Guide
        - Intro
        - High Availability Upgrade Strategies
            - Rolling Upgrades
            - Blue/Green Deployment Upgrades
            - Cluster Expansion Upgrades
        - Data Safe Upgrade Strategies
            - Full Cluster Upgrade
            - Blue/Green Deployment Upgrades
<file_sep>---
id: index
title: Welcome to the Developer Guide
sidebar_label: Introduction
---

See our [guides and tutorials](guides/index) that will help you learn how to combine various RabbitMQ features to achieve your messaging architecture objectives.

See our [developer reference](reference/index) documentation to learn the details about specific features.<file_sep>---
id: index
title: How to get RabbitMQ
---

## Trying RabbitMQ <span class="h-addition">(without installing)</span>

You can play with RabbitMQ to help you decide if it is the right tool
for you.

**The easiest to try RabbitMQ:**

```sh
curl -sSf https://rabbitmq.netlify.com/try-rabbitmq.sh | sh
```

For more detailed instructions to try RabbitMQ, here are two approaches.
The script above implements the first one.

<div class="doc-tiles"></div>

*   [![](/img/install/package.svg)](precompiled)
    ### [Precompiled binaries](precompiled)
    For both Unix systems and Microsoft Windows

*   [![](/img/logo/docker.svg)](docker)
    ### [Docker](docker)

Those methods are also useful when you want to run RabbitMQ as an
unprivileged user.

## Installing RabbitMQ

<div class="doc-tiles"></div>

*   [![](/img/logo/debian.svg)](debian)
    ### [Debian](debian)
    Debian, Ubuntu and derivatives

*   [![](/img/logo/redhat.svg)](redhat)
    ### [Red Hat](redhat)
    RHEL, CentOS, Fedora and derivatives

*   [![](/img/logo/opensuse.svg)](opensuse)
    ### [OpenSUSE](opensuse)
    OpenSUSE, SLES and derivatives

*   [![](/img/logo/windows.svg)](windows)
    ### [Microsoft Windows](windows)

*   [![](/img/logo/freebsd.png)](freebsd)
    ## [FreeBSD](freebsd)
    FreeBSD and derivatives

*   [![](/img/logo/apple.svg)](macos)
    ## [macOS](macos)

## Build from source

If you want to work on RabbitMQ or if you are a package maintainer, you
can [build from source](build), either using a release source archive or
from a Git clone.
<file_sep>---
id: flow-control
title: Understanding Flow Control
---

TODO<file_sep>---
id: peer-clusters
title: Peer Clusters
---

TODO<file_sep>---
id: use-mqtt
title: Use MQTT
---

So far, we only seen how to publish and consume messages using AMQP
0-9-1. However, RabbitMQ supports many more protocols! MQTT is one of
them, let's see how to use it with RabbitMQ.

> **TODO**: Write this page.
<file_sep>---
id: configure-rabbitmq
title: Configure RabbitMQ
---

If you reached this tutorial:
* you know how to develop a client to publish and consume messages
* you know how to observe your RabbitMQ node.

Now, RabbitMQ offers many settings you may want to tweak to adapt it to
your workload. Let's see how this is done with two simple settings.

> **TODO**: Write this page.
<file_sep>---
id: priority-routing
title: Priority Based Routing / Class of Service
sidebar_label: Priority Based Routing
---

TODO<file_sep>---
id: index
title: Introduction
---

Intro to these guides...
TODO<file_sep>---
id: index
title: Getting Started
---

In this Getting Started guide, we will go through several steps to give
you a general idea of all the features of RabbitMQ. You will learn:

* Start RabbitMQ.
* How to configure your node.
* How to publish and consume messages, using different protocols.
* How to cluster many nodes to get high availibility.
* How to observe your RabbitMQ node.

<div class="getting-started-certificate"></div>

![](/img/getting-started/certificate.svg)
<file_sep>---
id: index
title: Federation and Shovel
---

TODO<file_sep>---
id: index
title: Virtual Hosts
---

TODO<file_sep>---
id: messages
title: Messages
---

## Message Properties

### AMQP 0-9-1

Every delivery combines message metadata and delivery information. Different client libraries use slightly different ways of providing access to those properties. Typically delivery handlers have access to a delivery data structure.

The following properties are delivery and routing details; they are not message properties per se and set by RabbitMQ at routing and delivery time:

| Property | Type | Description |
| -- | -- | -- |
| Delivery tag | Positive integer | Delivery identifier, see Confirms.|
| Redelivered | Boolean | Set to `true` if this message was previously delivered and requeued |
| Exchange | String | Exchange which routed this message |
| Routing key | String | Routing key used by the publisher |
| Consumer tag | String | Consumer (subscription) identifier |

The following are message properties. Most of them are optional. They are set by publishers at the time of publishing:

| Property | Type | Description | Required? |
| -- | -- | -- | -- |
| Delivery mode | Enum (1 or 2) | 2 for "persistent", 1 for "transient". Some client libraries expose this property as a boolean or enum. | Yes |
| Type | String | Application-specific message type, e.g. "orders.created" | No |
| Headers | Map (string => any) | An arbitrary map of headers with string header names | No |
| Content type | String | Content type, e.g. "application/json". Used by applications, not core RabbitMQ | No |
| Content encoding | String | Content encoding, e.g. "gzip". Used by applications, not core RabbitMQ | No |
| Message ID | String | Arbitrary message ID | No |
| Correlation ID | String | Helps correlate requests with responses, see tutorial 6 | No |
| Reply To | String | Carries response queue name, see tutorial 6 | No |
| Expiration | String | Per-message TTL | No |
| Timestamp | Timestamp | Application-provided timestamp | No |
| User ID | String | User ID, validated if set | No |
| App ID | String | Application name | No |

## Message Types

The type property on messages is an arbitrary string that helps applications communicate what kind of message that is. It is set by the publishers at the time of publishing. The value can be any domain-specific string that publishers and consumers agree on.

RabbitMQ does not validate or use this field, it exists for applications and plugins to use and interpret.

Message types in practice naturally fall into groups, a dot-separated naming convention is common (but not required by RabbitMQ or clients), e.g. orders.created or logs.line or profiles.image.changed.

If a consumer gets a delivery of an unknown type it is highly advised to log such events to make troubleshooting easier.

## Content Type and Encoding

The content (MIME media) type and content encoding fields allow publishers communicate how message payload should be deserialized and decoded by consumers.

RabbitMQ does not validate or use these fields, it exists for applications and plugins to use and interpret.

For example, messages with JSON payload should use application/json. If the payload is compressed with the LZ77 (GZip) algorithm, its content encoding should be gzip.

Multiple encodings can be specified by separating them with commas.<file_sep>---
id: protocols
title: Protocols
---

RabbitMQ natively supports AMQP 0.9.1 but also can be configured to support extra protocols:

- MQTT
- STOMP
- AMQP 1.0

## MQTT

MQTT is a publish-subscribe messaging protocol used commonly in IOT.

- Clients can publish messages to topics on a broker.
- Clients can subscribe to individual topics or a hierarchy of topics.
- Supports three levels of delivery guarantee (QoS) scoped to publisher-broker and broker-consumer:
  - QoS 0: At-Most-Once delivery (messages can be lost)
  - QoS 1: At-Least-Once delivery (messages cannot be lost, but can be delivered more than once)
  - QoS 2: Exactly-Once (messages are delivered exactly once)

Exactly-Once only makes guarantees about delivery from publisher to broker, and broker to consumer. It does not prevent:

- a broker from losing the message. It is up to the broker to implement message replication or the server administrator to provide redundant storage.
- a consumer using a different QoS less strong than Exactly-Once. 

RabbitMQ supports all MQTT 3.1 features except for QoS 2 for consumers. It does however provide the ability to use replicated queues providing high availability and data safety.

- Link to plugin in docs TODO
- [GitHub](https://github.com/rabbitmq/rabbitmq-mqtt)

## STOMP

STOMP stands for Simple (or Streaming) Text Orientated Messaging Protocol. It is a text based publish-subscribe messaging protocol that is designed to be simple and lightweight.

Clients (both publishers and subscribers) open long lived connections to a broker. Messages are published to **destinations** and consumers subscribe to **destinations**. It does not include any message durability and persistence features in the protocol itself and the RabbitMQ implementation relies on the usual durability guarantees you get with any queue.

RabbitMQ offers many different ways to map STOMP destinations onto RabbitMQ exchanges and queues. Two plugins are provided.

### STOMP plugin

Read more about the STOMP plugin:

- Link to plugin in docs TODO
- [GitHub](https://github.com/rabbitmq/rabbitmq-stomp)

### Web STOMP plugin (STOMP over WebSocket)

Provides for support for STOMP over WebSocket to allow for browser to broker communications.

Read more about the Web STOMP plugin:

- Link to web plugin in docs TODO
- [GitHub](https://github.com/rabbitmq/rabbitmq-web-stomp)

## AMQP 1.0

AMQP 1.0 is a completely different protocol to AMQP 0.9.1 and should be considered separate protocols. AMQP 1.0 has wide support in various messaging systems, including RabbitMQ. However, RabbitMQ supports only a subset of the full protocol.

This [YouTube this video series from Microsoft](https://www.youtube.com/watch?v=ODpeIdUdClc) as a good AMQP 1.0 primer.

Learn more about RabbitMQ's support for AMQP 1.0:

- [GitHub](https://github.com/rabbitmq/rabbitmq-amqp1.0)
- Developer guide page TODO

Read on to learn about the differences between AMQP 0.9.1 and AMQP 1.0.

### Peer-to-peer (1.0) vs Broker Based (0.9.1)

AMQP 1.0 is a peer-to-peer protocol, it does not include the concept of a broker. Therefore it does not natively include routing, publish-subscribe or message durability. Despite not being a part of the protocol, typically AMQP 1.0 is used in a broker based system where one endpoint is a broker and the other an application. Through broker implementations you typically get publish-subscribe features.

AMQP 0.9.1 is an overtly broker-based protocol with native support for routing and publish-subscribe.

### Connection Concepts and Flow Control

AMQP 1.0 has a more complex set of concepts including connections, channels, sessions, nodes and links. It has two levels of flow control (session level and link level) to prevent system resources being used up and to throttle fast publishers.

AMQP 0.9.1 has a model of connections, channels, exchanges and queues. Flow control exists at three levels: the connection, channel and queue level. Addtionally, consumers can perform flow control by the use of prefetch and acknowledgements.

### On the wire format

AMQP 1.0 has a more complex on the wire binary format more similar to something like Avro, ProtoBuf or Thrift. AMQP 0.9.1 simply stores bytes as the publisher provides.<file_sep>---
id: reference
title: Policies Reference
---

TODO
