1"use strict";(self.webpackChunkrabbitmq_website=self.webpackChunkrabbitmq_website||[]).push([["1627"],{89108(e,n,a){a.r(n),a.d(n,{metadata:()=>i,default:()=>d,frontMatter:()=>o,contentTitle:()=>r,toc:()=>l,assets:()=>c});var i=JSON.parse('{"id":"channels/index","title":"Channels","description":"\x3c!--","source":"@site/versioned_docs/version-4.0/channels/index.md","sourceDirName":"channels","slug":"/channels/","permalink":"/docs/4.0/channels/","draft":false,"unlisted":false,"editUrl":"https://github.com/rabbitmq/rabbitmq-website/tree/main/versioned_docs/version-4.0/channels/index.md","tags":[],"version":"4.0","frontMatter":{"title":"Channels","displayed_sidebar":"docsSidebar"},"sidebar":"docsSidebar","previous":{"title":"Stream Core and Plugin","permalink":"/docs/4.0/stream-core-plugin-comparison"},"next":{"title":"Reliability and Data Safety","permalink":"/docs/4.0/reliability"}}'),s=a(74848),t=a(28453);let o={title:"Channels",displayed_sidebar:"docsSidebar"},r="Channels",c={},l=[{value:"Overview",id:"overview",level:2},{value:"The Basics",id:"basics",level:2},{value:"Channel Lifecycle",id:"lifecycle",level:2},{value:"Opening Channels",id:"opening-channels",level:3},{value:"Closing Channels",id:"closing-channels",level:3},{value:"Channels and Error Handling",id:"error-handling",level:3},{value:"Resource Usage",id:"resource-usage",level:2},{value:"Maximum Number of Channels per Connection",id:"channel-max",level:3},{value:"Maximum number of Channels per Node",id:"maximum-number-of-channels-per-node",level:3},{value:"Monitoring, Metrics and Diagnostics",id:"monitoring",level:2},{value:"Memory Use",id:"memory-use",level:3},{value:"Channel Leaks",id:"channel-leaks",level:3},{value:"Relevant Metrics",id:"relevant-metrics",level:4},{value:"High Channel Churn",id:"high-channel-churn",level:3},{value:"Inspecting Channels and Their State in Management UI",id:"inspect-in-management-ui",level:3},{value:"Inspecting Channels and Their State Using CLI Tools",id:"inspect-using-cli-tools",level:3},{value:"Publisher Flow Control",id:"flow-control",level:2}];function h(e){let n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"channels",children:"Channels"})}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["This guide covers various topics related to channels, an ",(0,s.jsx)(n.a,{href:"/tutorials/amqp-concepts",children:"AMQP 0-9-1"}),"-specific abstraction.\nChannels cannot exist without a connection, so getting familiar with the ",(0,s.jsx)(n.a,{href:"./connections",children:"Connections guide"})," first\nis highly recommended."]}),"\n",(0,s.jsx)(n.p,{children:"This guide covers:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#basics",children:"The basics"})," of channels"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#lifecycle",children:"Channel lifecycle"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#error-handling",children:"Channel exceptions"})," (errors) and what they mean"]}),"\n",(0,s.jsxs)(n.li,{children:["Channel ",(0,s.jsx)(n.a,{href:"#resource-usage",children:"resource usage"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#monitoring",children:"Monitoring"})," and metrics related to channels and how to identify common problems"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#flow-control",children:"Flow control"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"and other topics related to connections."}),"\n",(0,s.jsx)(n.h2,{id:"basics",children:"The Basics"}),"\n",(0,s.jsxs)(n.p,{children:["Some applications need multiple logical connections to the\nbroker. However, it is undesirable to keep many TCP\nconnections open at the same time because doing so consumes\nsystem resources and makes it more difficult to configure\nfirewalls. AMQP 0-9-1 connections are multiplexed with\n",(0,s.jsx)(n.code,{children:"channels"}),' that can be thought of as "lightweight\nconnections that share a single TCP connection".']}),"\n",(0,s.jsx)(n.p,{children:"Every protocol operation performed by a client happens on a channel.\nCommunication on a particular channel is completely separate\nfrom communication on another channel, therefore every protocol\nmethod also carries a channel ID (a.
1k.a. channel number), an integer\nthat both the broker and clients use to figure out which channel the method is for."}),"\n",(0,s.jsx)(n.p,{children:"A channel only exists in the context of a connection and never on its own.\nWhen a connection is closed, so are all channels on it."}),"\n",(0,s.jsx)(n.p,{children:"For applications that use multiple threads/processes for\nprocessing, it is very common to open a new channel per thread/process\nand not share channels between them."}),"\n",(0,s.jsx)(n.h2,{id:"lifecycle",children:"Channel Lifecycle"}),"\n",(0,s.jsx)(n.h3,{id:"opening-channels",children:"Opening Channels"}),"\n",(0,s.jsxs)(n.p,{children:["Applications open a channel right after successfully opening a ",(0,s.jsx)(n.a,{href:"./connections",children:"connection"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Here's a Java client example that opens a new channel with an automatically allocated channel ID\nafter opening a new connection:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-java",children:"ConnectionFactory cf = new ConnectionFactory();\nConnection conn = cf.createConnection();\n\nChannel ch = conn.createChannel();\n\n// ... use the channel to declare topology, publish, consume\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In .NET client channels are represented using the ",(0,s.jsx)(n.code,{children:"IModel"})," interface, so the names in the API\nare different:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-csharp",children:'var cf = new ConnectionFactory();\nvar conn = cf.newConnection();\n\n// the .NET client calls channels "models"\nvar ch = conn.CreateModel();\n\n// ... use the channel to declare topology, publish, consume\n'})}),"\n",(0,s.jsx)(n.p,{children:"Much like connections, channels are meant to be long lived. That is, there is no need to open\na channel per operation and doing so would be very inefficient, since opening a channel is a\nnetwork roundtrip."}),"\n",(0,s.jsx)(n.h3,{id:"closing-channels",children:"Closing Channels"}),"\n",(0,s.jsx)(n.p,{children:"When a channel is no longer needed, it should be closed. Closing a channel will render it\nunusable and schedule its resources to be reclaimed:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-java",children:"Channel ch = conn.createChannel();\n\n// do some work\n\n// close the channel when it is no longer needed\n\nch.close();\n"})}),"\n",(0,s.jsx)(n.p,{children:"The same example using the .NET client:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-csharp",children:'// the .NET client calls channels "models"\nvar ch = conn.CreateModel();\n\n// do some work\n\n// close the channel when it is no longer needed\n\nch.Close();\n'})}),"\n",(0,s.jsx)(n.p,{children:"As mentioned above, a closed channel cannot be used. An attempt to perform an operation\non a closed channel will result in an exception that says that the channel has already been\nclosed."}),"\n",(0,s.jsx)(n.p,{children:"When a channel's connection is closed, so is the channel."}),"\n",(0,s.jsxs)(n.p,{children:["If a channel is closed immediately after a consumer ",(0,s.jsx)(n.a,{href:"./confirms",children:"acknowledged a number of deliveries"})," on it,\nthe acknowledgements may or may not reach their target queue before the channel is terminated.\nIn this case the messages with a pending acknowledgement on the channel will be automatically requeued\nfollowing the channel closure."]}),"\n",(0,s.jsxs)(n.p,{children:["This scenario usually applies to workloads with short lived channels. Using long lived channels and\ndesigning consumers in a way that they can handle redeliveries will mitigate the above behavior.\nLong lived channels are usually associated with better performance, as well. Note that redelivered\nmessages will be ",(0,s.jsx)(n.a,{href:"./consumers#message-properties",children:"explicitly marked as such"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"error-handling",children:"Channels and Error Handling"}),"\n",(0,s.jsx)(n.p,{children:"In the section above channels were closed by applications. There is another way a channel can\nbe closed: due to a protocol exception."}),"\n",(0,s.jsx)(n.p,{children:'Certain scenarios are assumed to be recoverable ("soft") errors in the protocol. They render\nthe channel closed but applications can open another one and try to recover or retry a number of\ntimes. Most common examples are:'}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"./queues#property-equivalence",children:"Redeclaring an existing queue"})," or exchange with non-matching properties\nwill fail with a ",(0,s.jsx)(n.code,{children:"406 PRECONDITION_FAILED"})," error"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"./access-control",children:"Accessing a resource"})," the user is not allowed to access will fail\nwith a ",(0,s.jsx)(n.code,{children:"403 ACCESS_REFUSED"})," error"]}),"\n",(0,s.jsxs)(n.li,{children:["Binding a non-existing queue or a non-existing exchange will fail with a ",(0,s.jsx)(n.code,{children:"404 NOT_FOUND"})," error"]}),"\n",(0,s.jsxs)(n.li,{children:["Consuming from a queue that does not exist will fail with a ",(0,s.jsx)(n.code,{children:"404 NOT_FOUND"})," error"]}),"\n",(0,s.jsxs)(n.li,{children:["Publishing to an exchange that does not exist will fail with a ",(0,s.jsx)(n.code,{children:"404 NOT_FOUND"})," error"]}),"\n",(0,s.jsxs)(n.li,{children:["Accessing an ",(0,s.jsx)(n.a,{href:"./queues#exclusive-queues",children:"exclusive queue"}
1)," from a connection other than its declaring one will\nfail with a ",(0,s.jsx)(n.code,{children:"405 RESOURCE_LOCKED"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Client libraries provide a way to observe and react to channel exceptions. For example, in the Java\nclient there is ",(0,s.jsx)(n.a,{href:"/client-libraries/java-api-guide#shutdown",children:"a way to register an error handler"})," and access a channel\nshutdown (closure) reason."]}),"\n",(0,s.jsx)(n.p,{children:"Any attempted operation on a closed channel will fail with an exception. Note that when RabbitMQ\ncloses a channel, it notifies the client of that using an asynchronous protocol method. In other words,\nan operation that caused a channel exception won't fail immediately but a channel closure event\nhandler will fire shortly after."}),"\n",(0,s.jsx)(n.p,{children:"Some client libraries may use blocking operations that wait for\na response. In this case they may communicate channel exceptions differently, e.g. using\nruntime exceptions, an error type, or other means appropriate for the language."}),"\n",(0,s.jsxs)(n.p,{children:["See the ",(0,s.jsx)(n.a,{href:"./specification",children:"AMQP 0-9-1 Reference"})," for a more complete list of\nerror codes."]}),"\n",(0,s.jsx)(n.h2,{id:"resource-usage",children:"Resource Usage"}),"\n",(0,s.jsx)(n.p,{children:"Each channel consumes a relatively small amount of memory on the client. Depending on client library's\nimplementation detail it can also use a dedicated thread pool (or similar) where consumer\noperations are dispatched, and therefore one or more threads (or similar)."}),"\n",(0,s.jsxs)(n.p,{children:["Each channel also consumes a relatively small amount of memory on the node the client is connected to,\nplus a few Erlang processes. Since a node usually serves multiple channel connections, the effects\nof excessive channel usage or channel leaks will primarily be reflected in RabbitMQ nodes' ",(0,s.jsx)(n.a,{href:"#monitoring",children:"metrics"}),"\nand not those of clients."]}),"\n",(0,s.jsxs)(n.p,{children:["Given both of these factors, limiting the number of channels used per connection is highly recommended.\nAs a guideline, most applications can use a single digit number of channels per connection.\nThose with particularly high concurrency rates (usually such applications are ",(0,s.jsx)(n.a,{href:"./consumers",children:"consumers"}),")\ncan start with one channel per thread/process/coroutine and switch to channel pooling\nwhen metrics suggest that the original model is no longer sustainable, e.g. because it consumes\ntoo much memory."]}),"\n",(0,s.jsxs)(n.p,{children:["See the ",(0,s.jsx)(n.a,{href:"#monitoring",children:"Monitoring, Metrics and Diagnostics"})," section to learn about how to inspect\nchannels, the number of channels on a connection, channel churn rate and so on."]}),"\n",(0,s.jsx)(n.h3,{id:"channel-max",children:"Maximum Number of Channels per Connection"}),"\n",(0,s.jsx)(n.p,{children:"The maximum number of channels that can be open on a connection simultaneously\nis negotiated by client and server at connection time. The value is configurable for\nboth RabbitMQ and client libraries."}),"\n",(0,s.jsxs)(n.p,{children:["On the server side, the limit is controlled using the ",(0,s.jsx)(n.code,{children:"channel_max"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"# no more 100 channels can be opened on a connection at the same time\nchannel_max = 100\n"})}),"\n",(0,s.jsx)(n.p,{children:"Should the configured limit be exceeded, the connection will be closed with a fatal\nerror:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"2019-02-11 16:04:06.296 [error] <0.887.0> Error on AMQP connection <0.887.0> (127.0.0.1:49956 -> 127.0.0.1:5672, vhost: '/', user: 'guest', state: running), channel 23:\n operation none caused a connection exception not_allowed: \"number of channels opened (22) has reached the negotiated channel_max (22)\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Clients can be configured to allow fewer channels per connection. With ",(0,s.jsx)(n.a,{href:"/client-libraries/java-api-guide",children:"RabbitMQ Java client"}),",\n",(0,s.jsx)(n.code,{children:"ConnectionFactory#setRequestedChannelMax"})," is the method that controls the limit:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-java",children:"ConnectionFactory cf = new ConnectionFactory();\n// Ask for up to 32 channels per connection. Will have an effect as long as the server is configured\n// to use a higher limit, otherwise the server's limit will be used.\ncf.setRequestedChannelMax(32);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["With ",(0,s.jsx)(n.a,{href:"/client-libraries/dotnet-api-guide",children:"RabbitMQ .NET client"}),", use the ",(0,s.jsx)(n.code,{children:"ConnectionFactory#RequestedChannelMax"}),"\nproperty:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-csharp",children:"var cf = new ConnectionFactory();\n// Ask for up to 32 channels per connection. Will have an effect as long as the server is configured\n// to use a higher limit, otherwise the server's limit will be used.\ncf.RequestedChannelMax = 32;\n"})}),"\n",(0,s.jsx)(n.p,{children:"The lower value of the two is used: the client cannot\nbe configured to allow for more channels than the server configured maximum.\nClients that attempt that will run into an error that looks like this in the logs:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"2019-02-11 16:03:16.543 [error] <0.882.0> closing AMQP connection <0.882.0> (127.0.0.1:49911 -> 127.0.0.1:5672):\nfailed to negotiate connection parameters: negotiated channel_max = 2047 is higher than the maximum allowed value (32)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"maximum-number-of-channels-per-node",children:"Maximum number of Channels per Node"}),"\n",(0,s.jsxs)(n.p,{children:["It is possible to configure the maximum number of channels that are allowed to be open on each node in a cluster using the\nconfiguration parameter ",(0,s.jsx)(n.code,{children:"channel_max_per_node"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"# no more than 500 channels can be opened on each node at the same time\nchannel_max_per_node = 500\n"})}),"\n",(0,s.jsx)(n.h2,{id:"monitoring",children:"Monitoring, Metrics and Diagnostics"}),"\n",(0,s.jsxs)(n.p,{children:["Because they affect node resource use,\nthe number of currently open channels and channel opening/closure rates are important metrics\nof the system that should be ",(0,s.jsx)(n.a,{href:"./monitoring",children:"monitored"}),". Monitoring them will help detect a number of\ncommon problems:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Channel leaks"}),"\n",(0,s.jsx)(n.li,{children:"High channel churn"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Both problems eventually lead to node exhaustion of ",(0,s.jsx)(n.a,{href:"#resource-usage",children:"resources"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Individual channel metrics such as the number of ",(0,s.jsx)(n.a,{href:"./confirms#acknowledgement-modes",children:"unacknowledged messages"}),"\nor ",(0,s.jsx)(n.code,{children:"basic.get"})," operation rate can help identify irregularities and inefficiencies\nin application behavior."]}),"\n",(0,s.jsx)(n.h3,{id:"memory-use",children:"Memory Use"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"./monitoring",children:"Monitoring systems"})," and operators alike may need to inspect how much memory\nchannels consume on a node, the total\nnumber of channels on a node and then identify how many there are on each connection."]}),"\n",(0,s.jsxs)(n.p,{children:["The number of channels is displayed in the ",(0,s.jsx)(n.a,{href:"./management",children:"management UI"})," on the Overview tab,\nas is the ",(0,s.jsx)(n.a,{href:"./connections#monitoring",children:"number of connections"}),".\nBy dividing the number of channels by the number of connections\nthe operator can determine an average number of channels per connection."]}),"\n",(0,s.jsxs)(n.p,{children:["To find out how much memory on a node is used by channels, use ",(0,s.jsx)(n.a,{href:"./man/rabbitmq-diagnostics.8",children:(0,s.jsx)(n.code,{children:"rabbitmq-diagnostics memory_breakdown"})}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmq-diagnostics memory_breakdown -q --unit mb\n# => [elided for brevity]\n# ...\n# => connection_channels: 3.596 mb (2.27%)\n# ...\n# => [elided for brevity]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["See the ",(0,s.jsx)(n.a,{href:"./memory-use",children:"RabbitMQ Memory Use Analysis guide"})," for details."]}),"\n",(0,s.jsx)(n.h3,{id:"channel-leaks",children:"Channel Leaks"}),"\n",(0,s.jsx)(n.p,{children:"A channel leak is a condition under which an application repeatedly opens channels without closing them,\nor at least closing only some of them."}),"\n",(0,s.jsx)(n.p,{children:"Channel leaks eventually exhaust the node (or multiple target nodes) of RAM and CPU resources."}),"\n",(0,s.jsx)(n.h4,{id:"relevant-metrics",children:"Relevant Metrics"}),"\n",(0,s.jsx)(n.p,{children:"Management UI's Overview tab lists a total number of channels in all virtual hosts the current\nuser has access to:"}),"\n",(0,s.jsx)("figure",{children:(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"mgmt-ui-global-channel-count.png",src:a(46029).A+"",width:"1160",height:"156"})})}),"\n",(0,s.jsx)(n.p,{children:"To inspect the current number of channels on a connection as well as the per-connection channel limit, navigate\nto the Connections tab and enable the relevant columns if they are not displayed:"}),"\n",(0,s.jsx)("figure",{children:(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Per connection channel count in management UI",src:a(76347).A+"",width:"1794",height:"202"})})}),"\n",(0,s.jsxs)(n.p,{children:["Overview and individual node pages provide a chart of channel churn rate as of ",(0,s.jsx)(n.a,{href:"/release-information",children:"RabbitMQ 3.7.9"}),".\nIf the rate of channel open operations is consistently higher than that of channel close operations,\nthis is evidence of a channel leak in one of the applications:"]}),"\n",(0,s.jsx)("figure",{children:(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Channel count growth in management UI",src:a(21829).A+"",width:"1186",height:"284"})})}),"\n",(0,s.jsx)(n.p,{children:"To find out what connection leaks channels, inspect per-connection channel count as demonstrated in this guide."}),"\n",(0,s.jsx)(n.h3,{id:"high-channel-churn",children:"High Channel Churn"}),"\n",(0,s.jsx)(n.p,{children:"A system is said to have high channel churn when its rate of newly opened channels is consistently high and\nits rate of closed channels is consistently high. This usually means that an application\nuses short lived channels or channels are often closed due to channel-level exceptions."}),"\n",(0,s.jsx)(n.p,{children:"While with some workloads this is a natural state of the system,\nlong lived channels should be used instead when possible."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"./management",children:"Management UI"})," provides a chart of channel churn rate.\nBelow is a chart that demonstrates a fairly low channel churn with a virtually identical number of channel open and closed\nin the given period of time:"]}),"\n",(0,s.jsx)("figure",{children:(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Node channel churn in management UI",src:a(49203).A+"",width:"1156",height:"276"})})}),"\n",(0,s.jsx)(n.p,{children:"While connection and disconnection rates are system-specific, rates consistently above 100/second likely indicate a suboptimal\nconnection management by one or more applications and usually are worth investigating."}),"\n",(0,s.jsx)("figure",{children:(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"High channel churn in management UI",src:a(42739).A+"",width:"1156",height:"276"})})}),"\n",(0,s.jsxs)(n.p,{children:["Note that some clients and runtimes (notably PHP) do not use long-lived connections and high connection\nchurn rates are expected from them unless a ",(0,s.jsx)(n.a,{href:"https://github.com/cloudamqp/amqproxy",children:"specialized proxy is used"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"inspect-in-management-ui",children:"Inspecting Channels and Their State in Management UI"}),"\n",(0,s.jsx)(n.p,{children:"To inspect channels in the management UI, navigate to the Channels tab and add or remove columns\nas needed:"}),"\n",(0,s.jsx)("figure",{children:(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"High channel churn in management UI",src:a(50670).A+"",width:"2070",height:"714"})})}),"\n",(0,s.jsx)(n.h3,{id:"inspect-using-cli-tools",children:"Inspecting Channels and Their State Using CLI Tools"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"./man/rabbitmqctl.8",children:(0,s.jsx)(n.code,{children:"rabbitmqctl list_connections"})})," and ",(0,s.jsx)(n.a,{href:"./man/rabbitmqctl.8",children:(0,s.jsx)(n.code,{children:"rabbitmqctl list_channels"})})," are the\nprimary commands for inspecting per-connection channel count and channel details such as the number of\nconsumers, ",(0,s.jsx)(n.a,{href:"./confirms#acknowledgement-modes",children:"unacknowledged messages"}),", ",(0,s.jsx)(n.a,{href:"./confirms#channel-qos-prefetch",children:"prefetch"})," and so on."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmqctl list_connections name channels -q\n# => name channels\n# => 127.0.0.1:52956 -> 127.0.0.1:5672 10\n# => 127.0.0.1:52964 -> 127.0.0.1:5672 33\n"})}),"\n",(0,s.jsx)(n.p,{children:"The rightmost column contains channel count on the connection."}),"\n",(0,s.jsx)(n.p,{children:"Table headers can be suppressed:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmqctl list_connections name channels -q --no-table-headers\n# => 127.0.0.1:52956 -> 127.0.0.1:5672 10\n# => 127.0.0.1:52964 -> 127.0.0.1:5672 33\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To inspect individual channels, use ",(0,s.jsx)(n.a,{href:"./man/rabbitmqctl.8",children:(0,s.jsx)(n.code,{children:"rabbitmqctl list_channels"})}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmqctl list_channels -q\n# => pid user consumer_count messages_unacknowledged\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n"})}),"\n",(0,s.jsx)(n.p,{children:"Table headers can be suppressed:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmqctl list_channels -q --no-table-headers\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n# => <[email protected]> guest 0 0\n"})}),"\n",(0,s.jsx)(n.p,{children:"It is possible to display a different set of columns:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmqctl list_channels -q --no-table-headers vhost connection number prefetch_count messages_unconfirmed\n# => / <[email protected]> 1 0 0\n# => / <[email protected]> 1 0 0\n# => / <[email protected]> 2 0 0\n# => / <[email protected]> 3 0 0\n# => / <[email protected]> 2 0 0\n# => / <[email protected]> 3 0 0\n# => / <[email protected]> 4 0 0\n# => / <[email protected]> 4 0 0\n# => / <[email protected]> 5 0 0\n# => / <[email protected]> 6 0 0\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmqctl list_channels -s vhost connection number confirm\
1n# => / <[email protected]> 1 false\n# => / <[email protected]> 1 false\n# => / <[email protected]> 2 false\n# => / <[email protected]> 3 false\n# => / <[email protected]> 2 false\n# => / <[email protected]> 3 false\n# => / <[email protected]> 4 false\n# => / <[email protected]> 4 false\n# => / <[email protected]> 5 false\n"})}),"\n",(0,s.jsx)(n.h2,{id:"flow-control",children:"Publisher Flow Control"}),"\n",(0,s.jsxs)(n.p,{children:["Channels that publish messages can outpace other parts of the system, most likely busy queues and queues\nthat perform replication. When that happens, ",(0,s.jsx)(n.a,{href:"./flow-control",children:"flow control"})," is applied to\npublishing channels and, in turn, connections. Channels and connections that only consume messages\nare not affected."]}),"\n",(0,s.jsxs)(n.p,{children:["With slower consumers that use ",(0,s.jsx)(n.a,{href:"./confirms#acknowledgement-modes",children:"automatic acknowledgement mode"}),"\nit is very likely that connections and channels will experience flow control when writing to\nthe TCP socket."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"./monitoring",children:"Monitoring"})," systems can collect metrics on the number of connections in flow state.\nApplications that experience flow control regularly may consider to use separate connections\nto publish and consume to avoid flow control effects on non-publishing operations (e.g. queue management)."]})]})}function d(e={}){let{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},21829(e,n,a){a.d(n,{A:()=>i});let i=a.p+"assets/images/mgmt-ui-channel-count-growth-ddc0721bd8c67644b9a347adeab0e7c3.png"},50670(e,n,a){a.d(n,{A:()=>i});let i=a.p+"assets/images/mgmt-ui-channel-list-6af9c43c85298e981391d7d1446d7bfe.png"},46029(e,n,a){a.d(n,{A:()=>i});let i=a.p+"assets/images/mgmt-ui-global-channel-count-cf606d15f2ca00418605da41ef49812c.png"},42739(e,n,a){a.d(n,{A:()=>i});let i=a.p+"assets/images/mgmt-ui-high-channel-churn-2c63dc3c0183aa98daa8ea49d5d50934.png"},49203(e,n,a){a.d(n,{A:()=>i});let i=a.p+"assets/images/mgmt-ui-node-channel-churn-5e5428ea6ba3aaa7236c8f8c13565267.png"},76347(e,n,a){a.d(n,{A:()=>i});let i=a.p+"assets/images/mgmt-ui-per-connection-channel-max-and-count-408c3ada50bd59b535fff412c7a7110c.png"},28453(e,n,a){a.d(n,{R:()=>o,x:()=>r});var i=a(96540);let s={},t=i.createContext(s);function o(e){let n=i.useContext(t);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(t.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.