下面以注册送积分为例来说明:下例共有两个微服务交互,用户服务和积分服务,用户服务负责添加用户,积分服务负责增加积分。

image.png

交互流程如下:

  1. 用户注册
    用户服务在本地事务新增用户和增加 “积分消息日志”。(用户表和消息表通过本地事务保证一致)
    mysql begin transaction //1.新增用户 //2.存储积分消息日志 commit transation
    这种情况下,本地数据库操作与存储积分消息日志处于同一个事务中,本地数据库操作与记录消息日志操作具备原子性。

  2. 定时任务扫描日志
    如何保证将消息发送给消息队列呢?
    经过第一步消息已经写到消息日志表中,可以启动独立的线程,定时对消息日志表中的消息进行扫描并发送至消息中间件,在消息中间件反馈发送成功后删除该消息日志,否则等待定时任务下一周期重试。

  3. 消费消息
    如何保证消费者一定能消费到消息呢?
    这里可以使用 MQ 的 ack(即消息确认)机制,消费者监听 MQ,如果消费者接收到消息并且业务处理完成后向 MQ 发送 ack(即消息确认),此时说明消费者正常消费消息完成,MQ 将不再向消费者推送消息,否则消费者会不断重试向消费者来发送消息。
    积分服务接收到”增加积分”消息,开始增加积分,积分增加成功后向消息中间件回应 ack,否则消息中间件将重复投递此消息。
    由于消息会重复投递,积分服务的”增加积分”功能需要实现幂等性。

引用

https://zhuanlan.zhihu.com/p/147817106