消息中间件

可靠消息队列的实现 基于SpringBoot + LTS + S

2018-03-31  本文已影响49人  winters1992

使用消息队列实现下面三个目标

1.保证事务一致性
2.顺序消息投递及消费
3.幂等性即 每个消息只消费一次


Kafka简介

kafka消费模式:

kafka采取pull模式,消费速度由消费者线程的消费速度决定

kafka分区:

每个主题下的kafka分区采用磁盘顺序IO写入,消费时采用磁盘顺序IO读出,
消费者在消费成功后 投递ack 分区offest会自动修改,从而保证单个分区有序,具体图示如下


kafka分区
kafka投递模式:

At most once 消息可能会丢,但绝不会重复传输
At least one 消息绝不会丢,但可能会重复传输
Exactly once 每条消息肯定会被传输一次且仅传输一次,很多时候这是用户所想要的。
默认采取At least one,消费者需要在业务层面上实现去重方案,针对一个主题,所有的消息应该有一个唯一ID标示


幂等性与事务一致的实现

幂等性
消费者代码逻辑
一致性

生产者根据业务线程产生的数据,将事件进行持久化,定时调度的投递线程将标记offset 根据 mysql的自增主键序,
将消息根据其业务key值进行hash,投递到指定的kafka分区,代码里面保证messageKey一致,kafka就会投递到同一个分区中去,
保证消息在业务逻辑上是有序的。

下图的例子就是将每一个订单的更新消息都投递到一个分区中去,这样保证了业务上的有序


保证业务有序 生产者代码逻辑
顺序消费

保证顺序消费的原则就是每一个FIFO队列(这里指我们使用的kafka的分区,kafka单个分区是保证FIFO的)
每个分区在任意时刻最多只能有一个消费者线程接管它

这里在集成使用SpringCloudStream的时候,可以编写测试代码 使用ConcurrentHashMap 统计线程ID以及其消费的消息的 Kafka partion id,

顺序消费

关于消费者实例宕机的问题,单个服务实例存在有可能宕机的情况,在实测中SpringCloudStream会根据配置自动将每个分区分配到不同的线程消费

正常消费的情况

单个实例宕机的情况下,其余的消费者线程会自动接管宕机实例的消费分区

实例1宕机的情况

数据的整体流转,在代码中的具体实现

todo


代码

https://github.com/jonwinters/message_queue


参考

领域驱动设计-远程界限上下文 事件转储

https://www.zhihu.com/question/27707687

https://www.zhihu.com/question/30195969

上一篇 下一篇

猜你喜欢

热点阅读