当前位置: 首页 > news >正文

遇到RabbitMQ 的 `channel_max` 限制报错

raise exception aiormq.exceptions.ConnectionNotAllowed: NOT_ALLOWED -
number of channels opened (2047) has reached the negotiated
channel_max (2047)

这个错误表明你遇到了 RabbitMQ 的 channel_max 限制。RabbitMQ 服务器与客户端在建立连接时会“协商”一个最大通道数(channel_max),默认通常是 2047。当你的应用创建的通道数量达到这个上限时,就会抛出 NOT_ALLOWED - number of channels opened (2047) has reached the negotiated channel_max (2047) 错误。

问题分析:

这个问题是另一个层面的问题:通道(Channel)的生命周期管理不当

存在一个关键误解:

通道(Channel)不应该被复用或“池化”。

每次使用完通道后,它应该被 关闭,而不是放回连接池。如果你反复从同一个连接创建新通道但不关闭它们,通道计数就会不断累积,最终达到 channel_max 限制。


✅ 正确的做法

  1. 每个操作使用一个新通道
  2. 操作结束后,通道必须被关闭
  3. 连接可以复用,但通道不能

🔧 修复方案:修改 get_channel() 上下文管理器

你需要确保每次 get_channel() 使用完毕后,通道被关闭,而连接被放回池中。

@asynccontextmanager
async def get_channel(self) -> AsyncGenerator[AbstractRobustChannel, None]:"""获取通道的上下文管理器每次调用都会从连接池获取一个连接,创建一个新通道使用完毕后,通道会被关闭,连接会被归还到池中"""if not self._is_initialized:await self.initialize()async with self._lock:while True:if self._connection_pool:connection = self._connection_pool.pop()if not connection.is_closed:breakelse:logger.warning("Found a closed connection in pool, discarding it.")continueelse:logger.warning("No available connections in pool, creating new one")connection = await self._create_connection()breaktry:# 创建新通道channel = await connection.channel()logger.debug("Created new channel for operation")yield channel  # 使用通道finally:# 关键:使用完后关闭通道if 'channel' in locals() and not channel.is_closed:await channel.close()logger.debug("Channel closed after use")# 将连接(不是通道)归还到池中async with self._lock:if not connection.is_closed:self._connection_pool.append(connection)logger.debug("Connection returned to pool")else:logger.warning("Connection was closed, not returning to pool")

🚫 为什么不能复用通道?

  • 线程/协程不安全:AMQP 通道不是线程安全的,多个协程同时使用同一个通道可能导致协议错误。
  • 状态污染:通道可能处于某种状态(如事务、QoS 设置等),复用会导致不可预测的行为。
  • 最佳实践:官方推荐是“每个操作一个通道”或“每个线程/协程一个通道”。

🛠 其他建议

  1. 检查 channel_max 配置(可选):
    你可以尝试在连接时设置更低的 channel_max 来避免达到默认的 2047,但这只是治标不治本。
connection = await aio_pika.connect_robust(self.url,heartbeat=self.heartbeat,timeout=self.connection_timeout,client_properties={"channel_max": 100},  # 限制客户端通道数
)
  1. 监控连接和通道状态
    添加日志,监控连接和通道的创建、关闭情况。

  2. 避免长时间持有通道
    通道应该用于短时间的操作(如发布、消费一次消息),不要长期持有。


✅ 总结

你遇到的错误是因为通道没有被正确关闭,导致连接上的通道数不断累积,最终达到 channel_max 限制。

解决方案:

  • 修改 get_channel(),确保每次使用后 关闭通道
  • 连接 归还到连接池,而不是通道。
  • 遵循“每个操作一个通道”的最佳实践。

这样就能避免 channel_max 被耗尽,解决 ConnectionNotAllowed 错误。

http://www.dtcms.com/a/461162.html

相关文章:

  • 机器学习实战项目:Python+Flask 汽车销量分析可视化系统(requests爬车主之家+可视化 源码+文档)✅
  • 惠州城乡建设部网站印刷包装公司网站模板
  • WEB前端 JavaScript 学习笔记
  • 如何使用Python实现LRU缓存
  • OSCP渗透实战(第二期):Linux系统攻防与权限提升完全指南
  • LeetCode 118. 杨辉三角
  • AI原生应用架构白皮书 - AI原生应用架构及其关键要素
  • 蓝绿发布与金丝雀发布策略简介_笔记
  • 流媒体视频技术在明厨亮灶场景中的深度应用
  • 建设网站是否需要一个主机全球邮企业邮箱登录
  • 余弦相似度凭什么成了文本推荐的“方向指南针”?从几何夹角到语义匹配的AI密码
  • 解决Docker Hub被封的问题
  • 基于android的中天模拟键盘APP的设计与实现(初稿)
  • 数据结构——十七、线索二叉树找前驱与后继
  • 数据结构-----栈队列
  • 兰州网站制作有哪些怎样下载字体到wordpress
  • 【ASP.NET Core】分布式场景下ASP.NET Core中JWT应用教程
  • C++分布式语音识别服务实践——性能优化与实战部署
  • 【硬核分表】MySQL水平分表全景指南:从策略对比、全局ID到ShardingSphere实战
  • 零基础学AI大模型之Stream流式输出实战
  • Nacos 实战指南:微服务下服务注册与配置管理的完整落地
  • 网站站seo教程深圳有几个区哪个区最富裕
  • 网站seo诊断分析和优化方案企业形象设计课程标准
  • linux中jenkins正常启动外部无法访问
  • 紫砂壶网站开发与设计报告论文大型门户网站建设所具有的功能模块主要有几种类型
  • TCC 与 Saga 分布式事务:最终一致性实战指南
  • python如何把png图片转jpg
  • CentOS 7 上安装 PostgreSQL
  • PCIe协议之Margning篇之 Margining 入门
  • 业主信息查询优化说明