消息队列的匹配规则
1.消息队列模式
消息队列模式:发送者,接受者
2.主题消息模式
主题消息:发布者,订阅者
3.Rabbitmq消息确认机制
通过持久化数据的方式,生产者将消息发送出去之后,消息到底有没有达到rabbitmq服务器默认是不知道的。
消息队列如何确保其消息的顺序性
通常来说有以下的思路
- 单线程消费来确保消息的顺序性
- 对消息进行编号,消费者处理时根据编号判断顺序。
rabbitmq:(队列消息的思路)
拆分多个queue,每个queue一个consumer。或者就一个queue但是对应一个consumer,然后这个consumer内部用内存队列做排队,然后分发给底部不同worker处理
-
防止使用同一个队列,导致数据123进入不同的消费者,从而使得数据123没有按指定的顺序被执行
-
通过拆分queue来保证每一个消费者都能获得完整的数据123,然后消费者内部进行排队,从而保证消息的有序性。
-
这里同时也要设计,保证消息的幂等性。
kafka
一个topic,一个partition(分割),一个consumer,内部单线程消费,写N个内存queue,然后N个线程分别消费一个内存queue。 -
通过指定key的方式,来确保相关的数据123会分发到同一个partition
-
partition会内部对其进行排序,保证其有序性。
消息队列如何保证其不会重复消费
简单来说,如何实现消息的幂等性,即消息执行一次和执行多次的结果是一样的。
保证数据不会重复消费,要结合业务来实现
- 比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update 一下好吧。
- 比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。
- 比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id
之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个
id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。 - 比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。
消息队列如何保证消息不会丢失
消息从生产到消费可以经历三个阶段:生产阶段、存储阶段和消费阶段。
生产阶段:在这个阶段,从消息在生产者创建出来,经过网络传输到消息队列服务器中。
存储阶段:消息在消息队列服务器中存储,如果是集群,消息会在这个阶段被复制到其他的副本上。
消费阶段:消费者从消息队列服务器中拉取消息,通过网络传输发送到消费者。
而解决消息队列在整个过程中不会消息丢失的方式,就是借助消息队列的应答模式来实现。
应答模式
消费者完成消费处理后,会发送一个消费应答,告诉消息队列服务器这个消息已经处理完成可以删除这个消息了,如果一个消费者由于宕机
没有发送消息应答,那么消息队列服务器会认为消息发送失败,自动进行补偿行为,即将这个消息重新加入队列,重新投递。
应答模式又分为自动应答和手动应答,区别在于告诉消息队列服务删除消息的时间点是否要手动删除。
应答模式牺牲了消息队列的性能,从而提高了消息的可靠性。
消息队列如何解决消息堆积问题
消息队列除了有异步解耦的功能,还有挡住前端数据洪峰的功能。
- 修复现有consumer的问题,并将其停掉。
- 重新创建一个容量更大的topic,比如patition是原来的10倍。
- 编写一个临时consumer程序,消费原来积压的队列。该consumer不做任何耗时的操作,将消息均匀写入新创建的队列里。
- 将修复好的consumer部署到原来10倍的机器上消费新队列。
- 消息积压解决后,恢复原有架构
核心思路,提高消费者的消费能力。
来源:CSDN
作者:热心市民罗先生
链接:https://blog.csdn.net/weixin_40990818/article/details/104247085