深入理解Spring中RabbitMQ的Channel

 更新时间:2023年08月28日 09:17:12   作者: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 的原因如下:

  • 创建和销毁TCP连接很耗时;
  • 打开太多TCP连接,耗操作系统资源,并发量大到一定程度,系统的吞吐量会降低;
  • 使用一个connection多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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Dubbo3和Spring Boot整合过程源码解析

    Dubbo3和Spring Boot整合过程源码解析

    Dubbo首先是提供了一个单独的模块来和Spring Boot做整合,利用 Spring Boot自动装配的功能,配置了一堆自动装配的组件,本文介绍Dubbo3和Spring Boot整合过程,需要的朋友一起看看吧
    2023-08-08
  • maven解决依赖冲突的三种解决方法

    maven解决依赖冲突的三种解决方法

    依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成了包版本冲突,本文主要介绍了maven解决依赖冲突的三种解决方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Java中的同步非阻塞IO模型详解

    Java中的同步非阻塞IO模型详解

    这篇文章主要介绍了Java中的同步非阻塞IO模型详解,同步非阻塞IO模型,我们能够知道,用户线程一直发送请求,内核一直都能都够返回 ,直到内核完成准备数据、数据拷贝的工作,并且返回成功的指示,在此过程中用户线程不是阻塞的状态,需要的朋友可以参考下
    2024-01-01
  • 详解Mybatis中万能的Map和模糊查询写法

    详解Mybatis中万能的Map和模糊查询写法

    这篇文章主要介绍了Mybatis中万能的Map和模糊查询写法的相关资料,帮助大家更好的理解和使用Mybatis,感兴趣的朋友可以了解下
    2021-03-03
  • Java实现特定范围的完数输出算法示例

    Java实现特定范围的完数输出算法示例

    这篇文章主要介绍了Java实现特定范围的完数输出算法,简单说明了完数的概念、计算原理并结合实例形式分析了java针对给定范围内的完数输出操作实现技巧,需要的朋友可以参考下
    2017-12-12
  • java对xml节点属性的增删改查实现方法

    java对xml节点属性的增删改查实现方法

    下面小编就为大家带来一篇java对xml节点属性的增删改查实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • 在已有spring的基础上集成hibernate的实例讲解

    在已有spring的基础上集成hibernate的实例讲解

    下面小编就为大家带来一篇在已有spring的基础上集成hibernate的实例讲解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • 解决无法解析javax.servlet的方法

    解决无法解析javax.servlet的方法

    最近在创建一个servlet时,自动生成的代码中出现servlet无法解析的提示,令我无法正常使用servlet里的方法,在对各个步骤进行查看后,发现了问题所在,需要的朋友可以参考下
    2021-05-05
  • java开发CPU流水线与指令乱序执行详解

    java开发CPU流水线与指令乱序执行详解

    这篇文章主要为大家介绍了java开发CPU流水线与指令乱序执行详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Springboot mybatis常见配置问题解决

    Springboot mybatis常见配置问题解决

    这篇文章主要介绍了Springboot mybatis常见配置问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11

最新评论