mandatory
mandatory=true
,如果交换器无法根据自身的类型和路由键找到一个符合条件的队列,RabbitMQ会调用 Basic.Return
命令将消息返回给生产者mandatory=false
,上述情形下,RabbitMQ 将消息直接丢弃channel.addReturnListener
添加监听器接收返回结果immediate
immediate=true
,如果交换器在消息路由到队列时发现队列上并不存在任何消费者,该消息将不会存入队列中。当与路由键匹配的所有队列都没有消费者时,该消息会通过 Basic.Return
返回生产者备份交换器
AE可以将未被路由的消息存储到 RabbitMQ 中
Map args = new HashMap();
args.put("alternate-exchange","myAe");
// 声明普通交换器(AE交换器作为备份交换器)
channel.exchangeDeclare("normalExchange","direct",true,false,args);
// 声明AE交换器
channel.exchangeDeclare("myAe","fanout",true,false,null);
// 普通队列 绑定 普通交换器
channel.queueBind("normalQueue","normalExchange","normalKey");
// 声明 未路由队列
channel.queueDeclare("unroutedQueue",true,false,false,null);
// 未路由队列 绑定 AE交换器
channel.queueBind("unroutedQueue","myAe","");
特殊情况
通过队列设置消息TTL
Map args = new HashMap();
args.put("x-message-ttl",6000); // 单位毫秒
channel.queueDeclare(queueName,durable,exclusive,autoDelete,args);
Policy方式
rabbitmqctl set_policy TTL ".*" '{"message-ttl":6000}' --apply-to queues
消息过期:一旦过期,从队列中抹去
设置每条消息TTL
在 channel.basicPublish
方法中加入 expiration 参数,单位毫秒
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
builder.deliveryMode(2);
builder.expiration("60000");
AMQP.BasicProperties properties = builder.build();
channel.basicPublish(exchangeName,routingKey,mandatory,properties,"ttlTestMessage".getBytes());
消息过期:消息过期后,不会马上从队列中抹去,在即将投递到消费者之前判定
设置队列的TTL
通过 channel.queueDeclare
方法中的 x-expires 参数可以控制队列被自动删除前处于未使用状态的时间
RabbitMQ 会确保在过期时间到达后将队列删除,在 RabbitMQ 重启后,过期时间会重置
当消息在一个队列中变成死信,会被重新发送到死信交换器(DLX),绑定DLX的队列称为死信队列
死信原因:1.消息被拒绝; 2.消息过期; 3. 队列达到最大长度
绑定死信队列:在 channel.queueDeclare
方法中设置 x-dead-letter-exchange
参数为此队列添加 DLX
消息当被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,才能拿到消费
用法:
具有高优先级的队列有高的优先权,优先级高的消息优先被消费
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
builder.priority(5);
AMQP.BasicProperties properties = builder.build();
channel.basicPublish("exchange_priority","rk_priority",properties,("message").getBytes());
String callbackQueueName = channel.queueDeclare().getQueue();
BasicProperties props = new BasicProperties.Builder().replyTo(callbackQueueName).build();
channel.basicPublish("","rpc_queue",props,message.getBytes());
RPC 处理流程:
持久化可以提高 RabbitMQ 的可靠性,防止在异常情况(重启、关闭、宕机)下数据丢失
持久化的各种情况
事务机制
事务方法:
事务流程:
事务问题:事务机制会耗尽 RabbitMQ 的性能
发送方确认机制
发送方确认机制好处:相比于事务,它是异步非阻塞的
消息分发
channel.basicQos
方法,设置允许限制信道上的消费者保持最大未确认消息数量消息顺序性
弃用 QueueingConsumer
Basic.Qos
方法得到有效解决
消息传输保障等级
最少一次:需要考虑 事务、mandatory、持久化处理、autoAck
最多一次:无须考虑以上问题,随便发送与接收
恰好一次:RabbitMQ 目前无法保障