所谓最大努力通知,换句话说就是并不保证100%通知到。这种分布式事务的方案,通常也是借助异步消息进行通知的。
发送者将消息发送给消息队列,接收者从消息队列中消费消息。在这个过程中,如果出现了网络通信故障或者消息队列发生了故障,就有可能导致消息传递失败,即消息被丢失。因此,最大努力通知无法保证每个接收者都能成功接收到消息,但是可以尽最大努力去通知。
下面是一个简单的例子来说明最大努力通知的过程。假设有一个在线商城系统,顾客可以下订单购买商品。当顾客成功下单后,通知顾客订单已经确认。这个通知就可以采用最大努力通知的方式。
@startuml
autonumber
actor "用户" as User
User -> 商城系统: 下单
商城系统 -> 订单系统: 创建订单
订单系统 --> 消息中间件: 下单成功消息
alt 消息发送成功
消息中间件 --> 用户通知服务: 下单成功消息
else 消息发送失败
订单系统 --> 消息中间件: 重试3次
end
用户通知服务 -> User: 邮件通知
@enduml
需要注意的是,在最大努力通知的过程中,可能会出现消息重复发送的情况,也可能会出现消息丢失的情况。因此,在设计最大努力通知系统时,需要根据实际业务需求和风险承受能力来确定最大努力通知的策略和重试次数,以及对消息进行去重等处理。
最大努力通知这种事务实现方案,一般用在消息通知这种场景中,因为这种场景中如果存在一些不一致影响也不大。
本地消息表相对于最大努力通知而言,引入了本地消息表,通过本地事务来保证消息可以发送成功。相对来说,具有更强的可靠性,可以在一定程度上保证消息的传递不丢失。但是,本地消息表也会带来额外的存储开销和网络通信成本。
而最大努力通知这种方案比较简单,但是可能存在丢消息的情况。其实,一般业务中,也会通过对账来解决的,并不会完全放任消息丢失,只不过对账的机制会有一定的延时,并且可能需要人工介入。