消息队列关键点总结

消息队列RabbitMQ关键点总结

总结一下自己对消息队列的看法,不对请指正。

1.1、消息队列三大特性

解耦:订单调用库存,可能开始指定调用的参数个数类型,后来库存服务接口升级维护,调用参数个数或者类型等就会发生改变,这样订单服务也会跟着改变,偶合性过高。但是引入消息队列之后,订单只需要把下单关键信息放入消息队列里面,就不用太过于关心怎么调用库存服务了,库存直接从队列取消息消费就可以了。

异步:下单->发短信->发邮件。一般先下单然后发送短信、发邮件,执行时长可能会有下单+入数据库+发送短信+发邮件等。但是引入消息队列后,下单入库,直接把下单成功信息放入消息队列,耗时就是入数据库和入队列的时间,就不用管后续的操作。后续接到队列的消息后各自执行就行。

削峰:1、用户的请求,服务器收到之后,首先写入消息队列,加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面。2、秒杀业务根据消息队列中的请求信息,再做后续处理。

1.2、消息队列异步调用

消息队列和feign都可以进行远程调用,但是feign进行多个远程调用的时候进行CompletableFuture异步编排的时候,会出现请求头的cookie信息不共享、上下文不共享问题。比如远程调用根据用户信息获取购物车服务,产生了新的线程,如果是串行就是一个线程不会出现请求头丢失,新线程调用请求头不共享就会报错。

在消息队列中,消息通常是以消息头和消息体的形式进行传递。消息头包含了一些元数据信息,如消息的唯一标识、消息的发送时间等。这些元数据信息可以在消息传递过程中不丢失,确保消息的完整性和可追踪性。

1.3、分布式事务

分布式事务使用seata会有TCmanage事务协调者对事务等进行协调隔离产生额外的开销,相比较消息队列的可靠性消息投递会慢一点,消息队列靠的就是异步提高性能。在需要更强的事务管理能力和一致性保证时,使用Seata可能是更合适的选择,尽管可能会稍微慢一些。在性能要求较高,对事务管理要求不高的场景下,直接使用消息队列接口可能更为适合。

1.3.1、消息队列可靠性消息投递

消息队列采用最终一致性解决方案,可靠性在消息推送给交换机和交换机推送给队列的时候会可以设置两个回调函数ConfirmCallbackRetrunCallback,在消息接受的时候可以设置手动接受或者拒绝ack和nack

最终一致性就是基于消息的可靠性传递,由于网络故障等原因导致消息的延迟或失败,RabbitMQ也能够通过重试和持久化等机制来保证消息的最终一致性。

消息持久化:RabbitMQ允许将消息持久化到磁盘,即使在节点故障或重启后,消息也能够被恢复和重新传递。这样可以保证消息不会因为节点故障而丢失。

1.4、消息队列的要素

消息通过路由键与交换器进行绑定,交换器也有一个绑定键(路由键)与队列进行绑定。至于消息会发送到哪个队列就是通过比对消息发送的路由键与交换器绑定队列的路由键进行匹配。绑定键可以使用#匹配多个单词,*匹配一个单词。

交换器·分为一对一和一对多,一对一direct,一对多fanout扇形交换机,topic主题交换机。扇形交换机会把消息发送到所有与它绑定的队列(这里的路由键不起作用),主题交换机会发送到多个与之通过特定绑定规则的路由键的队列。一般一对多用topic。

一般使用@Configuration与@bean来注解注册交换器,队列,死信消息等

1.5、消息丢失、消息幂等、消息顺序消费、消息延时消费
  • 消息丢失参考可靠性消息投递
  • 消息幂等在消息队列中保证幂等性的常用方法有以下几种:
  1. 唯一标识符:在消息中添加一个唯一标识符(如UUID),消费者在处理消息时先检查该标识符是否已经处理过该消息,如果已经处理过则忽略,否则执行处理逻辑。
  2. 幂等性检查:消费者在处理消息时,先查询相关数据或状态,判断是否已经处理过该消息。如果已经处理过,则直接返回成功;如果未处理过,则执行处理逻辑,并将处理结果记录下来,以便下次查询时判断是否已经处理过。
  3. 乐观锁:在消费者处理消息时,使用乐观锁来确保同一消息只被处理一次。消费者在处理消息前先获取锁,如果获取成功,则执行处理逻辑,并在处理完成后释放锁;如果获取失败,则表示该消息已经被其他消费者处理过,当前消费者可以忽略该消息。
  4. 消息去重:消费者在处理消息时,记录已经处理过的消息的唯一标识符,下次再收到相同的消息时先判断是否已经处理过,如果已经处理过,则直接忽略该消息,避免重复处理。

综上所述,保证消息队列的幂等性需要在消费者端进行处理,通过添加唯一标识符、幂等性检查、乐观锁和消息去重等方式来确保同一消息只被处理一次。

  • 消息顺序性消费
  1. 单一消费者:使用单一消费者来消费消息,这样可以确保消息按照发送的顺序被消费。这种方式适用于对消息处理顺序要求较高的场景,但是缺点是无法实现消息的并行处理。
  2. 消息分区:将消息按照某种规则进行分区,每个分区由一个消费者来消费。通过合理的分区策略,可以保证同一个分区内的消息按照顺序被消费,但是不同分区之间的消息顺序无法保证。
  3. 消息分组:将消息分组,每个分组由一个消费者来消费。在同一个分组内,消息可以按照顺序被消费,但是不同分组之间的消息顺序无法保证。可以根据业务需求将相关的消息放在同一个分组中,从而实现消息的顺序消费。
  4. 消息重排序:在消费者端进行消息的重排序。消费者可以将接收到的消息进行缓存,然后按照一定的顺序进行处理。例如,可以使用优先队列或者有序队列来实现消息的有序消费。

然后按照一定的顺序进行处理。例如,可以使用优先队列或者有序队列来实现消息的有序消费。

  • 延时消费:可以采用延时队列,比如一个交换机,两个队列,交换机与两个队列进行绑定,把其中一个队列设置所有消息的过期时间,一旦消息过期(死信),就放入到另一个队列,此次消费者只需要实时接受消费另一个队列就可以了。

猜你喜欢

转载自blog.csdn.net/qq_45925197/article/details/132391433
今日推荐