可靠性消息事务实现

       本方案基于外部事件表(Mysql)+MQ(ActiveMQ)+SpringCloud方式提供事务型消息发送。此方案并不依赖特定的事件表及MQ,TPS受限时可进行替换。主要应用在事务中包含的重接口、第三方系统调用等,以实现异步化,保证最终一致性。因为是异步调用,所以接口限制为不能有返回值。为了记录完整的调用日志链,整个过程中注意传递请求日志id。

       在SpringCloud中远程调用默认协议为HTTP,客户端实现是使用Feign。在远程调用接口的定义处(@FeignClient)增加一个注解(如@TransactionalMessage)标记该远程调用支持异步事务消息。对@TransactionalMessage标记的方法做一个切面拦截,把FeignClient的请求信息(Request)预存到事件表中。如果此处有任何异常或有开关控制,此处可直接执行远程调用。如无异常则执行消息发送,忽略本身的远程调用。

       预存完事件表后,需把事件id绑定到线程变量中,与当前事务做关联,随后使用ApplicationEventPublisher发布该事务事件。为了合并一个事务下的事务消息,此处只发布一个事务事件,同一事务的后续消息id直接绑定到线程变量中即可。

       使用Spring的@TransactionalEventListener监听ApplicationEventPublisher发布的事务提交操作。

       监听到BEFORE_COMMIT时修改预存事件状态为已提交待发送状态,此操作还在包含在事务当中,所以可保存状态的一致性。

       监听到AFTER_COMMIT时把与当前事务关联的事务消息发送到MQ中通知执行远程方法调用。

       监听到AFTER_ROLLBACK时回滚预存的事件表数据。

       提供一个单独的服务,来处理事件表里的远程调用。需处理MQ的通知以及定时查询事件表里可重试状态的数据,还需注意重复消息,保证幂等性。还原事件表里记录的Request,Request记录了请求参数或请求体、请求头、请求地址(域名部分是由应用名替代)。注入Feign的Client客户端执行Request即可。此处需判断执行是否成功,除了判断HTTP调用是否成功,还需判断业务是否执行成功(所有接口需统一返回一个状态码来标明是否正常执行)。如果执行成功则删除事件表中对应的数据,否则回滚,等待下次重试。

RabbitMQ是一款可靠的消息队列中间件,它可以通过一些机制来实现可靠消息的最终一致性。 首先,RabbitMQ支持持久化消息。当消息被发送到队列中时,可以将消息标记为持久化,确保即使在系统故障或重启的情况下,消息也不会丢失。通过这种方式,可以保证消息可靠性。 其次,RabbitMQ采用了发布-订阅的模式。生产者将消息发布到交换机上,然后交换机根据规则将消息路由到相应的队列上,消费者从队列中订阅并消费消息。通过这种方式,可以确保消息的可靠传递和消费。 另外,RabbitMQ还支持事务。在发送消息之前,可以开启一个事务并将消息发送到队列中。如果事务成功提交,则消息会被正式发送;如果事务回滚,则消息不会发送。通过使用事务,可以保证消息发送的可靠性和一致性。 还有一种机制是消息的确认机制。在消息发送之后,生产者可以等待RabbitMQ返回一个确认消息。只有当生产者接收到确认消息时,才能确定消息已经被成功处理并可以进行下一步操作。通过这种方式,可以保证消息的可靠发送和处理。 综上所述,RabbitMQ通过持久化、发布-订阅、事务消息确认等机制,实现了可靠消息的最终一致性。无论是在消息的传递过程中,还是在系统的故障和重启中,都能确保消息可靠性和一致性,从而满足业务的需要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值