推荐一款基于RabbitMQ实现的SpringBoot可靠消息组件

开源地址

https://gitee.com/tech-famer/reliablemessage-spring-boot-starter

介绍

这是一款基于RabbitMQ的confirm和return回调机制实现的SpringBoot可靠消息组件,支持事务消息、消息回滚、失败重发等功能。

安装教程

组件有三种安装方式

  1. 通过maven命令:mvn clean package deploy将项目发布到私有仓库,在使用的项目中加入组件依赖,如下:
<depandency>
    <groupId>com.farmer.reliablemessage</groupId>
    <artifactId>reliablemessage-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</depandency>
  1. 通过maven命令:mvn clean package install将项目发布到本地仓库,在使用的本地项目中加入组件依赖,如下:
<depandency>
    <groupId>com.farmer.reliablemessage</groupId>
    <artifactId>reliablemessage-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</depandency>
  1. 将项目源码直接拷贝到需要的项目中直接使用。
使用说明
  1. 组件会将消息入库,消息数据库主键为VARCHAR()类型,使用者需要提供生成主键的spring bean,该spring bean需要实现接口com.farmer.reliablemessage.api.IDApi;组件内置了默认主键生成类com.farmer.reliablemessage.DefaultIDApi,算法为UUID,使用者可以自行实现主键生成算法,如雪花算法等。以下仅为示例:
@Configuration
public class IdConfig {

    @Bean
    public IDApi idApi(){
        return new IDApi() {
            @Override
            public String nextID() {
                return UUID.randomUUID().toString().replace("-","");
            }
        };
    }
}
  1. 在需要发送消息的类中引入可靠消息组件提供的MQTemplate,如下:
@Service
public class TestService {

    @Autowired
    private MQTemplate mqTemplate;

    @Transactional
    public void test(){
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
    }
}

组件只提供一个方法saveAndSendMessage,参数1为交换机名称,参数2为routingKey,参数3为消息体。

场景演示
  1. 普通消息

在普通方法中使用组件发送的消息即为普通消息,普通消息会立即投递到消息中间件,普通消息无法回滚。如:

@Service
public class TestService {

    @Autowired
    private MQTemplate mqTemplate;
    
    public void test(){
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
        // TODO 其他代码
    }
}

其他代码中出现异常,消息仍然会被投递到消息中间件。

  1. 事务消息

顾名思义消息支持事务。在事务中方法使用组件发送消息,消息不会立即投递,在事务提交后消息才会投递,如果事务回滚消息也将回滚而不会被投递。

2.1 简单事务方法,如下:

@Service
public class TestService {

    @Autowired
    private MQTemplate mqTemplate;

    @Transactional
    public void test(){
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
        // TODO 其他代码
    }
}

消息在其他代码执行完事务提交后,消息投递到消息中间件;其他代码出现运行时异常时,消息会回滚而不被投递到消息中间件。

2.2 事务方法调用非事务方法,如下:

@Service
public class TestService {

    @Autowired
    private MQTemplate mqTemplate;

    @Transactional
    public void test(){
        //消息1
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
        orther();
        // TODO 其他代码
    }
    
    public void orther(){
        //消息2
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
    }
}

消息1、2在test方法执行完事务提交后投递到消息中间件;其他代码或者orther方法中出现运行时异常时,消息会回滚而不被投递到消息中间件。

2.3 事务方法调用事务方法情况一,如下:

@Service
public class TestService {

    @Autowired
    private MQTemplate mqTemplate;
    
    @Autowired
    @Lazy
    private TestService testService;

    @Transactional
    public void test(){
        //消息1
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
        testService.orther();
        // TODO 其他代码
    }
    
    @Transactional(propagation = Propagation.REQUIRED)
    public void orther(){
        //消息2
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
    }
}

消息1、2在test方法执行完事务提交后投递到消息中间件;其他代码或者orther方法中出现运行时异常时,消息会回滚而不被投递到消息中间件。

2.4 事务方法调用事务方法情况二,如下:

@Service
public class TestService {

    @Autowired
    private MQTemplate mqTemplate;
    
    @Autowired
    @Lazy
    private TestService testService;

    @Transactional
    public void test(){
        //消息1
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
        testService.orther();
        // TODO 其他代码
    }
    
    @Transactional(propagation = Propagation.REQUIRED_NEW)
    public void orther(){
        //消息2
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
    }
}

消息2在orther方法执行完事务提交后投递到消息中间件;消息1在test方法执行完事务提交后投递到消息中间件;其他代码或者orther方法中出现运行时异常时,消息会回滚而不被投递到消息中间件。

2.5 消息回滚

@Service
public class TestService {

    @Autowired
    private MQTemplate mqTemplate;
    
    @Autowired
    @Lazy
    private TestService testService;

    @Transactional
    public void test(){
        //消息1
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
        testService.orther();
        // TODO 其他代码
    }
    
    @Transactional(propagation = Propagation.REQUIRED)
    public void orther(){
        //消息2
        mqTemplate.saveAndSendMessage("exchangeName","routingKey","payload");
        
        int i = 1/0;
    }
}

语句int i = 1/0;运行时异常导致事务回滚,消息1、2会随着事务一起回滚不会投递到消息中间件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值