RabbitMQ详解

一、基本概念

RabbitMQ是一个开源的遵循AMQP协议实现的基于Erlang语言编写,支持多种客户端(语言)。用于在分布式系统中存储消息,转发消息,具有高可用,高可扩性,易用性等特征。
官网:https://www.rabbitmq.com/

二、安装

此文章只记录Docker安装方式

// 获取镜像
docker pull rabbitmq:management
// 创建运行容器
docker run -di --name myrabbit -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -p 15672:15672 -p 5672:5672 -p 25672:25672 -p 61613:61613 -p 1883:1883 rabbitmq:management

运行成功后,浏览器访问http://ip:15672/ 查看是否启动成功
此处需注意,如果使用的是阿里云等云服务器,请别忘记开放端口

三、核心概念

Broker :也就是安装的rabbitmq服务
Connection:连接,应用程序与Broker的网络连接 TCP/IP
Channel:网络信道,几乎所有的操作都在Channel中进行,Channel是进行消息读写的通道,客户端可以建立对各Channel,每个Channel代表一个会话任务。
Message:消息,服务与应用程序之间传送的数据,由Properties和body组成,Properties可是对消息进行修饰,比如消息的优先级,延迟等高级特性,Body则就是消息体的内容。
Virtual Host:虚拟地址,用于进行逻辑隔离,最上层的消息路由,一个虚拟主机理由可以有若干个Exhange和Queueu,同一个虚拟主机里面不能有相同名字的Exchange
Exchange:交换机,接受消息,根据路由键发送消息到绑定的队列,所有消息的均是投递给交换机,最终由交换机转发给队列!!!
Bindings:Exchange和Queue的绑定关系,绑定后,交换机转发消息的时候才能转发到已绑定的队列中。
Routing key:是一个路由规则,虚拟机可以用它来确定如何路由一个特定消息,简单来说就是将消息转发给队列的时候进行一下判定,符合此路由的才进行转发,不符合的就不转发。
Queue:消息队列,保存消息,然后由消费者监听进行消费

四、工作模式

图片来自官网:https://www.rabbitmq.com/getstarted.html

图片来自官网:https://www.rabbitmq.com/getstarted.html
就挑下面几种进行解释:

4.1.简单模式

简单模式顾名思义,很简单,发布者,队列,消费者,发布者发送后直接交给默认交换机,交换机转发给队列,然后消费者消费

4.2.fanout模式

fanout也就是最简单的发布订阅模式,此模式将N个队列绑定此模式的交换机后,交换机直接会将消息全部转发给所绑定队列,哪怕你设置了RoutingKey也不生效

4.3.direct模式

direct也是一种发布订阅模式,只不过添加了RoutingKey的概念,你可以将队列绑定交换机的时候指定好对应的RoutingKey,那么交换机转发消息的时候会去判断发送消息所携带的RoutingKey是否与队列绑定的RoutingKey匹配,匹配才会转发到对应的队列

4.4.topic模式

topic是对direct模式的增强版,也就是对RoutingKey进行了增强,增加了模糊匹配的功能,如有两个队列,a队列绑定的RoutingKey设置为*.topic.#,b队列绑定的为#.topic.**,此处注意 * 代表有且仅有一个且必须得有一个,#代表是可有可无,可以有多个也可以一个没有,如果发布者发送的消息绑定的key为topic.test,那么这条消息只会转发给b队列,因为a队列的key前面匹配符为*,那么也就是要求必须拥有一个,没有则不匹配,不进行转发,如果发送者发送的消息绑定的key为test.topic,那么相应的也就是转发给a队列,而不转发给b队列,如果绑定的为test.topic.test,那a,b队列均可收到

4.5.Work模式

当一个队列有多个消费者监听消费的时候,该如何进行分发?
1.平均主义 : 平均主义就是不管消费者的消费能力,一人一条
2.能者多劳 : 能者多劳就是你消费的快,你就多消费几条,能者多老的实现的方式就是设置手动应答

五、高级特性

5.1.TTL(过期时间)

TTL可以对消息设置过期时间,在过期时间内可以被消费者获取;超过期限自动被删除。RabbitMQ可以对消息和队列设置TTL。
第一是可以通过队列属性设置,队列中所有消息都有相同的过期时间。 第二是可以对消息进行单独设置,每条消息TTL可以不同。
如果两种方法同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,可以设置死信队列,那么过期的消息可以投递到死信队列,消费者将无法再收到该消息。

5.2.死信队列

死信队列其实就是普通队列,只不过是就是队列的一种属性,当队列有异常投递的消息时,会将消息转发到此队列,所以又被称为死信队列,也就是死了的信息,要想使用死信队列,只需要在定义队列的时候设置队列参数 x-dead-letter-exchange 指定交换机即可。 消息变成死信,可能是由于以下的原因:
1.消息被拒绝
2.消息过期
3.队列达到最大长度

5.3.消息确认机制

server:
  port: 8080
spring:
  rabbitmq:
    username: "test"
    password: "test"
    virtual-host: /
    host: ip
    port: 5672
    publisher-confirm-type: correlated
    // publisher-confirm-type有NONE、CORRELATED、SIMPLE几种值
    // NONE值是默认值,禁用发布确认模式
    // CORRELATED值是开启发布确认模式,成功提交到交换器后会触发回调方法
    // SIMPLE值经测试有两种效果,其一效果和CORRELATED值一样会触发回调方法,其二在发布消息成功后使用rabbitTemplate调用waitForConfirms或waitForConfirmsOrDie方法等待broker节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是waitForConfirmsOrDie方法如果返回false则会关闭channel,则接下来无法发送消息到broker
public class MsgConfirmCallback implements RabbitTemplate.ConfirmCallback {
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if(ack){
            // 成功
        }else{
           // 失败
        }
    }
}

六、分布式可靠性保障

首先说到可靠性,rabbitmq的可靠性分为两部分,一是要保障可靠生产,二是保障可靠消费。二者实现方式不同。

简单来说可靠生产可以用冗余数据的存储+定时任务实时轮询查取进行处理,也就是将投递给MQ的数据在发送的同时存库,然后开启消息投递成功确认机制,这样如果投递成功,MQ返回回调,然后更新冗余库中的数据状态为发送成功。如果没有投递成功,那么定时任务查询,将未发送成功的数据进行重试,如果重试次数超过阈值,可以进行人工排错处理。

简单来说可靠消费可以用手动ack+try catch拒绝策略+死信队列进行处理(此处注意,如果使用try catch拒绝策略中重发设置为true,那么将造成MQ重发死循环)

如下所示:

@RabbitListener(queues = {"queue"})
public void consumer(String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) {
    try {
        // 获取消息
        System.out.println("消息:"+ msg);
        1 / 0; //故意设置出现异常
		// 手动ack
        channel.basicAck(tag, false);
    } catch (Exception ex) {
		// 出现异常后,拒绝,此时消息队列会将数据丢掉,如果业务可以允许丢掉,那无所谓
		// 但是如果不允许,那么添加死信队列,将数据投递到死信队列中
		// 参数1为消息的tag  参数2为是否多条处理 参数3为是否重发
		// 如果在try catch中设置为重发,那么会造成死循环,所以一般不要这么设置
		// 如果需要失败重试,并且专门配置了失败重试次数,那么就不要用try catch,二者不可兼容,切记!!!
        channel.basicNack(tag, false, false);
    }
}

七、需要注意的小细节

1.如果队列已存在,如果直接不删除,就代码动态更改队列参数,会报错,需要修改队列参数的时候,请先删除再重新创建
2.如何所有连接均处于blocking状态,所有服务均被挂起,一般都是磁盘或者内存满了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ是一个开源的消息代理软件,它实现了高级消息队列协议(AMQP)并提供可靠的消息传递机制。它可以用于构建分布式系统,处理大量的消息传递和异步通信。以下是关于RabbitMQ的一些详解: 1. 下载和安装:你可以从RabbitMQ官方网站下载RabbitMQ的安装包。你可以使用wget命令下载RabbitMQ的rpm包,例如:wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/rabbitmq-server-3.6.10-1.el7.noarch.rpm。安装完成后,你可以双击安装包进行安装。安装完成后,你可以运行rabbitmq-plugins enable rabbitmq_management命令来安装RabbitMQ-Plugins插件。然后,你可以运行rabbitmq-server.bat来启动RabbitMQ服务。\[1\]\[2\] 2. 后台运行:如果你想在后台运行RabbitMQ,你可以使用rabbitmq-server -detached命令来启动RabbitMQ服务。如果你想停止RabbitMQ服务,你可以使用rabbitmqctl stop命令。\[3\] 总结起来,RabbitMQ是一个功能强大的消息代理软件,它可以用于构建分布式系统和处理大量的消息传递。你可以通过下载和安装RabbitMQ来开始使用它,并且可以选择在前台或后台运行RabbitMQ服务。 #### 引用[.reference_title] - *1* *2* [RabbitMQ详解,用心看完这一篇就够了【重点】](https://blog.csdn.net/weixin_42039228/article/details/123493937)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [RabbitMQ 详解](https://blog.csdn.net/m0_53067943/article/details/130578563)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值