- 方法
- MQ中丢失
- 步骤
- 消费端丢失
RabbitMQ开发20200219总结
URI的规范的百分比编码
背景
RabbitMQ使用URI方式代替host,port,virtualhost,username,password等参数方式时,设置virtual host 为"/" 的时候,直接这样写会报错,所以进行查阅资料
解决过程
首先查阅RabbitMQ官网,查看相关资料,官网中说明了,"/" 需要使用百分比编码
第一次听说这种编码,然后又进行查阅URI的百分比编码,果然看到 /->%2F
代替
在查阅官网中,再次进行验证得到答案,所以应该就是这样没错了。
RabbitMQ如何保证消息的可靠性传递,要是消息丢失如何处理
方法
数据的丢失问题,可能出现在生产者,MQ,消费者中
生产者丢失: 生产者将数据发送到RabbitMQ的时候,可能数据在半路搞丢,RabbitMQ提供了事务功能,在生茶这发送数据之前开启RabbitMQ事务channel.txSelect,然后发送消息,如果没有被成功接收到,生产者就会收到异常报错,此时就可以回滚事务channel.txRollback
,然后重试,如果收到消息,那么就可以提交事务channel.txCommit
事务的缺点:性能消耗太大
改进
开启confirm模式,在生产者开启confirm模式之后,你每次写的消息都会分配一个唯一的id, 如果写入RabbitMQ中,RabbitMQ会给你回传一个ack消息,如果RabbitMQ没能处理这个消息,回调传一个nack接口,告诉你消息接受失败,可以重试,而且可以结合这个机制自己在内存中维护每个消息id的状态,如果超过一定时间还没接收到消息的回调,可以重发
比较
事务机制是同步的,你提交一个事物之后会在阻塞在那里,但是confim
机制是异步的,你发这个消息之后就可以发送下一个消息,然后这个消息RabbitMQ接收到了之后会异步回调通知你这个消息接收到了,所以一般在生产者那块避免数据丢失,都是用confirm机制的
MQ中丢失
RabbitMQ自己丢失了数据,这个必须开启RabbitMQ的时就华,消息写入之后会持久化到磁盘,哪怕RabbitMQ挂掉,也可以自动读取之前存储的数据
步骤
- 创建queue的时候设置持久化,可以保证RabbitMQ持久化queue元数据
- 发送消息的时候讲消息的deliveryMode设置为2, 消息设置为持久化的
消费端丢失
关闭自动的ack,通过一个api调用就行,每次在自己的代码中确保处理完的时候,再在程序里ack一下
消费端丢失:你消费的时候,刚消费到,还没处理,结果进程挂了,比如重启了,那么就尴尬了,RabbitMQ 认为你都消费了,这数据就丢了。这个时候得用 RabbitMQ 提供的ack机制,简单来说,就是你关闭 RabbitMQ 的自动ack,可以通过一个 api 来调用就行,然后每次你自己代码里确保处理完的时候,再在程序里ack一把。这样的话,如果你还没处理完,不就没有ack?那 RabbitMQ 就认为你还没处理完,这个时候 RabbitMQ 会把这个消费分配给别的 consumer 去处理,消息是不会丢的。
定时任务
RabbitMQ使用URI方式设置资源
背景
代码中原本使用host,port,virtualhost,username,password等设置RabbitMQ资源,但是如果存储在已有的表结构中,没有涉及这么多的字段,就因此查看是否有好的办法,不用涉及如此多的字段
解决方法
使用URI方式
可以代替很多参数,只需要一个字段即可满足所有需求,所以就是用了这种方式
注: 如果virtual host 是"/"的话,官网中有说,需要使用百分制编码,也就是%2f替代,图中其实也有对应的,可以仔细看下