热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一文了解消息中间件RabbitMQ

消息中间件---RabbitMQ1消息中间件的作用2.常用的消息中间件3消息中间件RabbitMQ3.1RabbitMQ介绍3.3RabbitMQ的队列模式3.3RabbitMQ的

消息中间件---RabbitMQ

  • 1 消息中间件的作用
  • 2. 常用的消息中间件
  • 3 消息中间件RabbitMQ
    • 3.1 RabbitMQ介绍
    • 3.3 RabbitMQ的队列模式
    • 3.3 RabbitMQ的工作模式
  • 4 RabbitMQ集群
    • 4.1 节点类型
    • 4.2 普通集群
    • 4.3 镜像模式
    • 4,4 远程模式(shovel)
    • 4.5 多活模式
  • 5 Rabbitmq的确认机制
    • 5.1 自动ack
    • 5.2 手动ack


1 消息中间件的作用

消息中间件作用有三个:异步处理消息、降低耦合度、流量削峰。

2. 常用的消息中间件

当前使用较多的消息队列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ等,而部分数据库如Redis、MySQL以及phxsql也可实现消息队列的功能

在这里插入图片描述

3 消息中间件RabbitMQ

3.1 RabbitMQ介绍

RabbitMQ是采用erlang语言开发的,必须有erlang环境才可以运行。RabbitMQ是一个遵循AMQP协议的消息中间件,它从生产者接收消息并递送给消费者,在这个过程中,根据规则进行路由,缓存与持久化。

3.2 RabbitMQ的基本介绍
在这里插入图片描述

  1. producer:消息生产者,就是投递消息的程序;

  2. Message:由生产者通过RabbitMQ发送给消费者的信息(路由键(Routing Key)是供交换机查看并根据键来决定如何分发消息到列队的一个键。路由键可以说是消息的目的地址);

  3. 连接(Connection):连接RabbitMQ和应用服务器的TCP连接;

  4. 信道(Channel):消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务;

    为什么不通过TCP直接发送命令: 创建和销毁TCP会话是非常昂贵的开销,信道的原理是一条线程一条信道,多条线程多条信道共同使用一条TCP连接,每个信道的ID唯一;

  5. 绑定(Binding):绑定是队列和交换机的一个关联连接;

  6. Exchange:通过routingkey和队列绑定在一起的,如果消息拥有的“路由键”跟队列和交换器的“路由键”匹配,那么消息就会被路由到该绑定的队列当中去;

    Exchange的类型:
    (1)fanout:消息会被转发到所有与交换机绑定队列;
    (2)direct:精确匹配Routing key和routing key;
    (3)topic:模糊匹配Routing key和routing key

  7. 队列(Queue):存储消息的缓存;

  8. Consumer:处理消息;
    消费模式:

(1)pull:消费者主动拉取消息

优点:客户端可以依据自己的消费能力进行消费 ;传输失败时不需要重试,反正数据还在服务端。
缺点:消息的实时性难以实现;
场景:服务端生产消息数据比较大时,而消费端处理比较复杂,消费能力相对较低。

(2)push:服务端主动推送消息给客户端

优点:服务端主动推送给客户端,实时性很高;
缺点:当客户端消费能力远低于服务端生产能力,那么一旦服务端推送大量消息到 客户端时,就会导致客户端消息堆积,处理缓慢,甚至服务崩溃;
服务端需要维护每次传输状态,以防消息传递失败进行重试。
场景:适合用于数据实时性要求高的场景

3.3 RabbitMQ的队列模式


  1. 普通队列
    非持久化消息:消息存储在内存之中;持久化的消息:存储在磁盘中;
    适用场景:消息量不是很大的情况
  2. 镜像队列
    消息发送到队列时,如果队列是镜像队列,会将队列镜像到cluster中其他的节点之上;
    对于持久化的消息,会在内存和磁盘中各存一份。
    缺点:镜像队列不能实现负载均衡;对exclusive队列设置镜像并不会有任何作用。

在这里插入图片描述
队列结构:是一个特殊的BackingQueue,它内部包裹了一个普通的BackingQueue做本地消息持久化处理,增加了将消息和ack复制到所有镜像的功能。所有对mirror_queue_master的操作,会通过组播GM的方式同步到各slave节点。GM负责消息的广播,mirror_queue_slave负责回调处理,而master上的回调处理是由coordinator负责完成。mirror_queue_slave中包含了普通的BackingQueue进行消息的存储,master节点中BackingQueue包含在mirror_queue_master中由AMQQueue进行调用。

  1. exclusive队列

    只对首次声明它的连接可见;
    会在其连接断开的时候自动删除;

  2. lazy队列
    优点:尽可能的将消息存储到磁盘中,在消费者消费到相应的消息时才会被加载到内存中,占用内存少;
    缺点:存在队列的单点故障;
    使用场景:发送端过快或消费端宕机,导致消息大量积压,在消息大爆发的时候,MQ服务器会撑不住,影响其他队列的消息收发。

  3. 死信队列
    死信消息如何形成的:
    (1)消息被否定确认;
    (2)消息在队列的存活时间超过设置的TTL时间;
    (3)消息队列的消息数量已经超过最大队列长度。
    死信队列:如果配置了死信队列信息,那么该消息将会被丢进死信队列中;如果没有配置,则该消息将会被丢弃。
    场景:故障发生时,让未正确处理的消息存放到死信队列中,待后续排查清楚问题后,处理死信消息。

  4. 延迟队列
    场景:实现定时任务
    实现方式:
    (1)延迟插件;
    (2)ttl+死信队列:消息过期时间/队列过期时间,如果同时设置队列和消息过期时间,较小的生效。


3.3 RabbitMQ的工作模式


  1. 简单模式:一个生产者,一个消费者,一个队列。
  2. 工作模式:一个生产者对应多个消费者,但是一条消息只能被一个消费者获取。
  3. 发布订阅模式:一个消费者将消息首先发送到交换器,交换器绑定到多个队列,然后被监听该队列的消费者所接收并消费。
  4. 路由模式:使用的是type为direct的交换机,让消费者有选择性的接收消息。
  5. 主题模式:使用type为topic的交换机

4 RabbitMQ集群

4.1 节点类型

磁盘节点:配置信息和元信息存储在磁盘上,至少一个磁盘节点。如果唯一磁盘的磁盘节点崩溃,集群是可以保持运行的,但不能更改任何东西,集群中最好设置两个磁盘节点。

内存节点:配置信息和元信息存储在内存中, 性能好;

4.2 普通集群

默认普通队列,集群仅采用元数据同步。仅同步元数据的原因:存储空间和性能。

特点:
(1)master存储队列的元数据信息和消息;
(2)slave只同步队列元数据信息,不会同步存储消息;
(3)master(读写),slave(不提供读写)作为路由节点起到转发作用;

缺点:master节点故障后,slave节点无法取到master节点中还未消费的消息实体。如果做了消息持久化,等master节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象;

4.3 镜像模式


  1. 把需要的队列做成镜像队列,master会将队列镜像到cluster中其他的slave节点之上。逻辑上的master和slave,相对于主队列而言。

  2. 特点:

    (1)消息的发布与消费都是通过master节点完成,master通过 mirror 队列把消息数据同步到其他的 slave 节点,对于持久化的消息会在磁盘和内存中各存一份;
    (2)除publish外所有动作都只会向master发送,然后由master将命令执行的结果广播给slave;
    (3)master节点故障后,集群中最老的slave被提升为master;slave节点故障后,仅仅是相邻节点感知,然后重新调整邻居节点信息。

  3. 镜像队列 gm:

    通过将所有 gm 进程形成一个循环链表,每个 gm 都会监控位于自己左右两边的 gm,当有 gm 新增时,相邻的 gm 保证当前广播的消息会通知到新的 gm 上;当有 gm 失效时,相邻的 gm 会接管保证本次广播消息会通知到所有 gm。

  4. 镜像队列的消息广播流程:

    (1)Master 节点发出消息,顺着镜像队列循环列表发送;
    (2)所有 Slave 节点收到消息会对消息进行缓存(Slave 节点缓存消息用于在广播过程中,有节点失效或者新增节点,这样左侧节点感知变化后会重新将消息推送给右侧节点);
    (3)当 Master 节点收到自己发送的消息后意味着所有节点都收到了消息,会再次广播 Ack 消息;
    (4)Ack 消息同样会顺着循环列表经过所有 Slave 节点,通知 Slave 节点可以清除缓存消息;
    (5)当 Ack 消息回到 Master 节点,对应消息的广播结束。

  5. 优点:(1)保证 100% 数据不丢失; (2)消除普通模式中队列消息单点带来的风险;

  6. 缺点:降低系统性能,集群内部的同步通讯会占用大量的网络带宽


4,4 远程模式(shovel)

远程模式可以实现双活的一种模式,简称 shovel 模式,所谓的 shovel 就是把消息进行不同数据中心的复制工作,可以跨地域的让两个 MQ 集群互联,远距离通信和复制。
Shovel 把消息进行数据中心的复制工作,可以跨地域的让两个 MQ 集群互联。
在这里插入图片描述

原理:使用shovel插件实现,通过定义RabbitMQ上一个队列和另外一个RabbitMQ上的交换机之间的复制关系来实现远程复制。它会在主服务上建立一个队列来监听交换机,所有到交换机的消息会投递到该队列,并且在从服务中订阅这个队列,使队列中的消息复制到从服务的交换机中。优点:异地的 MQ 集群,近端同步确认,远端异步确认;缺点:配置比较复杂

4.5 多活模式

federation 插件是一个不需要构建 cluster ,而在 brokers 之间传输消息的高性能插件,federation 插件可以在 brokers 或者 cluster 之间传输消息,连接的双方可以使用不同的 users 和 virtual hosts,双方也可以使用不同版本的 rabbitMQ 和 erlang。federation 插件使用 AMQP 协议通信,可以接受不连续的传输。在这里插入图片描述

federation 插件实现,只配置两个集群中两个单点队列之间的复制,每个集群内部自己会完成多节点的同步(镜像队列来完成)。

优点:Federation插件可以在Brokers或者Cluster之间传输消息,连接双方可以使用不同的users和vistual hosts; 双方也可以使用版本不同的RabbitMQ和Erlang。

5 Rabbitmq的确认机制

rabbitmq发出消息后会等待consumer端应答,只有收到ack确定信息后才会将消息在rabbitmq清除掉。

5.1 自动ack

(1)autoAck=true;
(2)消息一旦被接收,消费者自动发送ACK;

对于自动确认来说,当方法没有异常执行完毕后,会对MQ发出ACK;若方法出现异常,会对MQ发出nack,消息会重回队列。

场景:消息不太重要,丢失也没有影响

5.2 手动ack

保证数据不被重复消费,同时数据也不能少,也就是数据一致性。
(1)关闭自动ack:autoAck=false;
(2)消息接收后,不会自动发送ACK,需要手动调用

场景:消息非常重要,异常发生不会丢数据。

如果重复ack(自动ack的同时开启手动ack)会造成造成消息丢失


推荐阅读
  • 本文提供了 RabbitMQ 3.7 的快速上手指南,详细介绍了环境搭建、生产者和消费者的配置与使用。通过官方教程的指引,读者可以轻松完成初步测试和实践,快速掌握 RabbitMQ 的核心功能和基本操作。 ... [详细]
  • 本文详细介绍了HDFS的基础知识及其数据读写机制。首先,文章阐述了HDFS的架构,包括其核心组件及其角色和功能。特别地,对NameNode进行了深入解析,指出其主要负责在内存中存储元数据、目录结构以及文件块的映射关系,并通过持久化方案确保数据的可靠性和高可用性。此外,还探讨了DataNode的角色及其在数据存储和读取过程中的关键作用。 ... [详细]
  • 本文探讨了使用Python实现监控信息收集的方法,涵盖从基础的日志记录到复杂的系统运维解决方案,旨在帮助开发者和运维人员提升工作效率。 ... [详细]
  • 本文介绍了MySQL窗口函数的基本概念、应用场景及常见函数的使用方法。窗口函数在处理复杂查询时非常有用,例如计算每个用户的订单排名、环比增长率、以及动态聚合等。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • CentOS下ProFTPD的安装与配置指南
    本文详细介绍在CentOS操作系统上安装和配置ProFTPD服务的方法,包括基本配置、安全设置及高级功能的启用。 ... [详细]
  • 本文详细介绍了在Linux操作系统上安装和部署MySQL数据库的过程,包括必要的环境准备、安装步骤、配置优化及安全设置等内容。 ... [详细]
  • 修复一个 Bug 竟耗时两天?真的有那么复杂吗?
    修复一个 Bug 竟然耗费了两天时间?这背后究竟隐藏着怎样的复杂性?本文将深入探讨这个看似简单的 Bug 为何会如此棘手,从代码层面剖析问题根源,并分享解决过程中遇到的技术挑战和心得。 ... [详细]
  • DHCP三层交换机设置方式全局模式和接口模式设置方式和命令resetsave回车输入yreboot输入n输入y重启后就恢复默认设置了默认用户名密码adminAdmin@huawei ... [详细]
  • 1、编写一个Java程序在屏幕上输出“你好!”。programmenameHelloworld.javapublicclassHelloworld{publicst ... [详细]
  • 本文提供了处理WordPress网站中出现过多重定向问题的方法,包括检查DNS配置、安装SSL证书以及解决数据库连接错误等步骤。 ... [详细]
  • 本文回顾了作者在求职阿里和腾讯实习生过程中,从最初的迷茫到最后成功获得Offer的心路历程。文中不仅分享了个人的面试经历,还提供了宝贵的面试准备建议和技巧。 ... [详细]
  • 解决ADODB连接Access时出现80004005错误的方法
    本文详细介绍了如何解决在使用ADODB连接Access数据库时遇到的80004005错误,包括错误原因分析和具体的解决步骤。 ... [详细]
  • binlog2sql,你该知道的数据恢复工具
    binlog2sql,你该知道的数据恢复工具 ... [详细]
  • 本文详细解析了MySQL中常见的几种错误,并提供了具体的解决方法,帮助开发者快速定位和解决问题。 ... [详细]
author-avatar
生活碎事_780
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有