RabbitMQ快速学习

简介

  • MQ全称是Message Queue,可以理解为消息队列的意思,先搞清楚几个概念

  • 在了解消息通讯之前首先要了解3个概念:生产者、消费者和代理。

生产者:消息的创建者,负责创建和推送数据到消息服务器;

消费者:消息的接收方,用于处理数据和确认消息;

代理:就是RabbitMQ本身,用于扮演“快递”的角色,本身不生产消息,只是扮演“快递”的角色。

  • 总结:消费者生产消息,发送到代理,消费者从代理获取消息

RabbitMQ重要关键词解释:

  • ConnectionFactory(连接管理器):应用程序与Rabbit之间建立连接的管理器,程序代码中使用;
  • Channel(信道):消息推送使用的通道;
  • Exchange(交换器):用于接受、分配消息;
  • Queue(队列):用于存储生产者的消息;
  • RoutingKey(路由键):用于把生成者的数据分配到交换器上;
  • BindingKey(绑定键):用于把交换器的消息绑定到队列上;

RabbitMQ角色之间如何运作

  • 消费者获取和rabbitmq的连接,然后通过信道传输消息,消息传输时我们绑定一个key在信道上,也就是路由键,这时交换机登场将消息按照路由键分类,发往和路由键匹配的队列中完成发送。

  • 这里值得注意得是
    channel只是用来与队列交互的一个东西,不能直接操作队列
    接受消息是通过channel订阅指定路由键的队列的消息
    发送一般是通过channel带上routingKey发送到指定的exchange,exchange上根据routingKey绑定queue来决定发送到什么队列
    不显式声明交换机时并且发送消息不指定交换机,则默认使用Direct交换机,并且声明队列时,不显式绑定队列与交换机,则队列以队列名为routing-key绑定到默认的direct交换机,发送消息不指定交换机时,则将消息发到默认的direct交换机

在这里插入图片描述
在这里插入图片描述

交换器分类

direct(默认)=》如果路由键匹配的话,消息就投递到相应的队列
headers
fanout=》发布/订阅模式,,当你发送一条消息的时候,交换器会把消息广播到所有附加到这个交换器的队列上,对于fanout交换器来说routingKey(路由键)是无效的,这个参数是被忽略的。
topic=》topic交换器运行和fanout类似,但是可以更灵活的匹配自己想要订阅的信息,这个时候routingKey路由键就排上用场了,使用路由键进行消息(规则)匹配。可以进行模糊匹配,这样可以更灵活的接受消息

##如何保证消息送到

  • 通过AMQP提供的事务机制实现;(事物性能差,这里不做解释)
  • 使用发送者确认模式实现;

Confirm的三种实现方式:(推荐异步确认方式

方式一:channel.waitForConfirms()普通发送方确认模式;

// 开启发送方确认模式
channel.confirmSelect();
String message = String.format("时间 => %s", new Date().getTime());
channel.basicPublish("", config.QueueName, null, message.getBytes("UTF-8"));
if (channel.waitForConfirms()) {
    System.out.println("消息发送成功" );
}

方式二:channel.waitForConfirmsOrDie()批量确认模式;

channel.confirmSelect();
for (int i = 0; i < 10; i++) {
    String message = String.format("时间 => %s", new Date().getTime());
    channel.basicPublish("", config.QueueName, null, message.getBytes("UTF-8"));
}
channel.waitForConfirmsOrDie(); //直到所有信息都发布,只要有一个未确认就会IOException
System.out.println("全部执行完成");

方式三:channel.addConfirmListener()异步监听发送方确认模式;

//异步监听确认和未确认的消息
channel.addConfirmListener(new ConfirmListener() {
    @Override
    public void handleNack(long deliveryTag, boolean multiple) throws IOException {
        System.out.println("未确认消息,标识:" + deliveryTag);
    }
    @Override
    public void handleAck(long deliveryTag, boolean multiple) throws IOException {
        System.out.println(String.format("已确认消息,标识:%d,多个消息:%b", deliveryTag, multiple));
    }
});

数据持久化

Rabbit队列和交换器有一个不可告人的秘密,就是默认情况下重启服务器会导致消息丢失,那么怎么保证Rabbit在重启的时候不丢失呢?
答案就是消息持久化。

当你把消息发送到Rabbit服务器的时候,你需要选择你是否要进行持久化,但这并不能保证Rabbit能从崩溃中恢复,想要Rabbit消息能恢复必须满足3个条件:

  • 投递消息的时候durable设置为true,消息持久化,代码:channel.queueDeclare(x, true, false, false, null)
  • 设置投递模式deliveryMode设置(持久),代码:
    channel.basicPublish(x, x, MessageProperties.PERSISTENT_TEXT_PLAIN,x)
    MessageProperties.PERSISTENT_TEXT_PLAIN设置为存储纯文本到磁盘
  • 消息已经到达持久化交换器上
  • 消息已经到达持久化的队列

参考

参考一

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值