深入理解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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解MyBatis XML配置解析

    详解MyBatis XML配置解析

    这篇文章主要介绍了详解MyBatis XML配置解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Java构造器使用方法及注意事项

    Java构造器使用方法及注意事项

    这篇文章主要介绍了Java构造器使用方法及注意事项的相关资料,这里举例说明如何使用构造器及需要注意的地方,需要的朋友可以参考下
    2017-07-07
  • Java之如何读取Excel获取真实行数

    Java之如何读取Excel获取真实行数

    这篇文章主要介绍了Java之如何读取Excel获取真实行数问题,具有很好的参考价值,希望对大家有所帮助。
    2023-06-06
  • Java实现雪花算法的原理和实战教程

    Java实现雪花算法的原理和实战教程

    这篇文章主要介绍了Java实现雪花算法的原理和实战教程,本文通过语言表述和代码的实现讲解了该项算法,,需要的朋友可以参考下
    2021-06-06
  • SpringBoot项目启动打包报错类文件具有错误的版本 61.0, 应为 52.0的解决方法

    SpringBoot项目启动打包报错类文件具有错误的版本 61.0, 应为 52.0的解决

    这篇文章主要给大家介绍了关于SpringBoot项目启动打包报错类文件具有错误的版本 61.0, 应为 52.0的解决方法,文中有详细的排查过程和解决方法,通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • springboot+mybatis plus实现树形结构查询

    springboot+mybatis plus实现树形结构查询

    实际开发过程中经常需要查询节点树,根据指定节点获取子节点列表,本文主要介绍了springboot+mybatis plus实现树形结构查询,感兴趣的可以了解一下
    2021-07-07
  • SpringMVC拦截器——实现登录验证拦截器的示例代码

    SpringMVC拦截器——实现登录验证拦截器的示例代码

    本篇文章主要介绍了SpringMVC拦截器——实现登录验证拦截器的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-02-02
  • 简单了解Mybatis如何实现SQL防注入

    简单了解Mybatis如何实现SQL防注入

    这篇文章主要介绍了简单了解Mybatis如何实现SQL防注入,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Java按时间梯度实现异步回调接口的方法

    Java按时间梯度实现异步回调接口的方法

    这篇文章主要介绍了Java按时间梯度实现异步回调接口,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-08-08
  • 手写Java LockSupport的示例代码

    手写Java LockSupport的示例代码

    LockSupport给我们提供了一个非常强大的功能,它是线程阻塞最基本的元语,他可以将一个线程阻塞也可以将一个线程唤醒,因此经常在并发的场景下进行使用。本文将用60行代码实现手写LockSupport,需要的可以参考一下
    2022-08-08

最新评论