RabbitMQ不讲武德,发个消息也这么多花招 (2)

3、新建一个消费者 ExchangeConsumer 类,不同的方法实现分别监听不同的队列:

@Component public class ExchangeConsumer { /** * 监听绑定了direct交换机的的消息队列 */ @RabbitHandler @RabbitListener(queues = "LONGLY_WOLF_ORDER_QUEUE") public void directConsumer(String msg){ System.out.println("direct交换机收到消息:" + msg); } /** * 监听绑定了topic交换机的的消息队列 */ @RabbitHandler @RabbitListener(queues = "LONGLY_WOLF_USER_QUEUE") public void topicConsumer(String msg){ System.out.println("topic交换机收到消息:" + msg); } /** * 监听绑定了fanout交换机的的消息队列 */ @RabbitHandler @RabbitListener(queues = "LONGLY_WOLF_PRODUCT_QUEUE") public void fanoutConsumer(String msg){ System.out.println("fanout交换机收到消息:" + msg); } }

4、新增一个 RabbitExchangeController 类来作为生产者,进行消息发送:

@RestController @RequestMapping("/exchange") public class RabbitExchangeController { @Autowired private RabbitTemplate rabbitTemplate; @GetMapping(value="/send/direct") public String sendDirect(String routingKey,@RequestParam(value = "msg",defaultValue = "no direct message") String msg){ rabbitTemplate.convertAndSend("LONGLY_WOLF_DIRECT_EXCHANGE",routingKey,msg); return "succ"; } @GetMapping(value="/send/topic") public String sendTopic(String routingKey,@RequestParam(value = "msg",defaultValue = "no topic message") String msg){ rabbitTemplate.convertAndSend("LONGLY_WOLF_TOPIC_EXCHANGE",routingKey,msg); return "succ"; } @GetMapping(value="/send/fanout") public String sendFaout(String routingKey,@RequestParam(value = "msg",defaultValue = "no faout message") String msg){ rabbitTemplate.convertAndSend("LONGLY_WOLF_FANOUT_EXCHANGE",routingKey,msg); return "succ"; } }

5、启动服务,当我们调用第一个接口时候,路由键和绑定键 order.detail 精确匹配时,directConsumer 就会收到消息,同样的,调用第二接口时,路由键满足 user.# 时,topicConsumer 就会收到消息,而只要调用第三个接口,不论是否指定路由键,fanoutConsumer 都会收到消息。

消息过期了怎么办

简单的发送消息我们学会了,难道这就能让我们就此止步了吗?显然是不能的,要玩就要玩高级点,所以接下来让我们给消息加点佐料。

TTL(Time-To-Live)

TTL 即 一条消息在队列中的最大存活时间。在一条在队列中超过配置的 TTL 的消息称为已死消息。但是需要注意的是,已死消息并不能保证会立即从队列中删除,但是能保证已死的消息不会被投递出去。

设置 TTL 的方式有两种:

1、给队列设置 x-message-ttl,此时所有被投递到队列中的消息,都会在到达 TTL 时成为已死消息。

这种情况就会出现当一条消息同时路由到 N 个带有 TTL 时间的队列,而由于每个队列的 TTL 不一定相同,所以同一条消息在不同的队列中可能会在不同时间死亡或者不会死亡(未设置 TTL ),所以一个队列中的消息死亡不会影响到其他队列中的消息。

2、单独给某一条消息设置过期时间。

此时需要注意的时,当消息达到 TTL 时,可能不会马上被丢弃,因为只有处于队列头部消息过期后才会被丢弃,假如队列头部的消息没有设置 TTL,而第 2 条消息设置了 TTL,那么即使第 2 条消息成为了已死消息,也必须要等到队列头部的消息被消费之后才会被丢弃,而已死消息在被丢弃之前也会被计入统计数据(比如队列中的消息总数)。所以为了更好的利用 TTL 特性,建议让消费者在线消费消息,这样才能确保消息更快的被丢弃,防止消息堆积。

PS:消息过期和消费者传递之间可能存在自然的竞争条件。例如,消息可能在发送途中(未到达消费者)过期。

队列的生存

和 TTL 针对消息不同的是,我们可以通过设置过期时间属性 `x-expires`` 来处理队列,当在指定过期时间内内未使用队列时,服务器保证将删除队列(但是无法保证在过期时间过后队列将以多快的速度被删除)。

TTL 和过期时间实战

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsxyy.html