consumer:
push message,from queue to consumer
pull message, from consumer to queue
Each consumer (subscription) has an identifier called aconsumer tag. It can be used to unsubscribe frommessages. Consumer tags are just strings.
Message Acknowledgements
因为网络的不可靠性和consumer 应用的不稳定性,可能会crash,才有这个message ack机制来保证消息不丢失。
expicit acknowledgements model: broker 从queue发送message到consumer通过方法basic.ack,可以由consumer来决定什么时候发送acknowledgement给broker,可以是接受到message就发送,也可以是吧message存到硬盘后发送,也可以是完全处理完此message后再发送。如果consumer在发送acknowledgement之前 出问题crash了,则broker会转发此message给下一个准备接受此类message的consumer处理而不会丢失message,如果没有准备好或注册好的consumer,borker会一直等。
rabbitmq没有超市机制,consumer可以处理很长的时间,
rabbitmq只有consumer crash了,connection,tcp connection,channel close了,broker会检测到这些情况,requeue没有收到message acknowledge的message。
检查有哪些message在consumer处理完后,忘记发送ack(channel.basicAck(envelope.getDeliveryTag(), false);)给broker的命令:
In order to debug this kind of mistake you can use rabbitmqctlto print the messages_unacknowledged field:
sudo rabbitmqctl list_queues name messages_ready messages_unacknowledged
On Windows, drop the sudo:
rabbitmqctl.bat list_queues name messages_ready messages_unacknowledged
reject messages情况及其处理:
message处理失败或者超时,consumer可以回一个reject message 通过basic.reject,并且要求broker discard或者重新加入queue,当只有一个consumer处理这个 message时,可能会出现,reject message,然后重新加入queue,再然后message发给上次失败处理的同一个consumer,又被reject。。。 进入死循环。
Negative Acknowledgements
AMQP提供basic.reject可以reject 单独一个message,不能批处理negatively acknowledgements。rabbitmq做了extension,解决了这个问题,通过basic.ack, 客户端 set themultiple flag of thebasic.nack method totrue
摘自官网:
This example rejects two messages with a single call tothe broker (the second argument onbasicNack is themultiple flag):
GetResponse gr1 = channel.basicGet("some.queue", false);
GetResponse gr2 = channel.basicGet("some.queue", false);
channel.basicNack(gr2.getEnvelope().getDeliveryTag(), true, true);
Prefetching Messages
consumer一次性接受多个messages的情况,批接收,rabbitmq只支持channel级别的prefetch-count,不支持connection级别或者基于size的prefetching。
Message Attributes and Payload