基于rocketmq的分布式事务(封装工具类)

基于rocketmq的分布式事务(封装工具类)


前言

根据朋友封装的工具 借鉴的,记录一下~~~

一、rocketMq是什么?

是一个分布式消息传递和流平台,具有低延迟,高性能和可靠性,万亿级容量和灵活的可伸缩性。简而言之就是个消息队列。

二、使用步骤

(1)、linux安装启动rocketmq注意点(这里使用虚拟机 docker安装)

1、在安装完rocketmq之后要先启动 mqnamesrv 再启动 mqbroker
2、在启动mqbroker的时候要记得处理ip的问题,默认启动会使用docker的内网地址,需要配置成虚拟机ip
附上shell
#启动mqnamesrv
nohup sh mqnamesrv &
#创建一个mqbroker的配置文件
echo brokerIP1=192.168.147.130 >broker.properties
#启动mqbroker 开启自动创建主题
nohup sh mqbroker -n 你的ip:9876 -c broket.properties autoCreateTopicEnable=true &
#查看是否启动成功
tail -f ~/logs/rocketmqlogs/broker.log

(2)、java代码通过rocketmq的事务 处理分布式事务 并封装(个人基本封装例子,可通过基于配置文件配置,更灵活简便)这里直接使用代码配置

1、引入依赖
		<dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-remoting</artifactId>
            <version>4.4.0</version>
        </dependency>
2、启动加载生产者实例工具类,使用的是TransactionMqProducer 使用事务 默认的是不具有事务的,并且配置事务处理的类 实现TransactionListener 这里没有独立写 直接new了
@Configuration
public class rocketMqConfig {
 
    @Value("${apache.rocketmq.namesrvAddr}")
    private String namesrvAddr;
 
    private static final String PRODUCER_GROUP = "xd_producer_group";
 
    @Bean
    public ITransactionRocketMqUtil rocketMqUtilSs(){
 
        TransactionMQProducer producer = new TransactionMQProducer(PRODUCER_GROUP);
        producer.setVipChannelEnabled(false);
        producer.setNamesrvAddr(namesrvAddr);
        //创建一个自定义线程工厂
        ThreadFactory threadFactory =
                new ThreadFactoryBuilder().setNameFormat("transaction-thread-name-%s").build();
        //创建一个线程池
        ThreadPoolExecutor executor =
                new ThreadPoolExecutor(
                        2, 5, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(30), threadFactory);
        //设置生产者线程池
        producer.setExecutorService(executor);
        //设置事务监听器
        producer.setTransactionListener(new TransactionListener() {
            @Override
            public LocalTransactionState executeLocalTransaction(Message message, Object o) {
                try {
                    LoggerUtil.info("开始事务处理");
                    System.out.println(1/0);
                    LoggerUtil.info("完成事务");
                    return LocalTransactionState.COMMIT_MESSAGE;
                }catch (Exception e){
                    LoggerUtil.info("失败事务");
                    return LocalTransactionState.ROLLBACK_MESSAGE;
                }finally {
                    LoggerUtil.info("事务处理结束");
                    return null;
                }
            }
 
            @Override
            public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
                try {
                    LoggerUtil.info("开始事务回查");
                    System.out.println(1/1);
                    return LocalTransactionState.COMMIT_MESSAGE;
                }catch (Exception e){
                    return LocalTransactionState.ROLLBACK_MESSAGE;
                }finally {
                    LoggerUtil.info("事务回查结束");
                }
            }
        });
        return new TransactionRocketMqUtil(producer);
    }
}
(3)、生产者消息发送工具类
public class TransactionRocketMqUtil implements ITransactionRocketMqUtil {
 
    private TransactionMQProducer producer;
 
    public TransactionRocketMqUtil(TransactionMQProducer producer){
        LoggerUtil.info("初始化类");
        this.producer = producer;
        start();
    }
 
    public TransactionSendResult transactionSend (String topic,String msg) throws Exception {
        Message message = new Message(topic,msg.getBytes());
        TransactionSendResult result =  producer.sendMessageInTransaction(message,null);
        return result;
    }
 
    public void shutdown(){
        this.producer.shutdown();
    }
 
    /**
     * 使用前先调用start方法
     */
    public void start(){
        try {
            this.producer.start();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
(4)、消费者注册封装
@Configuration
public class ConsumerContext {
 
    private DefaultMQPushConsumer consumer;
 
    @Value("${apache.rocketmq.namesrvAddr}")
    private String namesrvAddr;
    @Bean
    public ContextContextTool testConsumer() throws Exception {
        new ContextContextTool().ContextTool();
        return null;
    }
}

这里我写死了消费者的类可以在 ContextTool() 方法中配置传入消费者的 类 以及组 和 主题 消费者的类需要实现MessageListenerConcurrently接口,逻辑写在consumeMessage方法中

public class ContextContextTool {
    @Value("${apache.rocketmq.namesrvAddr}")
    private static String namesrvAddr;
    public void ContextTool() throws MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("test_group");
        consumer.setNamesrvAddr(namesrvAddr);
        consumer.subscribe("test_topic","*");
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                for (MessageExt msg : list) {
                    LoggerUtil.info("消费成功"+msg);
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
        LoggerUtil.info("创建消费者并启动监听:test_topic");
    }
}
(5)、消息发送
public void sendProducerTransaction() throws Exception {
       TransactionSendResult result = transactionRocketMqUtil.transactionSend("test_topic","test_msg");
       LoggerUtil.info("发送消息到rocketmq事务监听"+result);
   }
(6)、结果

在这里插入图片描述

总结

rocketmq解决分布式事务是非常方便的,使数据达到最终一致性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值