java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > RabbitMQ的Channel

深入理解Spring中RabbitMQ的Channel

作者:Sam_Deep_Thinking

这篇文章主要介绍了深入理解Spring中RabbitMQ的Channel,在RabbitMq中,channel表示逻辑连接或者叫虚拟连接,是棣属于TCP连接的,一个TCP连接里可以创建多个channel,在Rabbit MQ里,消息的发送和接收都是基于channel的,需要的朋友可以参考下

概述

在 AMQP 协议中,有 channel 的概念,在 RabbitMq 中, channel 表示逻辑连接或者叫虚拟连接,是棣属于 TCP 连接的。

一个 TCP 连接里可以创建多个 channel ,在 Rabbit MQ 里,消息的发送和接收都是基于 channel 的。

connection和channel的关系

有了 TCP 连接后,还需要 channel 的原因如下:

因此采用多个 channel 多路复用一个 TCP 连接的方式才比较合理。

channel线程不安全

channel 不是线程安全的,线程并发的去访问同一个 channel 会出问题。

这里有几种处理方式:

  1. 全局公用一个channel且使用全局锁,让操作channel排队.这种明显性能是不行的;
  2. 一个线程对应创建一个新的channel,但是要处理好一个连接能支撑的最大channel数量;
  3. 一个线程对应一个channel,但是是从channel池子拿的,不是每次都创建新的.一旦一个线程完成了一个channel的使用,它将返回到池中,从而使该channel可用于另一个线程。

量不大的话,使用第二种方式就可以了。量大的话,建议使用第三种方式,毕竟创建和销毁 channel 也是耗时耗资源的.在 spring amqp 中,提供了一个缓存 channel 的方案。

可以在创建 CachingConnectionFactory 时指定缓存的模式。

connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL);
connectionFactory.setChannelCacheSize(25);

上面的两行代码,表示 channel 共用唯一的一个连接,且缓存了25个 channel ,注意这里的25个并不是说,这个连接里只能最多创建25个 channel ,而是说最多缓存25个 channel 。举个例子,假设并发发送100条消息,在 CachingConnectionFactory.CacheMode.CHANNEL 模式下,瞬间会创建100个 channel 的,然后往缓存里放25个 channel ,当流量下去了,刚刚创建的多余的 channel 会自动关闭掉的,缓存里只保留25个。

使用这种方式的话,要注意缓存的 channel 数量,不能太小,不然流量一大,仍然会造成频繁关闭 channel 的情况。当然我们也不能说有多少并发,就创建多少个 channel ,还是要限制一下,这个时候可以使用:

connectionFactory.setChannelCheckoutTimeout(1000);

当 ChannelCheckoutTimeout 的值大于0的时候, ChannelCacheSize 的值就是最大的 channel 数量了,一旦从缓存中获取不到 channel ,等待 ChannelCheckoutTimeout 毫秒后,如果还是获取不到的,就会抛 AmqpTimeoutException 了。

我们也可以自己实现 channel pool ,但是不太建议怎么做,毕竟 spring amqp 还是相当成熟的,直接使用就可以了。

CacheMode.CHANNEL模式性能

如上文所述,采用了 CacheMode.CHANNEL 的模式的话,就是一线程一 channel 形式,且这些 channel 共享了同一个连接,也即是共享同一个 socket

当并发量一大的时候,可能导致同一时刻,多个线程都想往这个 socket 上写数据。

为了避免这种情况,只能加锁,让拿不到锁的线程 block 住。做了压力测试,并发10个线程发送1000000条消息,结果线程被 block 住了,如下图:

在这里插入图片描述

作者也提到,当流量很大的时候,使用 CacheMode.CONNECTION 的模式,可以提高发送效率。

channel的监控

RabbitMQ Admin UI 提供了一个监控 channel 的界面,我们主要关注两点:

channel有没有可能泄露,打开了channel,却没有关闭channel;打开channel和关闭channel的速率。

如果通道打开操作的速率始终高于通道关闭操作的速率,那就可能发生 channel 泄露了。

如下图:

在这里插入图片描述

如果打开和关闭 channel 的速率都很高,也值得观察一下。因为可能是没有缓存 channel 了。

当流量继续增大的时候,可能会出现吞吐量上不去的情况,如下图:

在这里插入图片描述

到此这篇关于深入理解Spring中RabbitMQ的Channel的文章就介绍到这了,更多相关RabbitMQ的Channel内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文