1.RabbitMQ如何实现高用?
采用镜像集群模式,创建的queue,无论是元数据还是queue的消息都存在多个实例,每次写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。
缺点:性能消耗大
2.如何保证不被重复消费?
生成者发送数据里面添加一个全局唯一id,通过redis或set根据id查一下,看消息有没有消费过,如果没有就处理,如果有就不处理,
3.如何保证消息的可靠性传输(如何处理消息丢失的问题)?
1.如果生成者弄丢数据
采用rabbitMQ提供的事务机制,有两种事务的方式,一种是生产者发送数据之前开(channel.txselect),try,catch捕捉异常,然后回滚事务,再重试发送数据,如果收到消息了,就提交事(channel.txconmmit)这种事务机制会导致吞吐量会下来,很耗性能。同步,阻塞在那
另外一种是confirm机制,生产者开启confirm机制之后,每次写入消息都会分配唯一的id,
然后写入rabbitMQ中,消费者接收到消息后,通过handleAck方法,告诉这个消息OK了,
如果没有处理这个消息,会回调一个handleNack方法,告诉你这个消息接收失败了,可以重试你可以结合这个机制自己在内存里维护每个消息id的状态
如果超过一定时间还没接收到这个消息的回调,那么你可以重发。异步,发完消息,可以处理别的消息
2.rabbitMQ弄丢数据
开启一个rabbitMQ的持久化,将消息持久化到磁盘(redis),哪怕rabbitMQ挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢。
设置持久有两个步骤,第一个创建queue的时候将其设置持久化,这样就可以保证rabbitMQ持久化queue的元数据,但是不会持久化queue里面的数据;第二个是发送消息的时候将消息的deliveryMode设置为2,就是将消息设置为持久化。而且持久化可以跟生产者那边的confirm机制配合起来,只有消息被持久化到磁盘之后,才会通知生产者ack了,所以哪怕是在持久化到磁盘之前,rabbitmq挂了,数据丢了,生产者收不到ack,你也是可以自己重发的。
3.消费端弄丢的数据
使用rabbitMQt提供的baseack方法,开启手动应答,每次自己代码处理完就在应答,如果没处理挂了,
4.如何保证数据的顺序
将需要按顺序执行的数据,通过一个消费者来消费,可以避免顺序错乱的问题.
5.如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?
准备大量的消费者的服务(原来的倍数)每台机器绑定一个queue,然后将原来的消费者代码一下, 不至直接落库,全部将数据转到准备的消费上,然后从准备的消费者的入库,这样可以提高N倍的效率
6.如果让你写一个消息队列,改如何设计啊?说一下设计的思路?
1.首先这个mq的支持可伸缩性。就是需要的时候快速扩容,就可以增加吞吐量和容量,那怎么搞?设计个分布式的系统呗参照一下kafka的设计理念,broker -> topic -> partition,每个partition放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给topic增加partition,然后做数据迁移,增加机器,不就可以存放更多数据,提供更高的吞吐量了?
2.其次你得考虑一下这个mq的数据要不要落地磁盘吧?那肯定要了,落磁盘,才能保证别进程挂了数据就丢了。
3.考虑mq的可用性啊
4.能不能支持数据数据的丢失啊。