No available channels

文章讨论了在Spring框架中使用RabbitMQ时遇到的Noavailablechannels异常,该异常通常由于通道(channel)资源耗尽引起。文中解释了RabbitMQ的连接和信道概念,以及为何使用信道来复用TCP连接以优化性能。提出的解决方案包括:区分生产和消费使用不同连接,增大通道缓存大小,调整消费者并发度,以及增加checkout-timeout等待时间。

No available channels 异常

项目配置如下:

spring:
    rabbitmq:
        host: uck1
        port: 5672
        username: xxx
        password: xxxx
        publisher-confirms: true
        publisher-returns: true
        listener:
            direct:
                retry:
                    max-attempts: 3
                    enabled: true
                acknowledge-mode: manual
                # 每个队列的消费者数量
                consumers-per-queue: 5
                prefetch: 10
            type: direct
        cache:
            channel:
                size: 500
                checkout-timeout: 1000
            connection:
                mode: channel
                #size: 2

再无其他特殊配置,但是部署到线上会报 No available channels 的异常

org.springframework.amqp.AmqpTimeoutException: No available channels
	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.obtainPermits(CachingConnectionFactory.java:521)
	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.getChannel(CachingConnectionFactory.java:487)
	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.access$1600(CachingConnectionFactory.java:101)
	at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$ChannelCachingConnectionProxy.createChannel(CachingConnectionFactory.java:1333)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2079)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2047)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.send(RabbitTemplate.java:994)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.convertAndSend(RabbitTemplate.java:1060)
	at org.springframework.amqp.rabbit.core.RabbitTemplate.convertAndSend(RabbitTemplate.java:1053)
	at com.dkd.mq.PushProvider.sendOrdinaryMessage(PushProvider.java:83)
	at com.dkd.RabbitmqDelayApplication.lambda$afterSingletonsInstantiated$0(RabbitmqDelayApplication.java:62)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

rabbitmq 无论是生产者还是消费者 都需要和 RabbitMQ Broker 建立连接,这个连接就是一条 TCP 连接,也就是 Connection. 一旦 TCP 连接建立起来,客户端紧接着可以创建一个 AMQP 信道(Channel),每个信道都会被指派一个唯一的 ID . 信道是建立在 Connection 之上的虚拟连接,RabbitMQ 处理的每条 AMQP 指令都是通过信道完成的。

我们完全可以使用 Connection 就能完成信道的工作,为什么还要引入信道呢?

试想这样一个场景,一个应用程序中有很多个线程需要从 RabbitMQ 中消费消息,或者生产消息,那么必然需要建立很多个 Connection,也就是多个 TCP 连接。

然而对于操作系统而言,建立和销毁 TCP 连接是非常昂贵的开销,如果遇到使用高峰,性能瓶颈也随之显现。

RabbitMQ 采用类似 NIO(Non-blocking I/O)的做法,选择 TCP 连接复用,不仅可以减少性能开销,同时也便于管理。

每个线程把持一个信道,所以信道复用了 Connection 的 TCP 连接。同时 RabbitMQ 可以确保每个线程的私密性,就像拥有独立的连接一样。当每个信道的流量不是很大时,复用单一的 Connection 可以在产生性能瓶颈的情况下有效地节省 TCP 连接资源。但是信道本身的流量很大时,这时候多个信道复用一个 Connection 就会产生性能瓶颈,进而使整体的流量被限制了。此时就需要开辟多个 Connection,将这些信道均摊到这些 Connection 中,至于这些相关的调优策略需要根据业务自身的实际情况进行调节。

上面内容转自博客: https://www.cnblogs.com/eleven24/p/10326718.html

由上面可以知道 我们整个应用只使用了一个连接connection,并在这个连接的基础上创建了500个channel,我们的消费者和生产者都共同使用这些channel来传输数据. 如果此时系统性的并发度不高的话,就是说这个时候500个channel没有同时在使用的话,系统是没有问题的,但是如果系统并发度高,需要同时传输大量的数据和消费大量的数据时,同时耗尽了500个channel,并且还需要创建channel 这个时候就是出现了 No available channels
的问题.

解决办法

  • 措施1: 生产和消费使用不同的connection 扩大传输通路
    rabbitTemplate.setUsePublisherConnection(true);
    在这里插入图片描述

CachingConnectionFactory 在创建时就创建了两个工厂实例,
当设置这个值为true后,在创建连接时,程序会区分是发送还是消费来创建不同的连接,
这两个连接又分别缓存各自的channel

  • 措施2: 增大channel的缓存size
    这个在channel的缓存size 较小时是可以的,当channel的缓存size本身就较大时,更明智的办法不是继续增大size.
    因为connection 就好比 一条高速公路,channel 就好比一辆辆货车.
    货车太多会造成高速公路拥堵,造成数据传输效率降低和增加系统内存消耗.

  • 措施3: 减小部分消费者的并发度即consumers-per-queue: 5
    有些队列的数据量较小,完全可以一个并发即单线程消费搞定,减少channel占用.

  • 措施4: 增大checkout-timeout
    因为达到channel上限后即channel缓存池中channel耗尽,程序在申请channel 他不会立即报错,而是阻塞checkout-timeout时间,在这段时间内有谁及时归还了channel,这个时候也是会正常拿到channel的.

<think>嗯,用户询问配置AP无线功能时无法选择某些信道的原因,特别是是否因为全部信道被占用。首先需要回忆一下无线通信的基本知识。无线网络的信道分配确实是一个常见问题,但可能还有其他因素影响信道选择。 根据之前提供的引用内容,引用[1]中提到路由器可以设置无线信道和带宽,如果邻居使用了相同信道,可能会导致干扰,这时候手动更改信道可能有帮助。不过用户的问题是无法选择某些信道,这应该不是干扰导致的,而是更深层的限制因素。 接下来考虑可能的硬件和法规方面的原因。不同国家或地区的无线电管理机构,比如美国的FCC或中国的无线电管理局,会对可用信道进行规定。例如,2.4GHz频段通常有14个信道,但很多国家只允许使用1-11或1-13,而日本可能开放14信道。而5GHz频段的信道更多,但不同地区允许的信道也不同。因此,AP的信道选项受限于设备销售地区的法规,用户可能身处不支持某些信道的地区,导致无法选择。 硬件支持也是一个因素。低端AP可能只支持部分信道以节省成本,或者固件版本老旧,未更新支持新信道。此外,动态频率选择(DFS)的要求在5GHz频段尤其重要。DFS功能要求AP自动避开雷达等敏感频率,如果检测到雷达信号,某些信道会被自动禁用,用户无法手动选择。这时候即使信道未被占用,AP也可能禁止选择这些信道以避免干扰。 信道绑定技术如40MHz或80MHz带宽会占用多个相邻信道,可能导致某些信道无法单独选择。例如,当用户选择40MHz带宽时,信道6可能和信道2绑定,此时单独选信道3就无法实现。因此带宽设置会影响可选信道的范围。 另外,自动信道选择功能开启时,AP会定期扫描环境并自动切换信道,此时用户手动选择的选项可能被锁定或隐藏。用户需要先关闭自动功能才能自由选择信道。同时,网络模式如802.11b/g/n/ac的不同组合也可能限制可用信道,比如某些模式仅支持特定频段的信道。 关于全部信道被占用的情况,实际上无线电信道是共享媒介,即使邻居占用相同信道,用户仍然可以选择该信道,只是可能遇到干扰问题。因此无法选择某些信道的主要原因并非全部被占用,而是上述的法规、硬件、DFS、带宽绑定或自动设置等因素导致。 综合所有因素,用户应检查AP的地区设置是否正确,升级固件,关闭自动信道选择功能,调整带宽设置,并确认DFS的影响范围。通过这些步骤,通常可以解决信道不可选的问题,而非因为信道被占用。 </think>配置AP时无法选择某些信道**通常不是因"信道全被占用"导致**,而是由以下技术限制和法规因素造成的: --- ### 主要原因分析 1. **国家/地区法规限制(核心原因)** - 不同国家对WiFi频段开放的信道范围不同(例如: - **2.4GHz频段**:中国允许1-13信道,美国/加拿大仅开放1-11信道 - **5GHz频段**:信道36-64/149-165的开放范围因地区而异 - 设备会根据**固件中的区域码**自动屏蔽非法信道,用户无法突破此限制[^1]。 2. **DFS(动态频率选择)机制影响(5GHz特有)** - **雷达避让规则**:5GHz中的52-64/100-144信道需检测军用雷达信号 - 若AP检测到雷达活动(即使未占用),会自动禁用相关信道并显示为不可选 - 典型提示:`DFS Channel Unavailable` 3. **信道绑定(Bandwidth Bonding)限制** - 当选择**高带宽模式**(如40MHz/80MHz)时: - 需占用连续多个子信道(例如40MHz占用2个相邻20MHz信道) - 边界信道(如2.4GHz的信道12/13)因无法提供连续带宽会被禁用 - *示例*:若设置`80MHz带宽`,仅能选择36/52/100等主信道。 4. **硬件射频支持能力** - 低端AP芯片可能**物理屏蔽部分高频段**(如5.8GHz的149-165信道) - 老旧设备固件未更新时,无法支持新开放信道(如WiFi 6E的6GHz频段) --- ### 排查步骤 ```mermaid graph TD A[检查信道是否可选] --> B{5GHz信道?} B -->|是| C[查看DFS状态指示] B -->|否| D[确认国家/地区设置] C --> E[扫描雷达干扰] D --> F[核对本地无线电法规] E --> G[更换非DFS信道] F --> H[更新AP区域码] ``` 1. **登录AP管理界面 → 检查区域设置** - 路径:`Wireless Settings > Country Code`(必须与实际地理位置匹配) 2. **关闭自动信道选择** - 手动选择前需禁用`Auto Channel Selection`功能 3. **降低带宽测试** - 将带宽从80MHz改为20MHz,观察是否释放更多可选信道 4. **使用WiFi分析工具扫描**(如Acrylic WiFi) - 确认不可选信道是否确实被雷达占用(DFS触发时通常持续30分钟锁定) --- ### 结论 > **无法选择信道的主因并非"信道全被占用"**,而是: > - 📍 **地区法规的强制性限制**(占60%以上案例) > - ⚡ **DFS机制主动避让雷达信号** > - 🔧 **带宽绑定导致的物理层约束** > > 建议优先检查AP的区域码配置和DFS状态指示[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值