最大努力通知-实现分布式事务

文章目录

简介

最大努力通知方案的目标,就发起通知方通过一定机制,最大努力将业务处理结果通知到收方。
最大努力通知(Best Effort Notification,BEN):它是一种不保证强一致性的方法,通过异步通知来达到尽量保证事务的一致性,即尽力保证事务成功,但不能完全保证。
最大努力通知:这是一种通过消息中间件实现分布式事务的方案,主要应用在金融交易场景中。
分布式事务最大努力通知(Best Effort Delivery)是一种分布式系统中处理事务的方法。在这种方法中,系统会尽最大的努力来通知相关的服务或组件,但并不保证通知一定会成功。
具体来说,分布式事务最大努力通知通常用于以下场景:

  1. 异步通知:当某个服务需要通知其他服务或组件进行后续操作时,可以采用异步通知的方式,发出通知后即可继续自身的操作,而不需要等待被通知的服务的响应。
  2. 最终一致性:在分布式系统中,因为网络延迟、故障等原因,无法保证所有相关的服务或组件都能够及时收到通知。因此,采用最大努力通知的方式来处理事务,可以更好地适应分布式系统的不确定性,最终保证系统达到一致的状态。
    在实际应用中,分布式事务最大努力通知可能会导致以下情况:
    ● 通知失败:由于网络故障、接收方服务不可用等原因,通知可能会失败。
    ● 重复通知:为了确保通知的可靠性,可能需要定时重试通知操作,这可能导致接收方收到重复的通知。
    为了应对这些情况,通常需要在接收方设计幂等性的接收机制,以确保即使接收到重复的通知,也不会对系统状态产生额外影响。
    总的来说,分布式事务最大努力通知是一种在分布式系统中处理事务的方法,它通过异步、灵活的通知机制来适应分布式系统的复杂性,但同时也需要考虑通知可能失败和重复通知等情况。
    对于时间不敏感的业务,短信、邮件通知等。尽最大努力进行推送消息保证事务数据的最终一致性

分布式事务中的“最大努力通知”是一种解决分布式事务的方案,旨在通过一定的机制将业务处理的结果尽可能的通知下游业务接收方。具体来说,当一个事务发起时,它会尽力将业务处理的结果通知给下游业务接收方。如果通知失败,发起方会按照一定的策略进行重复通知。这种方案的目标是尽可能的保证业务处理结果的通知到达接收方。
这种方案有一定的消息重复通知机制,因为接收通知方可能没有接收到通知,此时要有一定的机制对消息进行重复通知。同时,如果尽最大努力也没有通知到接收方,或者接收方消费消息后要再次消费,此时可由接收方主动向通知方查询消息信息来满足需求。
最大努力通知适用于要求事务处理结果必须及时通知给接收方的场景,但是需要注意的是,由于这种方案可能会有大量的重复通知和查询,因此需要谨慎评估其对系统性能和稳定性的影响。

实现逻辑

最大努力通知是一种实现分布式事务的方式,其具体实现逻辑可以根据具体的系统需求和技术选型而有所不同。下面是一个常见的最大努力通知的实现逻辑:

  1. 发送通知:当需要通知其他服务或组件时,发送方首先将通知内容构建成消息或请求,并通过消息队列、异步调用等方式发送给接收方。
  2. 确认接收:接收方在接收到通知后,首先进行接收确认。这可以通过发送一个确认消息给发送方,或者将接收状态标记为已接收等方式来实现。
  3. 处理通知:接收方根据接收到的通知执行相应的操作。这可能涉及到数据库更新、业务逻辑处理等。
  4. 异常处理:如果出现通知处理过程中的异常情况,接收方可以记录异常信息、发送错误消息给发送方或者进行重试等操作。异常处理的方式可以根据具体需求来确定。
  5. 重试机制:为了提高通知的可靠性,接收方可以定期进行通知的重试。重试的频率和次数可以根据实际情况进行配置,以保证通知的最终成功。
  6. 幂等性处理:由于通知的重试可能导致接收方收到重复的通知,因此在接收方需要设计幂等性的处理逻辑,确保即使收到重复的通知,对系统状态不会产生额外的影响。
  7. 结果反馈:接收方可以将通知处理的结果通过消息队列、回调接口等方式反馈给发送方,以便发送方能够获取通知的处理结果。
    需要注意的是,最大努力通知并不能保证通知一定会成功,而是在尽最大努力的情况下去发送和处理通知。因此,在使用最大努力通知时,需要考虑异常情况的处理、重试机制的设置以及幂等性的保证,以确保系统能够在不确定性的分布式环境下实现一致性。

demo

最大努力通知的代码实现主要涉及到发送方和接收方两个模块。下面是一个基于Java语言、使用RabbitMQ消息队列作为通知中介的最大努力通知的代码实现示例:

发送方实现:

public class NotificationSender {
    private final String exchangeName = "notification-exchange";
    private final String routingKey = "notification-routing-key";
    
    private ConnectionFactory factory;
    private Connection connection;
    private Channel channel;
    
    public NotificationSender() throws IOException, TimeoutException {
        factory = new ConnectionFactory();
        factory.setHost("localhost");
        connection = factory.newConnection();
        channel = connection.createChannel();
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC);
    }
    
    public void sendNotification(Notification notification) throws IOException {
        String message = notification.toJson();
        channel.basicPublish(exchangeName, routingKey, null, message.getBytes());
    }
}

接收方实现:

public class NotificationReceiver {
    private final String exchangeName = "notification-exchange";
    private final String queueName = "notification-queue";
    private final String routingKey = "notification-routing-key";
    
    private ConnectionFactory factory;
    private Connection connection;
    private Channel channel;
    
    public NotificationReceiver() throws IOException, TimeoutException {
        factory = new ConnectionFactory();
        factory.setHost("localhost");
        connection = factory.newConnection();
        channel = connection.createChannel();
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC);
        channel.queueDeclare(queueName, true, false, false, null);
        channel.queueBind(queueName, exchangeName, routingKey);
    }
    
    public void startReceivingNotifications(NotificationHandler handler) throws IOException {
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                Notification notification = Notification.fromJson(message);
                try {
                    handler.handleNotification(notification);
                    channel.basicAck(envelope.getDeliveryTag(), false);
                } catch (Exception e) {
                    // 处理异常情况并进行重试
                    channel.basicNack(envelope.getDeliveryTag(), false, true);
                }
            }
        };
        channel.basicConsume(queueName, false, consumer);
    }
}

其中,Notification类表示通知的内容,可以根据具体需求来设计。NotificationHandler接口表示通知的处理逻辑,需要实现handleNotification方法来处理接收到的通知。

在使用时,可以通过如下方式来发送和接收通知:

// 发送方使用示例
NotificationSender sender = new NotificationSender();
Notification notification = new Notification("orderCreated", "orderId123");
sender.sendNotification(notification);

// 接收方使用示例
NotificationReceiver receiver = new NotificationReceiver();
receiver.startReceivingNotifications(new NotificationHandler() {
    @Override
    public void handleNotification(Notification notification) {
        System.out.println("Received notification: " + notification);
        // 处理通知
    }
});

需要注意的是,在实际应用中,还需要考虑重试机制、幂等性处理以及错误处理等问题。例如,在接收方的handleNotification方法中,需要处理通知处理过程中可能出现的异常情况,并进行重试或者错误反馈。

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思静语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值