订单系统分布式环境消息顺序处理

目录

消息为什么要顺序消费

消息顺序投递方案

kafka顺序投递

提高消费者吞吐量

ElasticSearch乐观锁

ElasticSearch与数据库一致性


消息为什么要顺序消费

一个订单会有很多种状态:待支付、已支付、待发货、交易完成等等。

每一种状态的流转都依赖上一个状态,其中一些状态是不可逆的,例如不能从已支付退回待支付。

订单状态流转就是一个典型的状态机场景,如图所示。

订单基于状态机设计模式可以很方便实现乐观锁,在分布式环境,可能多个实例同时将订单从一个状态更为为另一个状态,基于MySql的MVCC多版本并发控制,只有一个线程能更改成功。基于状态机的乐观锁保证了在微服务环境下的线程安全。

UPDATE  order SET status = '已支付' WHERE status = '待支付' AND order_id = 10001
UPDATE  order SET status = '已发货' WHERE status = '已支付' AND order_id = 10001

 

update语句涉及对数据库的更改,MySql会按顺序产生对应的binlog,可以基于Alibaba开源中间件Canal订阅binglog,实现订单消息的准实时收集,例如推送给ElasticSearch。订阅binlog一大好处就是业务逻辑不需要关心 ES 数据的写入。在大批量下单,活动、秒杀场景可能有大批量的binlog变更,如果直接通过Canal订阅binlog变动,会造成Canal Client瞬间爆掉。为了解决这个问题,我们可以引入kafka做一层封装,起到削峰作用。消息是异步的,基于消息投递的更新和删除的操作,如果出现了先发后至/后发先至的情况,就会导致ES里的数据是比较旧的数据,如果待支付消息覆盖了已支付消息是不允许的。

消息顺序投递方案

Canal就是把自己伪装成了MySQL的一个slave,然后同步其binlog。

具体使用方法和原理可以查看github主页 https://github.com/alibaba/canal 

Canal可以把有序的binlog按原来顺序投递到kafka,而Kafka也支持消息按投递顺序消费。

 

 

 

Alibaba Canal对集群的支持不太友好,除了Canal,kafka也有丰富的connector支持将数据导入kafka,一样支持顺序投递,而且原生支持集群的方式。

Kafka Elasticsearch Connector Tutorial with Examples

 

kafka顺序投递

这里不多讲kafka分区与消费者之间的关系,只需要了解Kafka 可以保证分区消息的顺序。

如果使用同一个生产者往同一个分区写入消息,而且

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值