RabbitMQ中关于消息队列的一些概念

概述:

JMS

JMS中有两个典型的消费概念。

Queue,P2P消费,queue中的每个消息以roundrobin的方式,分发给所有已订阅该queue的consumer,只有一个consumer能收到并处理此消息。

Topic,publish-subscribe,queue中的每个消息以broadcast的方式,分发给所有已订阅该queue的consumer,每个consumer都会收到并处理此消息。

AMQP

比起JMS,AMQP更复杂一点,定义了Exchange和Binding机制。

Exchange分为Direct(全匹配定向路由), Fanout(发布-订阅,广播路由), Topic(基于正则进行路由), Header,共4种类型。

Producer发布消息时,只和Exchange打交道,所以Exchange必须事先定义。

Consumer接收消息时,只和Queue打交道。

Queue可以和Exchange进行Binding,在什么时候进行绑定呢?记住一个AMQP协议中的默认规则,即Producer发布消息时,只和Exchange打交道。

扫描二维码关注公众号,回复: 3496478 查看本文章

MQTT

更轻量级的消息队列,多用于移动领域。


RabbitMQ中的一些事项

1,要持久化消息,Queue必须声明为durable=true,Message必须声明为PERSISTENT_TEXT_PLAIN这样的持久化。

2,Queue中的消息只能被一个Consumer接收并成功消费。

3,Consumer消费消息时,推荐设置autoAck=false。consumerChannel.basicConsume(queueName, false, consumer);//autoAck is false

4,Channel的prefetchCount推荐设置为1,Server每次向Consumer只推送一条消息。consumerChannel.basicQos(1);

默认是以轮训的方式消息Queue,但设置prefetchCount设置为1后,就是能者多干,弱者少干。

举例来说,默认的消费方式是这样的,假设queue中有3条消息。

consumer1处理慢,先处理msg1,一直是处理中。

consumer2处理快,处理msg2,很快处理完,但是,consumer2必须等待,因为consumer1还有没处理完。

consumer1处理完msg1,consumer1继续收到并处理消息msg3

consumer2接收并处理msg4。

这种方式收roundrobin,就是非常公平的分发消息。

如果prefetchCount设置为1,consumer接收消息的方式就有所改变了。

consumer1接收并处理msg1,处理中。。。

consumer2接收并正理msg2,很快处理完了。

consumer2再继续接收msg3,很快处理完了。

consumer2再继续处理msg4,很快处理完了。

consumer1现在才处理完msg1,好慢啊。

consumer1再继续处理msg5,处理中。。。

看出来了吧,这种方式,就是谁处理的快,谁就多干。

使用注意事项

channel.BasicQos(0, 1, false),实现公平调度的方式就是让每个消费者在同一时刻会分配一个任务,设置mq每次向consumer推送1条消息,用以保证consumer的消费能力,不会有大量unack消息在queue中。

channel.basicAck(false)和channel.basicReject()都会将消息回退到queue队列头,再次推送到consumer,导致有问题的消息始终一直尝试被消息,所以可以尝试ack=ture,再publish一次,这样该消息被push到queue队列尾。

可以尝试多次业务上去消费message,如果还是不能正常消费消息,自己记录一下Log吧。

推荐自己手动ack。

queue和exchange建议必须持久化

多个consumer要以共享一个connection,但必须使用不同的channel。

mq集群不能kill -9,建议用kill -15。

猜你喜欢

转载自blog.csdn.net/collonn/article/details/77524603