RabbitMQ知识点

rabbitmq基础

一、作用

削峰、异步、解耦

二、6种模式

简单队列、工作队列、发布订阅、路由模式、主题模式、RPC模式

三、交换机类型

1.direct Exchange(直接交换机)【路由交换机】
匹配路由键,只有完全匹配消息才会被转发

2.Fanout Excange(发布订阅交换机)
将消息发送至所有的队列

3.Topic Exchange(主题交换机)
将路由按模式匹配,此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“匹配不多不少一个词。因此“abc.#”能够匹配到“abc.def.ghi”,但是“abc.” 只会匹配到“abc.def”。

4.Header Exchange
在绑定Exchange和Queue的时候指定一组键值对,header为键,根据请求消息中携带的header进行路由

四、发布确认(confirm)

目的:确保生产者发送消息的过程中,消息不丢失

单个发布确认、批量发布确认、异步发布确认(推荐)

五、死信队列

死信来源:1、消息TTL过期 2、队列到达最大长度 3、消息被拒绝
应用场景:为确保消息不丢失,需使用死信队列机制。

六、延迟队列

是用来存放需要在指定时间被处理的元素的队列。
应用场景:
1、订单在半小时之内未支付则自动取消
2、用户注册成功后,三天内未登录,则发短信提醒
3、用户发起退款,三天内平台商家没有处理,则通知平台运营人员

优点:能处理定时任务在高并发下不能处理的。

实现:
1、基于死信队列 (存在问题)
第一个消息延迟时间很长,第二个消息延迟时间很短,不会优先执行
2、基于插件

七、幂等性

目的:解决消息重复消费,在消费者实现幂等性

实现方式:
1、唯一 ID + 指纹码机制,利用数据库主键去重;
2、利用 redis 的原子性去实现。执行 setnx 命令,天然具有幂等性(推荐)

指纹码:我们的一些规则或者时间戳加别的服务给到的唯一信息码,它并不一定是我们系统生成的,基本都是由我们的业务规则拼接而来,但是一定要保证唯一性,然后就利用查询语句进行判断这个 id 是否存在数据库中,优势是实现简单,就一个拼接,然后查询判断是否重复;劣势就是在高并发下,如果是单个数据库就会有写入性能瓶颈

八、优先级队列

应用场景:订单催付的情况

九、惰性队列

保证消息的稳定性

1、消息持久化。
先对交换机、队列持久化,再对消息持久化到硬盘
2、ACK自动应答。
将ack改为false,需在消费者中手动应答。

面试题

rabbitmq如何确保消息不丢失

先分析丢失消息的几种情况
A:生产者弄丢了数据
生产者将数据发送到rabbitmq的时候,可能在传输过程中因为网络等问题而将数据弄丢了。
B:rabbitmq自己丢了数据
如果没有开启rabbitmq的持久化,那么rabbitmq一旦重启,那么数据就丢了。所依必须开启持久化将消息持久化到磁盘,这样就算rabbitmq挂了,恢复之后会自动读取之前存储的数据。
C:消费端弄丢了数据
主要是因为消费者消费时,刚消费到,还没有处理,结果消费者就挂了,这样你重启之后,rabbitmq就认为你已经消费过了,然后就丢了数据。

解决方式
A:生产者丢失消息
① 可以选择使用rabbitmq提供的事务功能,就是生产者在发送数据之前开启事务,然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会受到异常报错,这时就可以回滚事务,然后尝试重新发送;如果收到了消息,那么就可以提交事务。

  channel.txSelect();//开启事务
  try{
      //发送消息
  }catch(Exection e){
      channel.txRollback();//回滚事务
      //重新提交
  }

缺点:rabbitmq事务已开启,就会变为同步阻塞操作,生产者会阻塞等待是否发送成功,太耗性能会造成吞吐量的下降。

② 可以开启confirm模式(发布确认)。在生产者那里设置开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后写入了rabbitmq之中,rabbitmq会给你回传一个ack消息,告诉你这个消息发送OK了;如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。 (推荐confirm模式)

	//开启confirm
    channel.confirm();
    //发送成功回调
    public void ack(String messageId){
      
    }
    // 发送失败回调
    public void nack(String messageId){
        //重发该消息
    }

二者不同
事务机制是同步的,你提交了一个事务之后会阻塞住,但是confirm机制是异步的,发送消息之后可以接着发送下一个消息,然后rabbitmq会回调告知成功与否。

B:rabbitmq自己弄丢了数据
设置消息持久化到磁盘。设置持久化有两个步骤:
①创建queue的时候将其设置为持久化的,这样就可以保证rabbitmq持久化queue的数据,但是不会持久化queue里面的数据。交换机也一样
②发送消息的时候将消息的props设置属性为MessageProperties.PERSISTENT_TEXT_PLAIN,这样消息就会被设为持久化方式,此时rabbitmq就会将消息持久化到磁盘上。

C:消费者弄丢了数据
使用rabbitmq提供的ack机制,首先关闭rabbitmq的自动ack,然后每次在确保处理完这个消息之后,在代码里手动调用ack。这样就可以避免消息还没有处理完就ack。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值