RabbitMQ核心架构

news2024/12/22 20:43:37

RabbitMQ架构设计 

  1. Producer:负责产生消息。

  2. Connection:RabbitMQ客户端和代理服务器之间的TCP连接。

  3. Channel:建立在连接之上的虚拟连接,RabbitMQ操作都是在信道中进行。

  4. Broker:一个Broker可以看做一个RabbitMQ服务节点或者服务实例。

  5. Exchange:生产者发送消息到交换器,交换器根据路由key投递到相应的队列。

  6. Queue:存储消息的队列 。

  7. RoutingKey:路由键,指定消息的路由规则。

  8. BindingKey:绑定键,关联交换器和队列。

  9. Consumer:消费消息。

路由机制

  1. Direct:默认方式,根据消息的路由键完全匹配队列的绑定键来分发消息。
  2. fanout:广播模式,将消息投递到所有绑定到交换器的队列。
  3. topic:使用模糊匹配的方式根据路由键将消息分发到不同的队列中,支持通配符(*和#)进行匹配。
  4. header:不依赖路由键,而是根据消息的头部信息来进行匹配和分发。

连接RabbitMQ

final ConnectionFactory factory = new ConnectionFactory();
factory.setHost(IP_ADDRESS);
factory.setPort(PORT);
factory.setUsername(USERNAME);
factory.setPassword(PASSWORD);
factory.setVirtualHost(VIRTUAL_HOST);
final Connection connection = factory.newConnection();
final Channel channel = connection.createChannel();

Connection 可以用来创建多个 Channel,但是 Channel 不能线程共享使用。channel 的开启有一个 isOpen 方法可以得知

com.rabbitmq.client.impl.ShutdownNotifierComponent#isOpen    
@Override
    public boolean isOpen() {
    synchronized(this.monitor) {
        return this.shutdownCause == null;
    }
}

生产者发送消息

  1. 生产者连接到 RabbitMO Broker,建立一个连接(Connection),开启一个信道(Channel)
  2. 生产者声明一个交换器,并设置相关属性,比如交换器类型、是否持久化等
  3. 生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等
  4. 生产者通过路由键将交换器和队列绑定起来
  5. 生产者发送消息至 RabbitMO Broker,其中包含路由键、交换器等信息
  6. 相应的交换器根据接收到的路由键查找相匹配的队列。
  7. 如果找到,则将从生产者发送过来的消息存入相应的队列中。
  8. 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
  9. 关闭信道。
  10. 关闭连接。

交换器和队列

创建临时队列

channel.exchangeDeclare(EXCHANGE_NAME, "direct", true);
final String queue = channel.queueDeclare().getQueue();
channel.queueBind(queue, EXCHANGE_NAME, routingKey);

上面创建一个持久化的、绑定类型为 direct 的交换器,同时也创建了一个非持久化的、排他的、自动删除的队列(队列名称由 RabbitMQ 自动生成)。

创建持久化队列

channel.exchangeDeclare(EXCHANGE_NAME, "direct", true);
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
channel.queueBind(queue, EXCHANGE_NAME, routingKey);

分配一个固定的队列名称,并设置持久化、非排他的、非自动删除的队列

生产者和消费者都可以声明一个交换器或则队列,如果尝试声明一个已经存在的交换器或队列(只要声明的参数完全匹配已存在的交换器或队列),RabbitMQ 则什么都不做,直接返回成功。如果参数不匹配则会抛出异常

创建交换器

public Exchange.DeclareOk exchangeDeclare(String exchange, String type,
                                          boolean durable,
                                          boolean autoDelete,
                                          boolean internal,
                                          Map<String, Object> arguments)

返回 Exchange.DeclareOk 标识成功声明了一个交换器

  • exchange:交换器名称

  • type:交换器类型;常见的有:fanout、direct、topic...

    com.rabbitmq.client.BuiltinExchangeType 类定义了交换器类型

  • durable:是否持久化

    持久化将交换器存盘,服务重启时不会丢失相关信息

  • autoDelete:是否自动删除;自动删除的前提是:至少有一个队列或则交换器与这个交换器绑定,之后所有与这个交换器绑定的队列或则交换器都与此解绑

    **注意:**这里自动删除,不是当连接断开时,自动删除这个交换器。

  • internal:是否内置的;如果是内置的交换器,客户端程序无法直接发送消息到这个交换器 中,只能通过交换器路由 到交换器这种方式。

  • arguments:其他一些结构化参数

删除交换器

void exchangeDeleteNoWait(String exchange, boolean ifUnused) throws IOException;
  • exchange:交换器名称
  • isUnused:设置为 true ,则只有交换器没有被使用时,才被删除。

创建队列

Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
                             Map<String, Object> arguments) throws IOException;
  • queue:队列名称

  • durable:是否持久化

  • exclusive:是否排他;当一个队列被声明为排他队列,该队列 仅对首次声明它 的连接可见,并在连接断开时自动删除。这里需要注意一点:就算是持久化的,一旦连接关闭,这个排他队列也会被自动删除。

  • autoDelete:是否自动删除,与交换器定义一致;

  • arguments:设置队列的其他一些参数

    如 x-message-ttlx-expiresx-max-lengthx-max-length-bytesx-dead-letter-exchangex-dead-letter-routing-keyx-max-priority

删除队列

Queue.DeleteOk queueDelete(String queue, boolean ifUnused, boolean ifEmpty) throws IOException;

 队列绑定交换器

Queue.BindOk queueBind(String queue, String exchange, String routingKey, Map<String, Object> arguments) throws IOException;
  • queue:队列名
  • exchange:交换器名称
  • routingKey:用来绑定队列和交换器的路由键
  • arguments:定义绑定的一些参数

交换器与交换器绑定

Exchange.BindOk exchangeBind(String destination, String source, String routingKey, Map<String, Object> arguments) throws IOException;

 发送消息

void basicPublish(String exchange, String routingKey, boolean mandatory, BasicProperties props, byte[] body)
    throws IOException;
  • exchange:交换器名称,如果为空,则会发送到 RabbitMQ 默认的交换器中
  • routingKey:路由键
  • mandatory:mandatory 参数设为 true 时,交换器无法根据自身的类型和路由键找到一个符合条件的队列,那么 RabbitMQ会调用 Basic.Return 命令将消息返回给生产者 。当 mandatory
    数设置为 false 时,出现上述情形,则消息直接被丢弃那么生产者如何获取到没有被正确路由到合适队列的消息呢?这时候可以通过调用channel addReturnListener 来添加 ReturnListener 监昕器实现。
  • props:消息的基本属性集

消费消息

RabbitMQ 消费模式分两种:

  • Push:推模式;采用 Basic.Consume 进行消费

  • Pull:拉模式;则使用 Basic.Get 进行消费

消息分发

当RabbitMQ 队列拥有多个消费者时 ,队列收到的消息将以轮询 (round-robin )的分发方式发送给消费者。每条消息只会发送给订阅列表里的一个消费者。这种方式非常适合扩展,而且它是专门为并发程序设计的。如果现在负载加重,那么只需要创建更多的消费者来消费处理消息即可。

默认情况下,如果有 个消费者,那么 RabbitMQ会将第 条消息分发给第 m%n (取余的方式)个消费者, RabbitMQ 不管消费者是否消费并己经确认 (Basic.Ack) 了消息。

如果某些消费者任务繁重,来不及消费那么多的消息,而某些其他消费者由于某些原因很快地处理完了所分配到的消息,进而进程空闲,这样就会造成整体应用吞吐量的下降。

这里就要用到 channel.basicQos(int prefetchCount) 这个方法,channel.basicQos 方法允许限制信道上的消费者所能保持的最大未确认消息的数量。例如在订阅消费队列之前,消费端程序调用了 channel.basicQos(5) ,之后订阅了某个队列进行消费。 RabbitMQ会保存一个消费者的列表,每发送一条消息都会为对应的消费者计数,如果达到了所设定的上限,那么 RabbitMQ 就不会向这个消费者再发送任何消息。直到消费者确认了某条消息之后 RabbitMQ 将相应的计数减1,之后消费者可以继续接收消息,直到再次到达计数上限。

Basic.Qos 的使用对于拉模式的消费方式无效.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2106519.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TP5发送邮件功能如何实现?怎么配置服务?

TP5发送邮件性能优化如何优化&#xff1f;怎么使用TP5发送邮件&#xff1f; 在现代Web开发中&#xff0c;TP5框架因其高效和灵活性而广受欢迎。无论是用于用户注册验证、密码重置还是定期通知&#xff0c;TP5发送邮件功能都能提供强大的支持。AokSend将详细介绍如何在TP5框架中…

开放式耳机和骨传导耳机哪个好?2024年开放式耳机排行榜10强

随着耳机市场的不断发展&#xff0c;开放式耳机和骨传导耳机逐渐成为两大热门选择。无论是追求高音质还是重视佩戴舒适度&#xff0c;消费者在选购耳机时都面临着一个重要问题&#xff1a;开放式耳机和骨传导耳机到底哪个更好&#xff1f;今天我们就来深入对比这两种耳机的优缺…

顶会最高分的文章怎么写?基于CNN的时间序列新SOTA就是最好的答案!

【时间序列CNN】&#xff08;卷积神经网络&#xff09;在近年来的深度学习领域中备受关注&#xff0c;它通过将卷积神经网络应用于时间序列数据&#xff0c;显著提升了模型在特征提取和模式识别任务中的表现。时间序列CNN技术已经在金融预测、健康监测和工业设备故障检测等多个…

竟然有50万个使用Flutter开发的应用了,这也太牛了!

近期工作比较清闲&#xff0c;在Flutter和React Native两者中犹豫学习哪个&#xff0c;做了不少功课&#xff0c;最终决定入手Flutter。原因很简单&#xff0c;感觉Flutter更有前景&#xff0c;另外B站也找到了适合自己学习的Flutter免费教程&#xff0c;天时地利人和&#xff…

进程的那些事——了解进程(虚拟地址空间)

目录 前言 一、程序地址空间&#xff08;虚拟地址空间&#xff09; 二、虚拟地址寻找物理内存 1.页表 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 程序和进程之间的区别&#xff1a; 进程&#xff1a;对用户而言&#xff0c;进程是运行中的…

写卡片可以成为专家吗?

前一段&#xff0c;一位同学问我&#xff1a; 写小卡片记录巅峰&#xff0c;积少成多就一定能成为行业专家了吗&#xff1f; 我的观点如下&#xff1a; 想成为行业专家&#xff0c;我认为要有两类卡片&#xff1a; 1. 对同行专家知识学习后&#xff0c;所写的卡片。比如&am…

【专项刷题】— 字符串

1、最长公共前缀 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 解法一&#xff1a;两两比较字符串解法二&#xff1a;比较每一个字符串的同一位图解&#xff1a;代码&#xff1a; class Solution {public String longestCommonPrefix(String[] strs) {String ret …

北京精诚博爱医院简介

北京精诚博爱医院位于北京市朝阳区崔各庄乡南皋路188号&#xff0c;地处东北五环外&#xff0c;毗邻首都机场高速&#xff0c;与北京798艺术区和草场地艺术区隔窗相望&#xff0c;交通便捷。是一所以医疗、康复、预防保健为一体综合性医保定点医院。 医院为国家呼吸临床中心医联…

旺店通ERP集成用友NC(用友NC主供应链)

源系统成集云目标系统 用友NC介绍 用友NC是用友NC产品的全新系列&#xff0c;是面向集团企业的世界级高端管理软件。它以“全球化集团管控、行业化解决方案、全程化电子商务、平台化应用集成”的管理业务理念而设计&#xff0c;采用J2EE架构和先进开放的集团级开发平…

基于Java的在线文献检索系统

基于springbootvue实现的在线文献检索系统&#xff08;源码L文ppt远程调试&#xff09;4-027 第4章 系统设计 4.1 总体功能设计 一般个人用户和管理者都需要登录才能进入在线文献检索系统&#xff0c;使用者登录时会在后台判断使用的权限类型&#xff0c;包括一般使用者…

C# NX二次开发-获取体全部面

使用 UF_MODL_ask_body_faces 或获取一个体的全部面&#xff1a; 代码&#xff1a; theUf.Modl.AskBodyFaces(body.Tag, out var face_list);face_list.Foreach(x > x.NxListing()); 免责声明&#xff1a; 只用于参考&#xff0c;如果有什么问题不要找我呀。

【Google Play】携程旅行8.71.6最新国际版(如何鉴别是否官方?)

作为业内权威的在线旅游服务公司&#xff0c;携程旅行手机客户端提供中国境内超过11万家酒店和公寓的选择&#xff0c;海外则有超过70万家酒店可供预订。覆盖所有国内航线机票以及大部分主流国际航线&#xff0c;国内火车票全覆盖&#xff0c;长途汽车票则涵盖了500多个城市的2…

Tauri应用开发实践指南(6)— Tauri 主题多语言设置开发

前言 在现代应用开发中,用户界面的主题和多语言支持是提升用户体验的关键因素。本文将介绍如何在Tauri应用中实现窗口主题设置和多语言设置的开发,并提供更多实用的技巧和最佳实践。 我们在上一节中实现了集成本地数据库的操作&#xff0c;现在通过这个能力再实现主题&多…

分布式微服务项目mysql不同数据库之间跨库联查,使用快捷表实现跨库分页查询

场景: 在分布式微服务项目中,经常有需要关联查询其他表信息的业务,但分布式项目中分库是肯定的,不同服务的数据库服务可能部署在不同的机器上,以下是几种跨库联查分页的几种解决方式 一、快捷表联查【推荐】 1、联合与被联合的数据库服务 FEDERATED 引擎都要开启…

Cpp学习手册-基础学习

首先你要去网上下载对应的运行软件&#xff0c;先把对应的 C 环境配置好&#xff0c;配置好了我们就可以开始我们的C 学习之旅了。希望通过学习我们能够成为一个比较不错的 C 开发工程师。我也会持续更新 C 知识。 1. C语法基础 当我通过 CLion 工具创建了一个新的 Project 。…

linux(ubuntu)安装QT-ros插件

Linux下的qt安装ros插件 查看qt版本和对应的ros插件版本查看qt版本查看 qt creator 版本 qt creator进行更新升级下载版本对应的ros_qtc_plugin 插件插件安装安装成功 查看qt版本和对应的ros插件版本 想要qt与ros联合开发&#xff0c;我门需要在qt creator中添加ros的插件&…

髓鞘少突胶质细胞糖蛋白;MOG 35-55 ;CAS:149635-73-4

【MOG35-55 简介】 髓鞘少突胶质细胞糖蛋白&#xff08;Myelin Oligodendrocyte Glycoprotein&#xff0c;MOG&#xff09;是一种在中枢神经系统中表达的糖蛋白&#xff0c;主要由少突胶质细胞产生&#xff0c;并在髓鞘形成中发挥作用。 【中文名称】髓鞘少突胶质细胞糖蛋白 …

day43(9/4)——k8s

一、前期准备 1、配置主机映射 [rootk8s-master ~]# vim /etc/hosts 192.168.8.168 k8s-master 192.168.8.176 k8s-node1 192.168.8.177 k8s-node2 [rootk8s-master ~]# ping k8s-master 2、配置yum源 [rootk8s-master yum.repos.d]# vim kubernetes.repo [kubernetes…

山东大学机试试题合集

&#x1f370;&#x1f370;&#x1f370;高分篇已经涵盖了绝大多数的机试考点&#xff0c;由于临近预推免&#xff0c;各校的机试蜂拥而至&#xff0c;我们接下来先更一些各高校机试题合集&#xff0c;算是对前边学习成果的深入学习&#xff0c;也是对我们代码能力的锻炼。加油…

SQL通用语法、SQL分类以及DDL

1.SQL 1.1SQL通用语法 1.SQL语句可以单行或多行书写&#xff0c;以分号结尾2.SQL语句可以使用空格/缩进来增强语句的可读性。3.MySQL数据库的SQL语句不区分大小写&#xff0c;关键字建议使用大写。4.注释&#xff1a; 单行注释&#xff1a;–空格 注释内容或#注释内容&#…