事务消息的发送和接收流程如下,原理很简单就是利用数据库的事务保证数据和消息发送的一致性,对于消息采用最大努力通知策略。
消息的发送与接收 (1).png需要注意的一些问题:
- 消息id与幂等校验
业务方生成的消息id主要关注业务类型和唯一标识,比如创建订单可能是order_create + 具体订单id,比如order_create_123,但是仅仅用这个做消息id在消息幂等key检查的时候有些业务场景有问题,比如一个消息是同步更新个人信息,对应的可以消息id是 update_user + 具体userid,这个消息可能会发多次,但是不同的时间发送消费消息得到的执行结果是不同的,这样的场景在接收消息的幂等校验去重时就有问题。
- 可以把幂等校验交给业务去做,不在基础组件里面实现。
- 最终发送时拼接一个事务表里面的主键id或者单独增加一个自增id。
- 消息去重是有必要的
定时扫描消息表和正常事务消息发送可能并发,会导致相同的消息重复发送,通过在原始消息id后拼接事务消息表的id + 幂等key去重就保证每个消息只会被成功处理一次。幂等采用锁机制,可以避免并发业务处理时间过长,并发锁失效后消息重试时并发调用业务逻辑,但是在极端情况下,如果消费时刚刚加上锁,但是还没有来的及处理业务,程序直接退出了,会导致后续消息重试时全部当已经完成处理,所以发版时要谨慎确保没有正在消费的消息。
- 消息可能多次发送不可避免
除了定时任务和正常发送导致并发以外,对于先发送消息成功后,然后删除消息表,消息表可能会删除失败,下次还会扫描到,会导致消息重复发送。
网友评论