Message Queue
消息消费模式
消息消费模式有两种:Clustering(集群消费)和 Broadcasting(广播消费)。
- 集群消费,一个消息只会被一个消费者消费。
- 广播消费消息会发给消费者组中的每一个消费者进行消费。
Message Order(消息顺序)
Message Order(消息顺序)有两种:Orderly(顺序消费)和Concurrently(并行消费)。
顺序消费表示消息消费的顺序同生产者为每个消息队列发送的顺序一致,所以如果正在处理全局顺序是强制性的场景,需要确保使用的主题只有一个消息队列。
消息去重
去重原则:使用业务端逻辑保持幂等性
幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用,数据库的结果都是唯一的,不可变的。
只要保持幂等性,不管来多少条重复消息,最后处理的结果都一样,需要业务端来实现。
去重策略:保证每条消息都有唯一编号(比如唯一流水号),且保证消息处理成功与去重表的日志同时出现。
建立一个消息表,拿到这个消息做数据库的insert操作。给这个消息做一个唯一主键(primary key)或者唯一约束,那么就算出现重复消费的情况,就会导致主键冲突,那么就不再处理这条消息。
消息的可用性
- RocketMQ采用的是混合型的存储结构,即为Broker单个实例下所有的队列共用一个日志数据文件(即为CommitLog)来存储。
- Kafka采用的是独立型的存储结构,每个队列一个文件。
顺序消费
请使用 RocketMQ ConsumeMessageOrderlyService
kafka事务原理
kafka事务也是基于二阶段提交来实现的,但是它在其中加入了一个事务协调者的概念,事务协调者并不是独立的应用,它是Broken的一部分,协调者也是需要ZooKeeper来保证其可用性的,为了提高并行性能kafka允许多个协调者分别负责管理事务主题中的不同的分区。下面我们大概介绍下图上的流程
- 开启事务,生产者发送给协调者一个事务开启请求,协调者在事务日志中创建一个事务ID并记录。
- 生产者发消息之前给协调者发送消息定位通知(发送的消息属于哪个主题和分区),协调者记录消息定位消息。
- 生产者将一些真正的业务消息给对应分区的Broken,kafka客户端会自动过滤未提交的事务消息。
- 生产者发送消息后,生产者给协调者发送提交或者回滚事务的请求。协调者根据结果将事务状态设置为回滚或者预提交状态,并写入日志。
- 协调者在事务相关的所有分区中写入一条“事务结束”的消息,当消费者受到这个消息时候,就可以把之前那些过滤掉未提交的消息放开给消费者消费,协调者记录日志,事务结束。
kafka事务消息和RocketMQ事务消息的区别
- 它们实用的场景是不一样的,RocketMQ中的事务,它解决的问题是,确保执行本地事务和发消息这两个操作,要么都成功,要么都失败。并且RocketMQ增加了一个事务反查的机制,来尽量提高事务执行的成功率和数据一致性。
- Kafka 中的事务,它解决的问题是,确保在一个事务中发送的多条消息,要么都成功,要么都失败。(这里面的多条消息不一定要在同一个主题和分区中,可以是发往多个主题和分区的消息)
- 当然也可以在kafka事务执行过程中开启本地事务来实现类似RocketMQ事务消息的效果,但是Kafka是没有事务消息反查机制的,它是直接抛出异常的,用户可以根据异常来实现自己的重试等方法保证事务正常运行。