PageSourceSearch

https://www.rabbitmq.com/assets/js/ca32c539.a9cd164b.js

js rabbitmq.com collected 2026-09-24 06:05:03 UTC 41,495 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkrabbitmq_website=self.webpackChunkrabbitmq_website||[]).push([["12537"],{8256(e,n,t){t.r(n),t.d(n,{metadata:()=>i,default:()=>m,frontMatter:()=>o,contentTitle:()=>c,toc:()=>h,assets:()=>d});var i=JSON.parse('{"id":"federation","title":"Federation Plugin","description":"\x3c!--","source":"@site/versioned_docs/version-4.3/federation.md","sourceDirName":".","slug":"/federation","permalink":"/docs/federation","draft":false,"unlisted":false,"editUrl":"https://github.com/rabbitmq/rabbitmq-website/tree/main/versioned_docs/version-4.3/federation.md","tags":[],"version":"4.3","frontMatter":{"title":"Federation Plugin"},"sidebar":"docsSidebar","previous":{"title":"Management Plugin","permalink":"/docs/management/"},"next":{"title":"Federated Queues","permalink":"/docs/federated-queues/"}}'),a=t(74848),r=t(28453),s=t(50773),l=t(57250);let o={title:"Federation Plugin"},c="Exchange and Queue Federation",d={},h=[{value:"Overview",id:"overview",level:2},{value:"Loose Coupling of Nodes or Clusters",id:"loose-coupling-of-nodes-or-clusters",level:3},{value:"WAN friendliness",id:"wan-friendliness",level:3},{value:"Specificity",id:"specificity",level:3},{value:"Scalability with Growing Connected Node Count",id:"scalability-with-growing-connected-node-count",level:3},{value:"What Does It Do?",id:"what-does-it-do",level:2},{value:"How is Federation Set Up?",id:"how-is-it-configured",level:2},{value:"Getting Started",id:"getting-started",level:2},{value:"A Basic Example",id:"tutorial",level:2},{value:"Federation Connection (Link) Failures",id:"link-failures",level:2},{value:"Federating Clusters",id:"clustering",level:2},{value:"Securing Federation Connections with TLS",id:"tls-connections",level:2},{value:"Federation Link Monitoring",id:"status",level:2},{value:"Using CLI Tools",id:"using-cli-tools",level:3},{value:"Using the Management UI",id:"using-the-management-ui",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Federation Links Do Not Start",id:"federation-links-do-not-start",level:3},{value:"Inspect Federation Upstreams",id:"inspect-federation-upstreams",level:4},{value:"Inspect Policies",id:"inspect-policies",level:4}];function u(e){let n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"exch
1ange-and-queue-federation",children:"Exchange and Queue Federation"})}),"\n",(0,a.jsx)(n.p,{children:"This guide covers various topics related to cluster federation, both\nof exchanges and queues:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"#overview",children:"Federation overview"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"#what-does-it-do",children:"What does federation do?"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"#getting-started",children:"Getting started"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"#tutorial",children:"A basic example"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"#link-failures",children:"Federation connections"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"#clustering",children:"Federating clusters"})}),"\n",(0,a.jsxs)(n.li,{children:["Federation ",(0,a.jsx)(n.a,{href:"#tls-connections",children:"support for TLS"})]}),"\n",(0,a.jsxs)(n.li,{children:["Monitoring federation ",(0,a.jsx)(n.a,{href:"#status",children:"link status"})]}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"#troubleshooting",children:"Troubleshooting"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,a.jsx)(n.p,{children:"The high-level goal of the Federation plugin is to replicate or move messages between brokers that have\nthe plugin enabled but do not belong to the same cluster. This is useful for a number of reasons."}),"\n",(0,a.jsx)(n.h3,{id:"loose-coupling-of-nodes-or-clusters",children:"Loose Coupling of Nodes or Clusters"}),"\n",(0,a.jsx)(n.p,{children:"The federation plugin can transmit messages between brokers\n(or clusters) in different administrative domains:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"they may be hosted in different data centers, potentially on different continents"}),"\n",(0,a.jsx)(n.li,{children:"they may have different users, virtual hosts, permissions and purpose"}),"\n",(0,a.jsx)(n.li,{children:"they may run on different versions of RabbitMQ and Erlang"}),"\n",(0,a.jsx)(n.li,{children:"they may be of different sizes"}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"wan-friendliness",children:"WAN friendliness"}),"\n",(0,a.jsx)(n.p,{children:"The federation plugin communication is entirely asynchronous and assumes that connections between\nclusters will fail from time to time. So it tolerates intermittent connectivity\nwell and does not create coupling between remote clusters (in terms of availability)."}),"\n",(0,a.jsx)(n.h3,{id:"specificity",children:"Specificity"}),"\n",(0,a.jsxs)(n.p,{children:["A broker can contain federated ",(0,a.jsx)(n.em,{children:"and"})," local-only components to best\nfit the desired architecture of the system."]}),"\n",(0,a.jsx)(n.h3,{id:"scalability-with-growing-connected-node-count",children:"Scalability with Growing Connected Node Count"}),"\n",(0,a.jsxs)(n.p,{children:["Federation does not require O(n",(0,a.jsx)("sup",{children:"2"}),") connections between\n",(0,a.jsx)(n.em,{children:"N"})," brokers (although this is the easiest way to set things up)."]}),"\n",(0,a.jsx)(n.h2,{id:"what-does-it-do",children:"What Does It Do?"}),"\n",(0,a.jsxs)(n.p,{children:["The federation plugin make it possible to ",(0,a.jsx)(n.em,{children:"federate"})," exchanges and queues.\nA federated exchange or queue can receive\nmessages from one or more remote clusters called ",(0,a.jsx)(n.em,{children:"upstreams"})," (to be more precise: exchanges\nand queues that exist in remote clusters)."]}),"\n",(0,a.jsx)(n.p,{children:'A federated exchange will "replay" a stream of messages published to its upstream counterpart, and publish them to a local queue or stream.'}),"\n",(0,a.jsx)(n.p,{children:"A federated queue lets a local consumer receive messages from an upstream queue when the remote queue\nitself does not have any local consumers online."}),"\n",(0,a.jsxs)(n.p,{children:["Federation links connect to upstreams largely the same way an application would. Therefore\nthey can connect to a specific vhost, use TLS, use multiple\n",(0,a.jsx)(n.a,{href:"./authentication",children:"authentication mechanisms"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Typically, federation is used to connect remote cluster
1s. However, it can also be used\nto move data between ",(0,a.jsx)(n.a,{href:"./vhosts",children:"virtual hosts"})," within the same cluster."]}),"\n",(0,a.jsx)(n.p,{children:"Federation documentation is organized as a number of more focussed guides:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"./federated-exchanges",children:"Exchange federation"}),": for replicating a flow of messages through an exchange to a remote cluster"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"./federated-queues",children:"Queue federation"}),': to create a "logical queue" across N clusters that will move messages where consumers are (if there are no local consumers)']}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"./federation-reference",children:"Federation settings reference"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"how-is-it-configured",children:"How is Federation Set Up?"}),"\n",(0,a.jsx)(n.p,{children:"Two steps are involved in setting up federation:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["First, one or more upstreams must be defined. They provide federation with information about how to connect\nto other nodes. This can be done via ",(0,a.jsx)(n.a,{href:"./parameters",children:"runtime parameters"}),"\nor the ",(0,a.jsx)(n.a,{href:"https://github.com/rabbitmq/rabbitmq-federation-management",children:"federation management plugin"})," which\nadds a federation management tab to the ",(0,a.jsx)(n.a,{href:"./management",children:"management UI"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:["To enable federation, one or more ",(0,a.jsx)(n.a,{href:"./policies",children:"policies"})," that match exchanges or queues must be declared.\nThe policy will make the matched objects (e.g. exchanges) federated, and one federation link\n(connection to other nodes) will be started for every match"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"getting-started",children:"Getting Started"}),"\n",(0,a.jsxs)(n.p,{children:["The federation plugin is included in the RabbitMQ distribution. To\nenable it, use ",(0,a.jsx)(n.a,{href:"./cli",children:"rabbitmq-plugins"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"rabbitmq-plugins enable rabbitmq_federation\n"})}),"\n",(0,a.jsxs)(n.p,{children:["If ",(0,a.jsx)(n.a,{href:"./management",children:"management UI"})," is used, it is recommended that\n",(0,a.jsx)(n.code,{children:"rabbitmq_federation_management"})," is also enabled:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"rabbitmq-plugins enable rabbitmq_federation_management\n"})}),"\n",(0,a.jsx)(n.p,{children:"When using a federation in a cluster, all the nodes of the\ncluster should have the federation plugin enabled."}),"\n",(0,a.jsx)(n.p,{children:"Information about federation upstreams is stored in the RabbitMQ\ndatabase, along with users, permissions, queues, etc. There\nare three levels of configuration involved in federation:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Upstreams"}),": each ",(0,a.jsx)(n.a,{href:"./federation-reference#upstreams",children:"upstream"})," defines a remote connection endpoint."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Upstream sets"}),": each ",(0,a.jsx)(n.a,{href:"./federation-reference#upstream-sets",children:"upstream set groups"})," together a set of upstreams to use for federation."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Policies"}),": each ",(0,a.jsx)(n.a,{href:"./policies",children:"policy"})," selects a set of exchanges,\nqueues or both, and applies a single upstream or an upstream\nset to those objects."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["In practice, for simple use cases you can almost ignore the\nexistence of upstream sets, since there is an implicitly-defined upstream set called ",(0,a.jsx)(n.code,{children:"all"}),"\nto which all upstreams are added."]}),"\n",(0,a.jsxs)(n.p,{children:["Upstreams and upstream sets are both defined using ",(0,a.jsx)(n.a,{href:"./parameters",children:"runtime parameters"}),".\nLike exchanges and queues, each virtual host has its own distinct set of parameters and policies. For more\ngeneric information on parameters and policies, see the guide on\n",(0,a.jsx)(n.a,{href:"./parameters",children:"parameters and policies"}),".\nFor full details on the parameters used by federation, see the ",(0,a.jsx)(n.a,{href:"./federation-reference",children:"federation reference"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Parameters and policies can be set in three ways:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Using ",(0,a.jsx)(n.a,{href:"./cli",children:"CLI tools"})]}),"\n",(0,a.jsxs)(n.li,{children:["In the management UI if an extension plugin (",(0,a.jsx)(n.code,{children:"rabbitmq_federation_management"}),") is enabled"]}),"\n",(0,a.jsx)(n.li,{children:"Using the HTTP API"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The HTTP API has a limitation: it does not support management of upstream sets."}),"\n",(0,a.jsx)(n.h2,{id:"tutorial",children:"A Basic Example"}),"\n",(0,a.jsx)(n.p,{children:"Here we will federate all the built-in exchanges except for\nthe default exchange, with a single upstream. The upstream\nwill be defined to buffer messages when disconnected for up\nto one hour (3600000ms)."}),"\n",(0,a.jsx)(n.p,{children:"To define an upstream, use one of the following examples,\none per tab:"}),"\n",(0,a.jsxs)(s.A,{groupId:"examples",children:[(0,a.jsx)(l.A,{value:"bash",label:"rabbitmqctl with bash",default:!0,children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'# target.hostname is just an example, replace it with a URI\n# of the target node (usually a member of a remote node/cluster,\n# or a URI that connects to a different virtual host within the same cluster)\nrabbitmqctl set_parameter federation-upstream my-upstream \\\n    \'{"uri":"amqp://target.hostname","expires":3600000}\'\n'})})}),(0,a.jsx)(l.A,{value:"rabbitmqadmin",label:"rabbitmqadmin with bash",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'# target.hostname is just an example, replace it with a URI\n# of the target node (usually a member of a remote node/cluster,\n# or a URI that connects to a different virtual host within the same cluster)\nrabbitmqadmin federation declare_upstream --name my-upstream \\\n    --uri "amqp://target.hostname" \\\n    --ttl 3600000\n'})})}),(0,a.jsx)(l.A,{value:"PowerShell",label:"rabbitmqctl with PowerShell",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-PowerShell",children:'# target.hostname is just an example, replace it with a URI\n# of the target node (usually a member of a remote node/cluster,\n# or a URI that connects to a different virtual host within the same cluster)\nrabbitmqctl.bat set_parameter federation-upstream my-upstream `\n    \'"{""uri"":""amqp://target.hostname"",""expires"":3600000}"\'\n'})})}),(0,a.jsx)(l.A,{value:"rabbitmqadmin-PowerShell",label:"rabbitmqadmin.exe with PowerShell",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-PowerShell",children:'# target.hostname is just an example, replace it with a URI\n# of the target node (usually a member of a remote node/cluster,\n# or a URI that connects to a different virtual host within the same cluster)\nrabbitmqadmin.exe federation declare_upstream --name my-upstream ^\n    --uri "amqp://target.hostname" ^\n    --ttl 3600000\n'})})}),(0,a.jsx)(l.A,{value:"Management UI",label:"Management UI",children:(0,a.jsxs)(n.p,{children:["Navigate to ",(0,a.jsx)(n.code,{children:"Admin"})," > ",(0,a.jsx)(n.code,{children:"Federation Upstreams"})," >\n",(0,a.jsx)(n.code,{children:"Add a new upstream"}),'. Enter "my-upstream" next to Name,\n"amqp://target.hostname" next to URI, and 36000000 next to\nExpiry. Click Add upstream.']})}),(0,a.jsx)(l.A,{value:"HTTP API",label:"HTTP API",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'PUT /api/parameters/federation-upstream/%2f/my-upstream\n{"value":{"uri":"amqp://target.hostname","expires":3600000}}\n'})})})]}
1),"\n",(0,a.jsx)(n.p,{children:"Then define a policy that will match built-in exchanges and use this upstream:"}),"\n",(0,a.jsxs)(s.A,{groupId:"examples",children:[(0,a.jsx)(l.A,{value:"bash",label:"rabbitmqctl with bash",default:!0,children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'rabbitmqctl set_policy --apply-to exchanges federate-me "^amq\\." \\\n    \'{"federation-upstream-set":"all"}\'\n'})})}),(0,a.jsx)(l.A,{value:"rabbitmqadmin",label:"rabbitmqadmin with bash",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'rabbitmqadmin policies declare \\\n    --name "federate-me" \\\n    --pattern "^amq\\." \\\n    --definition \'{"federation-upstream-set":"all"}\' \\\n    --apply-to "exchanges"\n'})})}),(0,a.jsx)(l.A,{value:"PowerShell",label:"rabbitmqctl with PowerShell",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-PowerShell",children:'rabbitmqctl.bat set_policy --apply-to exchanges federate-me "^amq\\." `\n    \'"{""federation-upstream-set"":""all""}"\'\n'})})}),(0,a.jsx)(l.A,{value:"rabbitmqadmin-PowerShell",label:"rabbitmqadmin.exe with PowerShell",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-PowerShell",children:'rabbitmqadmin.exe policies declare ^\n    --name "federate-me" ^\n    --pattern "^amq\\." ^\n    --definition "{""federation-upstream-set"":""all""}" ^\n    --apply-to "exchanges"\n'})})}),(0,a.jsx)(l.A,{value:"Management UI",label:"Management UI",children:(0,a.jsxs)(n.p,{children:["Navigate to ",(0,a.jsx)(n.code,{children:"Admin"})," > ",(0,a.jsx)(n.code,{children:"Policies"})," > ",(0,a.jsx)(n.code,{children:"Add / update a policy"}),'.\nEnter "federate-me" next to "Name", "^amq." next to\n"Pattern", choose "Exchanges" from the "Apply to" drop down list\nand enter "federation-upstream-set" = "all"\nin the first line next to "Policy". Click "Add" policy.']})}),(0,a.jsx)(l.A,{value:"HTTP API",label:"HTTP API",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ini",children:'PUT /api/policies/%2f/federate-me\n{"pattern":"^amq\\.", "definition":{"federation-upstream-set":"all"}, "apply-to":"exchanges"}\n'})})})]}),"\n",(0,a.jsx)(n.p,{children:'The defined policy will make the exchanges _whose names\nbegin with "amq." (all the built-in exchanges except\nfor the default one) with (implicit) low priority, and\nto federate them using the implicitly created upstream set\n"all", which includes our newly-created upstream.'}),"\n",(0,a.jsxs)(n.p,{children:["Any other ",(0,a.jsx)(n.a,{href:"./policies",children:"matching policy"})," with a priority greater than 0 will take\nprecedence over this policy. Keep in mind that ",(0,a.jsx)(n.code,{children:"federate-me"}),"\nis just a name we used for this example, you can use any\nstring you want there."]}),"\n",(0,a.jsx)(n.p,{children:"The built in exchanges should now be federated because they are\nmatched by the policy. You can\ncheck that the policy has applied to the exchanges by\nchecking the exchanges list in management or with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"rabbitmqctl list_exchanges name policy | grep federate-me\n"})}),"\n",(0,a.jsxs)(n.p,{children:["And you can check that federation links for each exchange have come up with ",(0,a.jsx)(n.code,{children:"Admin"})," > ",(0,a.jsx)(n.code,{children:"Federation Status"})," > ",(0,a.jsx)(n.code,{children:"Running Links"})," or with:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# This command will be available only if federation plugin is enabled\nrabbitmqctl federation_status\n"})}),"\n",(0,a.jsx)(n.p,{children:"In general there will be one federation link for each\nupstream that is applied to an exchange. So for example with\nthree exchanges and two upstreams for each there will be six\nlinks."}),"\n",(0,a.jsxs)(n.p,{children:["For simple use this should be all you need - you will probably\nwant to look at the ",(0,a.jsx)("a",{href:"./uri-spec",children:"AMQP URI\nreference"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)("a",{href:"./federation-reference",children:"federation reference"})," contains\nmore details on upstream parameters and upstream sets."]}),"\n",(0,a.jsx)(n.h2,{id:"link-failures",children:"Federation Connection (Link) Failures"}),"\n",(0,a.jsx)(n.p,{children:"Inter-node connections used by Federation are based on AMQP 0-9-1\nconnections. Federation links can be treated as special kind of clients\nby operators."}),"\n",(0,a.jsxs)(n.p,{children:["Should a link fail, e.g. due to a network interruption, it will\nattempt to re-connect. Reconnection period is a configurable value\nthat's defined in upstream definition. See\n",(0,a.jsx)("a",{href:"./federation-reference",children:"federation\nreference"}
1)," for more details on setting up upstreams and\nupstream sets."]}),"\n",(0,a.jsx)(n.p,{children:"Links generally try to recover ad infinitum but there are scenarios\nwhen they give up:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Failure rate is too high (max tolerated rate depends on\nupstream's ",(0,a.jsx)(n.code,{children:"reconnect-delay"})," but is generally a failure\nevery few seconds by default)."]}),"\n",(0,a.jsx)(n.li,{children:'Link no longer can locate its "source" queue or exchange.'}),"\n",(0,a.jsx)(n.li,{children:"Policy changes in such a way that a link considers itself no longer necessary."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["By increasing ",(0,a.jsx)(n.code,{children:"reconnect-delay"})," for upstreams it is possible\nto tolerate higher link failure rates. This is primarily relevant\nfor RabbitMQ installations where a moderate or large number of active links."]}),"\n",(0,a.jsx)(n.h2,{id:"clustering",children:"Federating Clusters"}),"\n",(0,a.jsx)(n.p,{children:"Clusters can be linked together with federation just as single brokers\ncan. To summarise how clustering and federation interact:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"You can define policies and parameters on any node in the downstream\ncluster; once defined on one node they will apply on all nodes."}),"\n",(0,a.jsx)(n.li,{children:"Exchange federation links will start on any node in the\ndownstream cluster. They will fail over to other nodes if\nthe node they are running on crashes or stops."}),"\n",(0,a.jsxs)(n.li,{children:["Queue federation links will start on the same node as the\ndownstream queue. If the downstream queue is a ",(0,a.jsx)(n.a,{href:"./quorum-queues",children:"replicated one"}),", they\nwill start on the same node as the leader, and will be\nrecreated on the same node as the new leader after any future leader elections."]}),"\n",(0,a.jsx)(n.li,{children:"To connect to an upstream cluster, you can specify multiple URIs in\na single upstream. The federation link process will choose one of\nthese URIs at random each time it attempts to connect."}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"tls-connections",children:"Securing Federation Connections with TLS"}),"\n",(0,a.jsxs)(n.admonition,{type:"important",children:[(0,a.jsxs)(n.p,{children:["Starting with Erlang 26, ",(0,a.jsx)(n.a,{href:"./ssl#peer-verification",children:"TLS client peer verification"})," is enabled by default by the TLS implementation."]}),(0,a.jsx)(n.p,{children:"If client TLS certificate and key pair is not configured, TLS-enabled Federation links\nwill fail to connect. A certificate (public key) and private key\npair must be configured for TLS-enabled Federation links that need to use peer verification."}),(0,a.jsx)(n.p,{children:"If peer verification is not necessary, it can be disabled."})]}),"\n",(0,a.jsxs)(n.p,{children:["Federation connections (links) can be secured with TLS. Because Federation uses\na RabbitMQ client under the hood, it is necessary to both configure\nthe target broker to ",(0,a.jsx)(n.a,{href:"./ssl",children:"listen for TLS connections"}),"\nand Federation to use TLS."]}),"\n",(0,a.jsx)(n.p,{children:"To configure Federation to use TLS, one needs to"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["In upstream URI, use the ",(0,a.jsx)(n.code,{children:"amqps"})," for scheme instead of ",(0,a.jsx)(n.code,{children:"amqp"})," and port ",(0,a.jsx)(n.code,{children:"5671"})," instead of ",(0,a.jsx)(n.code,{children:"5672"})," (assuming the default port is used but the port specified explicitly)"]}),"\n",(0,a.jsxs)(n.li,{children:["In the same upstream URI, specify CA certificate and client certificate/key pair, as well as other parameters (namely ",(0,a.jsx)(n.a,{href:"./ssl#peer-verification",children:"enable or disable peer verification"}),", ",(0,a.jsx)(n.a,{href:"./ssl#peer-verification-depth",children:"peer verification depth"}),") via ",(0,a.jsx)(n.a,{href:"./uri-query-parameters",children:"URI query parameters"})]}),"\n",(0,a.jsxs)(n.li,{children:["Optionally, configure ",(0,a.jsx)(n.a,{href:"./ssl/",children:"TLS-related"})," settings or defaults common for all links (plus, optionally, ",(0,a.jsx)(n.a,{href:"./shovel",children:"Shovel"}),") via the Erlang client settings"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"In the following example the upstream URI is modified to use TLS with a client certificate (public key)\nand private key pair but with peer verification disabled (for simplicity, it is encouraged for production use):"}),"\n",(0,a.jsxs)(s.A,{groupId:"examples",children:[(0,a.jsx)(l.A,{value:"bash",label:"rabbitmqctl with bash",default:!0,children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'# Note the TLS-related settings in the upstream URI field\nrabbitmqctl set_parameter federation-upstream my-upstream \\\n    \'{"uri":"amqps://target.hostname:5671?cacertfile=/path/to/ca_bundle.pem&certfile=/path/to/client_certificate.pem&keyfile=/path/to/client_key.pem&verify=verify_none","expires":3600000}\'\n'})})}),(0,a.jsx)(l.A,{value:"rabbitmqadmin",label:"rabbitmqadmin with bash",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'# Note the TLS-related settings in the upstream URI field\nrabbitmqadmin federation declare_upstream --name my-upstream \\\n    --uri "amqps://target.hostname:5671?cacertfile=/path/to/ca_bundle.pem&certfile=/path/to/client_certificate.pem&keyfile=/path/to/client_key.pem&verify=verify_none" \\\n    --ttl 3600000\n'})})}),(0,a.jsx)(l.A,{value:"PowerShell",label:"rabbitmqctl with PowerShell",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-PowerShell",children:'#\nrabbitmqctl.bat set_parameter federation-upstream my-upstream `\n    \'"{""uri"":""amqps://target.hostname:5671?cacertfile=drive:\\path\\to\\ca_bundle.pem&certfile=drive:\\path\\to\\client_certificate.pem&keyfile=drive:\\path\\to\\client_key.pem&verify=verify_none"",""expires"":3600000}"\'\n'})})}),(0,a.jsx)(l.A,{value:"rabbitmqadmin-PowerShell",label:"rabbitmqadmin.exe with PowerShell",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-PowerShell",children:'# Note the TLS-related settings in the upstream URI field\nrabbitmqadmin.exe federation declare_upstream --name my-upstream ^\n    --uri "amqps://target.hostname:5671?cacertfile=drive:\\path\\to\\ca_bundle.pem&certfile=drive:\\path\\to\\client_certificate.pem&keyfile=drive:\\path\\to\\client_key.pem&verify=verify_none" ^\n    --ttl 3600000\n'})})}),(0,a.jsxs)(l.A,{value:"Management UI",label:"Management UI",children:[(0,a.jsxs)(n.p,{children:["Navigate to ",(0,a.jsx)(n.code,{children:"Admin"})," > ",(0,a.jsx)(n.code,{children:"Federation Upstreams"})," >\n",(0,a.jsx)(n.code,{children:"Add a new upstream"}),'. Enter "my-upstream" next to Name, paste\n',(0,a.jsx)(n.code,{children:'"amqps://target.hostname:5671?cacertfile=/path/to/ca_bundle.pem&certfile=/path/to/client_certificate.pem&keyfile=/path/to/client_key.pem&verify=verify_none"'})," for URI,\nthen enter 36000000 next to Expiry."]}),(0,a.jsx)(n.p,{children:"Click Add upstream."})]}),(0,a.jsx)(l.A,{value:"HTTP API",label:"HTTP API",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'PUT /api/parameters/federation-upstream/%2f/my-upstream\n{"value":{"uri":"amqps://target.hostname:5671?cacertfile=/path/to/ca_bundle.pem&certfile=/path/to/client_certificate.pem&keyfile=/path/to/client_key.pem&verify=verify_none","expires":3600000}}\n'})})})]}),"\n",(0,a.jsxs)(n.p,{children:["These examples use a URI with four additional ",(0,a.jsx)(n.a,{href:"./uri-query-parameters",children:"URI query parameters"}),":"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"cacertfile"}),": the CA certificate bundle file that includes one or more CA certificates that were used to sign the client certificate and private key pair"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"certfile"}),": the client certificate (public key)"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"keyfile"}),": the client private key"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"verify"}),": ",(0,a.jsx)(n.a,{href:"./ssl#peer-verification",children:"controls peer verification"})," (in this specific example, disables it)"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:'Just like with "regular" client connections, if TLS-enabled federation links need to perform peer verification then server\'s CA must be\ntrusted on the node where federation link(s) runs, and vice versa.'}),"\n",(0,a.jsx)(n.h2,{id:"status",children:"Federation Link Monitoring"}),"\n",(0,a.jsxs)(n.p,{children:["Each combination of federated exchange or queue and upstream needs a\nlink to run. This is the process that retrieves messages from upstream\n
1and republishes them downstream. You can monitor the status of\nfederation links using ",(0,a.jsx)(n.code,{children:"rabbitmqctl"})," and the management\nplugin."]}),"\n",(0,a.jsx)(n.h3,{id:"using-cli-tools",children:"Using CLI Tools"}),"\n",(0,a.jsxs)(n.p,{children:["Federation link status can be inspected using ",(0,a.jsx)(n.a,{href:"./cli",children:"RabbitMQ CLI tools"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Invoke:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# This command will be available only if federation plugin is enabled\nrabbitmqctl federation_status\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will output a list of federation links running on the target node (not cluster-wide).\nIt contains the following keys:"}),"\n",(0,a.jsxs)("table",{children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:"Parameter Name"}),(0,a.jsx)("td",{children:"Description"})]})}),(0,a.jsxs)("tbody",{children:[(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:(0,a.jsx)(n.code,{children:"type"})}),(0,a.jsx)("td",{children:(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"exchange"})," or ",(0,a.jsx)(n.code,{children:"queue"})," depending on\nwhat type of federated resource this link relates to"]})})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:(0,a.jsx)(n.code,{children:"name"})}),(0,a.jsx)("td",{children:(0,a.jsx)(n.p,{children:"the name of the federated exchange or queue"})})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:(0,a.jsx)(n.code,{children:"vhost"})}),(0,a.jsx)("td",{children:(0,a.jsx)(n.p,{children:"the virtual host containing the federated exchange or queue"})})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:(0,a.jsx)(n.code,{children:"upstream_name"})}),(0,a.jsx)("td",{children:(0,a.jsx)(n.p,{children:"the name of the upstream this link is connected to"})})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:(0,a.jsx)(n.code,{children:"status"})}),(0,a.jsxs)("td",{children:[(0,a.jsx)(n.p,{children:"status of the link:"}),(0,a.jsxs)("ul",{children:[(0,a.jsx)("li",{children:(0,a.jsx)(n.code,{children:"starting"})}),(0,a.jsx)("li",{children:(0,a.jsx)(n.code,{children:"{running, LocalConnectionName}"})}),(0,a.jsx)("li",{children:(0,a.jsx)(n.code,{children:"{shutdown, Error}"})})]})]})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:(0,a.jsx)(n.code,{children:"connection"})}),(0,a.jsx)("td",{children:(0,a.jsx)(n.p,{children:"the name of the connection for this link (from config)"})})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:(0,a.jsx)(n.code,{children:"timestamp"})}),(0,a.jsx)("td",{children:(0,a.jsx)(n.p,{children:"time stamp of the last status update"})})]})]})]}),"\n",(0,a.jsx)(n.p,{children:"Here's an example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'# This command will be available only if federation plugin is enabled\nrabbitmqctl federation_status\n# => [[{type,<<"exchange">>},\n# =>   {name,<<"my-exchange">>},\n# =>   {vhost,<<"/">>},\n# =>   {connection,<<"upstream-server">>},\n# =>   {upstream_name,<<"my-upstream-x">>},\n# =>   {status,{running,<<"<[email protected]>">>}},\n# =>   {timestamp,{{2020,3,1},{12,3,28}}}]]\n# => ...done.\n'})}),"\n",(0,a.jsx)(n.h3,{id:"using-the-management-ui",children:"Using the Management UI"}),"\n",(0,a.jsxs)(n.p,{children:["Enable the ",(0,a.jsx)(n.code,{children:"rabbitmq_federation_management"})," ",(0,a.jsx)(n.a,{href:"./plugins",children:"plugin"})," that extends\n",(0,a.jsx)(n.a,{href:"./management",children:"management UI"})," with a new page that displays federation links in the cluster.\nIt can be found under ",(0,a.jsx)(n.code,{children:"Admin"})," > ",(0,a.jsx)(n.code,{children:"Federation Status"}),", or by using the\n",(0,a.jsx)(n.code,{children:"GET /api/federation-links"})," HTTP API endpoint."]}),"\n",(0,a.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,a.jsx)(n.h3,{id:"federation-links-do-not-start",children:"Federation Links Do Not Start"}),"\n",(0,a.jsx)(n.p,{children:"Federation links are started when"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"There is a configured upstream (or a set of upstream
1s)"}),"\n",(0,a.jsx)(n.li,{children:"There is a policy that matches some exchanges or queues"}),"\n",(0,a.jsx)(n.li,{children:"Federation can connect to the target upstream"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Therefore, in order to narrow down the problem, the recommended steps are:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Inspect federation upstreams"}),"\n",(0,a.jsxs)(n.li,{children:["Inspect ",(0,a.jsx)(n.a,{href:"./policies",children:"policies"}),", in particular looking for policies with conflicting ",(0,a.jsx)(n.a,{href:"./policies#priorities",children:"priorities"})]}),"\n",(0,a.jsxs)(n.li,{children:["Inspect ",(0,a.jsx)(n.a,{href:"./logging",children:"node logs"})]}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"inspect-federation-upstreams",children:"Inspect Federation Upstreams"}),"\n",(0,a.jsxs)(s.A,{groupId:"examples",children:[(0,a.jsx)(l.A,{value:"bash",label:"rabbitmq-diagnostics with bash",default:!0,children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"rabbitmq-diagnostics list_parameters --formatter=pretty_table\n"})})}),(0,a.jsx)(l.A,{value:"rabbitmqadmin",label:"rabbitmqadmin with bash",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"rabbitmqadmin federation list_all_upstreams\n"})})}),(0,a.jsx)(l.A,{value:"PowerShell",label:"rabbitmq-diagnostics with PowerShell",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-PowerShell",children:"rabbitmq-diagnostics.bat list_parameters --formatter=pretty_table\n"})})}),(0,a.jsx)(l.A,{value:"rabbitmqadmin-PowerShell",label:"rabbitmqadmin.exe with PowerShell",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-PowerShell",children:"rabbitmqadmin.exe federation list_all_upstreams\n"})})}),(0,a.jsxs)(l.A,{value:"Management UI",label:"Management UI",children:[(0,a.jsxs)(n.p,{children:["Make sure that the ",(0,a.jsx)(n.code,{children:"rabbitmq_federation_management"})," ",(0,a.jsx)(n.a,{href:"./plugins",children:"plugin"})," is enabled."]}),(0,a.jsxs)(n.p,{children:["Navigate to ",(0,a.jsx)(n.code,{children:"Admin"})," > ",(0,a.jsx)(n.code,{children:"Federation Upstreams"}),"."]})]}),(0,a.jsx)(l.A,{value:"HTTP API",label:"HTTP API",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ini",children:"GET /api/parameters\n"})})})]}),"\n",(0,a.jsx)(n.h4,{id:"inspect-policies",children:"Inspect Policies"}),"\n",(0,a.jsx)(n.p,{children:"Only one policy in RabbitMQ can be applied at a time, and that out of N policies\nwith equal priorities a random one will be selected."}),"\n",(0,a.jsx)(n.p,{children:"In other words, when there are conflicting policies that match the exchanges or queues\nthat are meant to be federated, the policy that enables federation is not guaranteed\nto be the effective one."}),"\n",(0,a.jsxs)(n.p,{children:["Using explicit different policies and avoiding policies that ",(0,a.jsx)(n.code,{children:"--apply-to all"})," will reduce\nthe risk of running into this problem."]})]})}function m(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},57250(e,n,t){t.d(n,{A:()=>l});var i=t(74848);t(96540);var a=t(34164),r=t(57663);function s({children:e,className:n,hidden:t}){return(0,i.jsx)("div",{role:"tabpanel",className:(0,a.A)("tabItem_Ymn6",n),hidden:t,children:e})}function l({children:e,className:n,value:t}){let{selectedValue:a,lazy:o}=(0,r.uc)(),c=t===a;return!c&&o?null:(0,i.jsx)(s,{className:n,hidden:!c,children:e})}},50773(e,n,t){t.d(n,{A:()=>u});var i=t(74848);t(96540);var a=t(34164),r=t(88287),s=t(57663),l=t(28584),o=t(19863);function c({className:e}){let{selectedValue:n,selectValue:t,tabValues:r,block:o}=(0,s.uc)(),d=[],{blockElementScrollPositionUntilNextRender:h}=(0,l.a_)(),u=e=>{let i=e.currentTarget,a=r[d.indexOf(i)].value;a!==n&&(h(i),t(a))},m=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{let t=d.indexOf(e.currentTarget)+1;n=d[t]??d[0];break}case"ArrowLeft":{let t=d.indexOf(e.currentTarget)-1;n=d[t]??d[d.length-1]}}n?.focus()};return(0,i.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":o},e),children:r.map(({value:e,label:t,attributes:r})=>(0,i.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:e=>{d.push(e)},onKeyDown:m,onClick:u,...r,className:(0,a.A)("tabs__item","tabItem_LNqP",r?.className,{"tabs__item--active":n===e}),children:t??e},e))})}function d({children:e}){return(0,i.jsx)("div",{className:"margin-top--md",children:e})}function h({className:e,children:n}){return(0,i.jsxs)("div",{className:(0,a.A)(r.G.tabs.container,"tabs-container","tabList__CuJ"),children:[(0,i.jsx)(c,{className:e}),(0,i.jsx)(d,{children:n})]})}function u(e){let n=(0,o.A)(),t=(0,s.OC)(e);return(0,i.jsx)(s.O_,{value:t,children:(0,i.jsx)(h,{className:e.className,children:(0,s.vT)(e.children)})},String(n))}},57663(e,n,t){t.d(n,{OC:()=>u,O_:()=>f,uc:()=>p,vT:()=>d});var i=t(74848),a=t(96540),r=t(56347),s=t(99989),l=t(96629),o=t(80618),c=t(41367);function d(e){return a.Children.toArray(e).filter(e=>"\n"!==e)}function h({value:e,tabValues:n}){return n.some(n=>n.value===e)}function u(e){let n,{defaultValue:t,queryString:i=!1,groupId:d}=e,u=function(e){let{values:n,children:t}=e;return(0,a.useMemo)(()=>{let e=n??a.Children.toArray(t).flatMap(e=>{if(!e)return[];if((0,a.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return[e];
1let n="string"==typeof e.type?e.type:e.type.name;throw Error(`Docusaurus error: Bad <Tabs> child <${n}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.
2If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)}).map(({props:{value:e,label:n,attributes:t,default:i}})=>({value:e,label:n,attributes:t,default:i})),i=(0,o.XI)(e,(e,n)=>e.value===n.value);if(i.length>0)throw Error(`Docusaurus error: Duplicate values "${i.map(e=>`'${e.value}'`).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[n,t])}(e),[m,p]=(0,a.useState)(()=>(function({defaultValue:e,tabValues:n}){if(0===n.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!h({value:e,tabValues:n}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let t=n.find(e=>e.default)??n[0];if(!t)throw Error("Unexpected error: 0 tabValues");return t.value})({defaultValue:t,tabValues:u})),[f,x]=function({queryString:e=!1,groupId:n}){let t=(0,r.W6)(),i=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,l.aZ)(i),(0,a.useCallback)(e=>{if(!i)return;let n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})},[i,t])]}({queryString:i,groupId:d}),[b,j]=function({groupId:e}){let n=e?`docusaurus.tab.${e}`:null,[t,i]=(0,c.Dv)(n);return[t,(0,a.useCallback)(e=>{n&&i.set(e)},[n,i])]}({groupId:d}),g=h({value:n=f??b,tabValues:u})?n:null;return(0,s.A)(()=>{g&&p(g)},[g]),{selectedValue:m,selectValue:(0,a.useCallback)(e=>{if(!h({value:e,tabValues:u}))throw Error(`Can't select invalid tab value=${e}`);p(e),x(e),j(e)},[x,j,u]),tabValues:u,lazy:e.lazy??!1,block:e.block??!1}}let m=(0,a.createContext)(null);function p(){let e=a.useContext(m);if(!e)throw Error("useTabsContext() must be used within a Tabs component");return e}function f(e){return(0,i.jsx)(m.Provider,{value:e.value,children:e.children})}},28453(e,n,t){t.d(n,{R:()=>s,x:()=>l});var i=t(96540);let a={},r=i.createContext(a);function s(e){let n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.