天天看点

浅谈业务流程中的mq使用方式

假设有个场景:

下单成功需要给用户发送消息通知,发送消息通知通过mq实现

事务提交前发送mq消息

step1:start transaction

step2:生成订单

step3:投递消息到mq

step4:commit transaction

问题:

step3发生异常会导致step4失败,下单失败,直接影响到下单业务

step4发生异常,其他step成功。事务回滚下单失败,但是却发送了成功消息。

事务之后发送消息

step1:start transaction

step2:生成订单

step3:commit transaction

step4:投递消息到mq

问题:

step4发生异常,其他step成功。下单成功,但是发送消息失败。

定时轮训发送消息

step1:start transaction

step2:生成订单

step3:本地库中插入一条需要发送消息的记录t_msg_record

step3:commit transaction

step5:新增一个定时器,轮询t_msg_record,将待发送的记录投递到mq中

问题:

这种方式借助了数据库的事务,业务和消息记录作为了一个原子操作。业务成功之后,消息日志必定是存在的。

业务单一的情况下没问题,不方便扩展。

消息服务

step1:生成一个全局唯一业务消息id,调用消息服务,将消息落地入库,此时消息的状态为待发送状态,返回消息id

step2:start transaction

step3:生成订单

step4:当前事务库插入一条日志(将step3中的业务和bus_msg_id关联起来)

step5:commit transaction

step6:如果上面都成功,调用消息服务,将消息投递到mq中。如果上面有失败的情况,则调用消息服务取消消息的发送

若step6失败,消息将处于待发送状态,此时业务方需要提供一个回查接口(通过业务消息id查询),验证业务是否执行成功。消息服务需新增一个定时任务,对于状态为待发送状态的消息做补偿处理,检查一下业务是否处理成功,从而确定消息是投递还是取消发送。

mq