bigywater.tech
RabbitMQ · 21

连接与 channel 的数量:一个连接多少 channel 合适

一个连接开多少 channel 合适?channel 多了会不会拖慢?想提高吞吐,该多开 channel 还是多开连接?这篇量了上限、每个 channel 的开销,以及 channel 和连接两种扩展方式各自的吞吐。

2047
channel_max:broker 允许一条连接上最多开的 channel 数
~4 进程 / ~20 KiB
每个 channel 在 broker 里的 Erlang 进程数和内存
36805 → 94976
1 个连接与 4 个连接(各一个客户端进程)的总发布吞吐,条/秒

上限

实测 · 本机执行输出
  协商后连接上的 channel_max = 2047(pika 默认请求 0 = 不限制,由 broker 在 Connection.Tune 里给出的 2047 决定)
  成功开到第 2047 个 channel 后,下一个失败: NoFreeChannels: 
  list_connections 的 channels 列: 2047

broker 在 Connection.Tune 里告诉客户端 channel_max(默认 2047),客户端协商后不能超过。超过时客户端库(这里是 pika)直接抛 NoFreeChannels。

开销

实测 · 本机执行输出
  channel 数  Erlang 进程增量  内存增量     每个 channel
  100                407         2.5 MiB      25.3 KiB / 4.1 进程
  1000              4007        17.8 MiB      18.2 KiB / 4.0 进程
  2000              8006        44.2 MiB      22.6 KiB / 4.0 进程

每个 channel 在 broker 里约 4 个 Erlang 进程、18~25 KiB,线性增长;2000 个 channel 就是 8006 个进程、约 44 MiB。

channel 不提速

实测 · 本机执行输出
  1 个连接 ×  1 个 channel: 2635 ms  37945 条/秒
  1 个连接 ×  4 个 channel: 2689 ms  37188 条/秒
  1 个连接 × 16 个 channel: 2688 ms  37197 条/秒
  1 个连接 × 64 个 channel: 2779 ms  35980 条/秒

同一个连接上开 1、4、16、64 个 channel 并轮流发布,吞吐都在 36000~38000 条/秒,没有区别。channel 的价值是隔离(各自的错误、确认、消费者),不是并行度。

连接提速

实测 · 本机执行输出
  1 个连接(各 50000 条,共 50000 条): 最慢的一个用了 1358 ms;合计 36805 条/秒
  2 个连接(各 50000 条,共 100000 条): 最慢的一个用了 1479 ms;合计 67609 条/秒
  4 个连接(各 50000 条,共 200000 条): 最慢的一个用了 2106 ms;合计 94976 条/秒
  8 个连接(各 50000 条,共 400000 条): 最慢的一个用了 4087 ms;合计 97867 条/秒

多开连接(每个连接一个客户端进程)才增加总吞吐:到 4 个连接时 94976 条/秒,8 个连接就不再增长了(机器 CPU 被客户端和 broker 共用)。

分步演示

连接与 channel 数量
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / RabbitMQ 4.3.6 / Erlang/OTP 28.5 / pika 1.4.4(Homebrew 与临时虚拟环境);所有节点都是本机自己起的 RabbitMQ 进程(127.0.0.1,端口 9500 以上,每个实验独立的数据目录与节点名,不连任何外部服务);命令输出来自真实的 rabbitmqctl 与管理 API,发布与消费用 pika 的真实连接;计时用 time.perf_counter,数字每次运行会有小幅抖动。第一节直连 broker 读 channel_max 并一直开到失败;第二节用 rabbitmqctl eval 读 erlang:system_info(process_count) 与 erlang:memory(total),开 channel 后等 2 秒;第三节同一个 pika 连接内轮流发布(不开 confirm,用 queue_declare passive 往返确认发完),3 轮中位数;第四节是 qwork.py 子进程各开一条连接,各发 50000 条,取最慢一个的耗时,3 轮中位数
    • 没有验证:开 confirm 时多 channel 的吞吐;消费端的多 channel / 多连接对比;服务器 CPU 核数更多时多连接的扩展上限;客户端换成多线程或异步客户端(这里是单线程 pika 的同步发布);连接数很大(几千)时 broker 的行为;TLS 连接的开销
    京ICP备2026067502号-1京公网安备11010502063487号