SpringBoot2.0整合RocketMQ实战


springboot依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

rocketmq客户端依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
            <version>4.7.1</version>
        </dependency>

消费者

        // 指定消费组名为my-consumer
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("my-consumer1");
        // 配置namesrv地址
        consumer.setNamesrvAddr("139.155.54.93:9876");
        // 订阅topic:myTopic001 下的全部消息(因为是*,*指定的是tag标签,代表全部消息,不进行任何过滤)
        consumer.subscribe("myTopic001", "*");
//        consumer.subscribe("orderTopic", "order1");
		// 注册监听器,进行消息消费。
        consumer.registerMessageListener(new MessageListenerConcurrently() {
    
    
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
    
    
                for (MessageExt msg : msgs) {
    
    
                    String str = new String(msg.getBody());
                    // 输出消息内容
                    System.out.println(str);
                }
                // 默认情况下,这条消息只会被一个consumer消费,这叫点对点消费模式。也就是集群模式。
                // ack确认
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        // 启动消费者
        consumer.start();
        System.out.println("Consumer start");

同步消息

        // 指定生产组名为my-producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        // 配置namesrv地址
        producer.setNamesrvAddr("139.155.54.93:9876");
        // 启动Producer
        producer.start();
        for (int i = 0; i < 10; i++) {
    
    
            // 创建消息对象,topic为:myTopic001,消息内容为:hello world
            Message message = new Message("orderTopic","order1","order-key", ("hello!" + i).getBytes());
            // 发送消息到mq,同步的
            SendResult result = producer.send(message);
            System.out.println("发送消息成功!result is : " + result);
        }

        // 关闭Producer
        producer.shutdown();
        System.out.println("生产者 shutdown!");

异步消息

        // 指定生产组名为my-producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        // 配置namesrv地址
        producer.setNamesrvAddr("139.155.54.93:9876");
        // 启动Producer
        producer.start();
        // 创建消息对象,topic为:myTopic001,消息内容为:hello world async
        Message msg = new Message("myTopic001", "hello world async".getBytes());
        // 进行异步发送,通过SendCallback接口来得知发送的结果
        producer.send(msg, new SendCallback() {
    
    
            // 发送成功的回调接口
            @Override
            public void onSuccess(SendResult sendResult) {
    
    
                System.out.println("发送消息成功!result is : " + sendResult);
            }
            // 发送失败的回调接口
            @Override
            public void onException(Throwable throwable) {
    
    
                throwable.printStackTrace();
                System.out.println("发送消息失败!result is : " + throwable.getMessage());
            }
        });
        Thread.sleep(3000);
        producer.shutdown();
        System.out.println("生产者 shutdown!");

单向消息

        // 指定生产组名为my-producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        // 配置namesrv地址
        producer.setNamesrvAddr("139.155.54.93:9876");
        // 启动Producer
        producer.start();

        // 创建消息对象,topic为:myTopic001,消息内容为:hello world oneway
        Message msg = new Message("myTopic001", "hello world oneway".getBytes());
        // 效率最高,因为oneway不关心是否发送成功,我就投递一下我就不管了。所以返回是void
        producer.sendOneway(msg);
        System.out.println("投递消息成功!,注意这里是投递成功,而不是发送消息成功哦!因为我sendOneway也不知道到底成没成功,我没返回值的。");
        producer.shutdown();
        System.out.println("生产者 shutdown!");

批量消息

        // 指定生产组名为my-producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        // 配置namesrv地址
        producer.setNamesrvAddr("139.155.54.93:9876");
        // 启动Producer
        producer.start();

        String topic = "myTopic001";
        String topic2 = "myTopic002";
        // 创建消息对象,topic为:myTopic001,消息内容为:hello world1/2/3
        Message msg1 = new Message(topic, "hello world1".getBytes());
        Message msg2 = new Message(topic, "hello world2".getBytes());
        Message msg3 = new Message(topic, "hello world3".getBytes());
        // 创建消息对象的集合,用于批量发送
        List<Message> msgs = new ArrayList<>();
        msgs.add(msg1);
        msgs.add(msg2);
        msgs.add(msg3);
        // 批量发送的api的也是send(),只是他的重载方法支持List<Message>,同样是同步发送。
        SendResult result = producer.send(msgs);
        System.out.println("发送消息成功!result is : " + result);
        // 关闭Producer
        producer.shutdown();
        System.out.println("生产者 shutdown!");

事务消息

        TransactionMQProducer producer = new TransactionMQProducer("my-transation-producer");
        producer.setNamesrvAddr("139.155.54.93:9876");
        producer.setTransactionListener(new TransactionListener() {
    
    
            /**
             * 本地事务方法
             * @param message
             * @param arg
             * @return
             */
            @Override
            public LocalTransactionState executeLocalTransaction(Message message, Object arg) {
    
    
                LocalTransactionState state = null;
                //msg-1返回COMMIT_MESSAGE
                if(message.getKeys().equals("msg-1")){
    
    
                    state = LocalTransactionState.COMMIT_MESSAGE;
                }
                //msg-2返回ROLLBACK_MESSAGE
                else if(message.getKeys().equals("msg-2")){
    
    
                    state = LocalTransactionState.ROLLBACK_MESSAGE;
                }else{
    
    
                    //这里返回unknown的目的是模拟执行本地事务突然宕机的情况(或者本地执行成功发送确认消息失败的场景)
                    state = LocalTransactionState.UNKNOW;
                }
                System.out.println(message.getKeys() + ",state:" + state);
                return state;
            }

            /**
             * 定时回查方法
             * @param messageExt
             * @return
             */
            @Override
            public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
    
    
                if (null != messageExt.getKeys()) {
    
    
                    switch (messageExt.getKeys()) {
    
    
                        case "msg-3":
                            System.out.println("msg-3 unknow");
                            return LocalTransactionState.UNKNOW;
                        case "msg-4":
                            System.out.println("msg-4 COMMIT_MESSAGE");
                            return LocalTransactionState.COMMIT_MESSAGE;
                        case "msg-5":
                            //查询到本地事务执行失败,需要回滚消息。
                            System.out.println("msg-5 ROLLBACK_MESSAGE");
                            return LocalTransactionState.ROLLBACK_MESSAGE;
                    }
                }
                return LocalTransactionState.COMMIT_MESSAGE;
            }
        });
        producer.start();
        //模拟发送5条消息
        for (int i = 1; i < 6; i++) {
    
    
            try {
    
    
                Message msg = new Message("transactionTopic", null, "msg-" + i, ("测试,这是事务消息! " + i).getBytes());
                producer.sendMessageInTransaction(msg, null);
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }

顺序消息

        DefaultMQProducer producer = new DefaultMQProducer("my-order-producer");
        producer.setNamesrvAddr("139.155.54.93:9876");
        producer.start();
        for (int i = 0; i < 10; i++) {
    
    
            Message message = new Message("orderTopic","order2","order-key", ("hello!" + i).getBytes());
            System.out.println("hello!" + i);
            producer.send(
                    // 要发的那条消息
                    message,
                    // queue 选择器 ,向 topic中的哪个queue去写消息
                    new MessageQueueSelector() {
    
    
                        // 手动 选择一个queue
                        @Override
                        public MessageQueue select(
                                // 当前topic 里面包含的所有queue
                                List<MessageQueue> mqs,
                                // 具体要发的那条消息
                                Message msg,
                                // 对应到 send() 里的 args,也就是2000前面的那个0
                                // 实际业务中可以把0换成实际业务系统的主键,比如订单号啥的,然后这里做hash进行选择queue等。
                                // 能做的事情很多,我这里做演示就用第一个queue,所以不用arg。
                                Object arg) {
    
    
                            // 向固定的一个queue里写消息,比如这里就是向第一个queue里写消息
                            MessageQueue queue = mqs.get(0);
                            // 选好的queue
                            return queue;
                        }
                    },
                    // 自定义参数:0
                    // 2000代表2000毫秒超时时间
                    0, 2000);
        }

定时消息(延迟消息)

延迟级别
“1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h”

设置延迟队列的level 如

message.setDelayTimeLevel(2);//延迟5秒

message.setDelayTimeLevel(5);//5表示延迟一分钟

        // 指定生产组名为my-producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        // 配置namesrv地址
        producer.setNamesrvAddr("139.155.54.93:9876");
        // 启动Producer
        producer.start();
        // 创建消息对象,topic为:myTopic001,消息内容为:hello world
        Message message = new Message("myTopic001", "schedule", "schedule-key", ("Hello schedule!").getBytes());
        //设置延迟队列的level,5表示延迟一分钟
        message.setDelayTimeLevel(5);
        // 发送消息到mq,同步
        SendResult result = producer.send(message);
        System.out.println("发送消息成功!result is : " + result);

        // 关闭Producer
        producer.shutdown();
        System.out.println("生产者 shutdown!");

代码地址
https://github.com/JsonTom888/MQProject/tree/master/rocketmq

猜你喜欢

转载自blog.csdn.net/weixin_43073775/article/details/109707075