rocketmq 客户端消息生产消费Demo测试

rocketmqdemo测试

1.创建工程引入maven依赖

服务端使用的4.9.1,java客户端使用4.5.0的包

    <dependencies>
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
            <version>4.5.0</version>
        </dependency>
    </dependencies>

2.消息生产者

1.创建消息生产者producer,并制定生产者组名
2.指定Nameserver地址
3.启动producer
4.创建消息对象,指定主题Topic、Tag和消息体
5.发送消息
6.关闭生产者producer

3.消息消费者

1.创建消费者Consumer,制定消费者组名
2.指定Nameserver地址
3.订阅主题Topic和Tag
4.设置回调函数,处理消息
5.启动消费者consumer

消息发送

1.发送同步消息

package com.test.mq.rocketmq.base.producer;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.protocol.body.ProducerConnection;
import org.apache.rocketmq.remoting.common.RemotingHelper;

import java.util.concurrent.TimeUnit;

/**
 * 发送同步消息
 **/
public class SyncProducer {
//1.创建消息生产者producer,并制定生产者组名
//2.指定Nameserver地址
//3.启动producer
//4.创建消息对象,指定主题Topic、Tag和消息体
//5.发送消息
//6.关闭生产者producer
    public static void main(String[] args) throws Exception {
        // 实例化消息生产者Producer
        DefaultMQProducer producer = new DefaultMQProducer("group1");
        // 设置NameServer的地址
        producer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
        producer.setSendMsgTimeout(6000);
        // 启动Producer实例
        producer.start();
        for (int i = 0; i < 10; i++) {
            // 创建消息,并指定Topic,Tag和消息体
            Message msg = new Message("TopicTest" /* Topic */,
                    "TagB" /* Tag */,
                    ("Hello RocketMQHJW " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
            );
            // 发送消息到一个Broker
            SendResult sendResult = producer.send(msg);
            // 通过sendResult返回消息是否成功送达
            System.out.printf("%s%n", sendResult);
            Thread.sleep(1000);
//            TimeUnit.SECONDS.sleep(10);
        }
        // 如果不再发送消息,关闭Producer实例。
        producer.shutdown();
    }
}

其中遇到的问题会有同步发送消息超时,解决方案,设置一下java客户端发送消息超时时间
https://blog.csdn.net/qq_16241519/article/details/103926356
在这里插入图片描述
发送消息的返回值如下情况,显示了消息发送在哪个broker下
在这里插入图片描述

2.发送异步消息

和发送同步消息基本一样,只是在producer.send的时候写入返回如果成功或者异常的时候如何处理

package com.test.mq.rocketmq.base.producer;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;

/**
 * 发送异步消息
 **/
public class AsyncProducer {
    public static void main(String[] args) throws Exception {
        // 实例化消息生产者Producer
        DefaultMQProducer producer = new DefaultMQProducer("group2");
        // 设置NameServer的地址
        producer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
        producer.setSendMsgTimeout(6000);
        // 启动Producer实例
        producer.start();
//        producer.setRetryTimesWhenSendAsyncFailed(0);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            // 创建消息,并指定Topic,Tag和消息体
            Message msg = new Message("TopicTest",
                    "TagB",
                    "Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));
            // SendCallback接收异步返回结果的回调
            producer.send(msg, new SendCallback() {
                public void onSuccess(SendResult sendResult) {
                    System.out.printf("%-10d OK %s %n", index,
                            sendResult.getMsgId());
                }
                public void onException(Throwable e) {
                    System.out.printf("%-10d Exception %s %n", index, e);
                    e.printStackTrace();
                }

            });
            Thread.sleep(1000);

        }
        // 如果不再发送消息,关闭Producer实例。
        producer.shutdown();
    }
}

发送结果如下
在这里插入图片描述

3.发送单向消息

如果生产者不关心消息发送是否成功失败的情况可以使用,例如发送日志

package com.test.mq.rocketmq.base.producer;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;

/**
 * 发送单向消息
 **/
public class OnewayProducer {
    public static void main(String[] args) throws Exception{
        // 实例化消息生产者Producer
        DefaultMQProducer producer = new DefaultMQProducer("group1");
        // 设置NameServer的地址
        producer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
        producer.setSendMsgTimeout(6000);
        // 启动Producer实例
        producer.start();
        for (int i = 0; i < 100; i++) {
            // 创建消息,并指定Topic,Tag和消息体
            Message msg = new Message("TopicTest" /* Topic */,
                    "TagA" /* Tag */,
                    ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
            );
            // 发送单向消息,没有任何返回结果
            producer.sendOneway(msg);
            Thread.sleep(1000);

        }
        // 如果不再发送消息,关闭Producer实例。
        producer.shutdown();
    }
}

消息消费

消费广播模式和负载均衡模式不同

consumer.setMessageModel(MessageModel.BROADCASTING);
consumer.setMessageModel(MessageModel.CLUSTERING);

在这里插入图片描述

1.消息消费负载均衡模式

package com.test.mq.rocketmq.base.consumer;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.util.List;

/**
 * 消息接收者
 **/
public class Consumer {
//1.创建消费者Consumer,制定消费者组名
//2.指定Nameserver地址
//3.订阅主题Topic和Tag
//4.设置回调函数,处理消息
//5.启动消费者consumer
public static void main(String[] args) throws Exception {
    // 实例化消息生产者,指定组名
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
    // 指定Namesrv地址信息.
    consumer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
    // 订阅Topic
    consumer.subscribe("TopicTest", "TagB");
    //负载均衡模式消费
    consumer.setMessageModel(MessageModel.CLUSTERING);
    //    consumer.setMessageModel(MessageModel.BROADCASTING);

    // 注册回调函数,处理消息
    consumer.registerMessageListener(new MessageListenerConcurrently() {
        public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                        ConsumeConcurrentlyContext context) {
            System.out.printf("%s Receive New Messages: %s %n",
                    Thread.currentThread().getName(), msgs);
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
    });
    //启动消息者
    consumer.start();
    System.out.printf("Consumer Started.%n");
}
}

打印结果
在这里插入图片描述

2.消息消费广播模式

package com.test.mq.rocketmq.base.consumer;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.util.List;

/**
 * 消息接收者 负载均衡模式
 **/
public class Consumer {
//1.创建消费者Consumer,制定消费者组名
//2.指定Nameserver地址
//3.订阅主题Topic和Tag
//4.设置回调函数,处理消息
//5.启动消费者consumer
public static void main(String[] args) throws Exception {
    // 实例化消息生产者,指定组名
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
    // 指定Namesrv地址信息.
    consumer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
    // 订阅Topic
    consumer.subscribe("TopicTest", "TagB");
    //负载均衡模式消费
//    consumer.setMessageModel(MessageModel.CLUSTERING);
    consumer.setMessageModel(MessageModel.BROADCASTING);

    // 注册回调函数,处理消息
    consumer.registerMessageListener(new MessageListenerConcurrently() {
        public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                        ConsumeConcurrentlyContext context) {
            System.out.printf("%s Receive New Messages: %s %n",
                    Thread.currentThread().getName(), msgs);
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
    });
    //启动消息者
    consumer.start();
    System.out.printf("Consumer Started.%n");
}
}

在这里插入图片描述

顺序消息

在这里插入图片描述

在这里插入图片描述

1.顺序消息生产者

package com.test.mq.rocketmq.order;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description:顺序消息生产者
 **/
public class Producer {

    public static void main(String[] args) throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("ordergroup");

        producer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
        producer.setSendMsgTimeout(6000);

        producer.start();

        String[] tags = new String[]{"TagA", "TagC", "TagD"};

        // 订单列表
        List<OrderStep> orderList = new Producer().buildOrders();

        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdf.format(date);
        for (int i = 0; i < 10; i++) {
            // 加个时间前缀
            String body = dateStr + " Hello RocketMQ " + orderList.get(i);
            Message msg = new Message("OrderTopic", tags[i % tags.length], "KEY" + i, body.getBytes());
            /*
            参数一:消息对象
            参数二:消息队列的选择器
            参数三:选择队列的业务标识(订单id)
            */
            SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
                /*
                * mqs:队列集合
                * msg:消息对象
                * arg:业务标识的参数(订单id)
                * */
                public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
                    Long id = (Long) arg;  //根据订单id选择发送queue
                    long index = id % mqs.size();
                    return mqs.get((int) index);
                }
            }, orderList.get(i).getOrderId());//订单id

            System.out.println(String.format("SendResult status:%s, queueId:%d, body:%s",
                    sendResult.getSendStatus(),
                    sendResult.getMessageQueue().getQueueId(),
                    body));
        }
        producer.shutdown();
    }

    /**
     * 订单的步骤
     */
    private static class OrderStep {
        private long orderId;
        private String desc;

        public long getOrderId() {
            return orderId;
        }

        public void setOrderId(long orderId) {
            this.orderId = orderId;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }

        @Override
        public String toString() {
            return "OrderStep{" +
                    "orderId=" + orderId +
                    ", desc='" + desc + '\'' +
                    '}';
        }
    }

    /**
     * 生成模拟订单数据
     */
    private List<OrderStep> buildOrders() {
        List<OrderStep> orderList = new ArrayList<OrderStep>();

        OrderStep orderDemo = new OrderStep();
        orderDemo.setOrderId(15103111039L);
        orderDemo.setDesc("创建");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103111065L);
        orderDemo.setDesc("创建");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103111039L);
        orderDemo.setDesc("付款");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103117235L);
        orderDemo.setDesc("创建");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103111065L);
        orderDemo.setDesc("付款");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103117235L);
        orderDemo.setDesc("付款");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103111065L);
        orderDemo.setDesc("完成");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103111039L);
        orderDemo.setDesc("推送");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103117235L);
        orderDemo.setDesc("完成");
        orderList.add(orderDemo);

        orderDemo = new OrderStep();
        orderDemo.setOrderId(15103111039L);
        orderDemo.setDesc("完成");
        orderList.add(orderDemo);

        return orderList;
    }
}

可以看到每个订单的业务都是在同一个消息队列里面
在这里插入图片描述

2.顺序消息消费者

package com.test.mq.rocketmq.order;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.*;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.util.List;

/**
 * 消息接收者 负载均衡模式
 **/
public class Consumer {
//1.创建消费者Consumer,制定消费者组名
//2.指定Nameserver地址
//3.订阅主题Topic和Tag
//4.设置回调函数,处理消息
//5.启动消费者consumer
public static void main(String[] args) throws Exception {
    // 实例化消息生产者,指定组名
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ordergroup");
    // 指定Namesrv地址信息.
    consumer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
    // 订阅Topic
    consumer.subscribe("OrderTopic", "*");
    //负载均衡模式消费
//    consumer.setMessageModel(MessageModel.CLUSTERING);
    consumer.setMessageModel(MessageModel.BROADCASTING);

    // 注册回调函数,处理消息
    consumer.registerMessageListener(new MessageListenerOrderly() {

        public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs,
                                                        ConsumeOrderlyContext context) {
            for (MessageExt msg : msgs){
                System.out.println("ThreadName:"+Thread.currentThread().getName()+":Receive New Messages:"+new String(msg.getBody()));
            }
//            System.out.printf("%s Receive New Messages: %s %n",
//                    Thread.currentThread().getName(), msgs);
            return ConsumeOrderlyStatus.SUCCESS;
        }
    });
    //启动消息者
    consumer.start();
    System.out.printf("Consumer Started.%n");
}
}

可以看到每个业务订单的消息都是先创建再付款再推送最后完成
在这里插入图片描述

延时消息

1.延时消息生产者

使用Message msg.setDelayTimeLevel(2) 设置消息延迟时间
使用限制等级从1-18级别具体时间如下

// org/apache/rocketmq/store/config/MessageStoreConfig.java
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
    package com.test.mq.rocketmq.deplay;

    import org.apache.rocketmq.client.producer.DefaultMQProducer;
    import org.apache.rocketmq.client.producer.SendResult;
    import org.apache.rocketmq.common.message.Message;
    import org.apache.rocketmq.remoting.common.RemotingHelper;

    /**
     * 发送同步消息
     **/
    public class SyncProducer {
    //1.创建消息生产者producer,并制定生产者组名
    //2.指定Nameserver地址
    //3.启动producer
    //4.创建消息对象,指定主题Topic、Tag和消息体
    //5.发送消息
    //6.关闭生产者producer
        public static void main(String[] args) throws Exception {
            // 实例化消息生产者Producer
            DefaultMQProducer producer = new DefaultMQProducer("group1");
            // 设置NameServer的地址
            producer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
            producer.setSendMsgTimeout(6000);
            // 启动Producer实例
            producer.start();
            for (int i = 0; i < 10; i++) {
                // 创建消息,并指定Topic,Tag和消息体
                Message msg = new Message("DelayTopic" /* Topic */,
                        "TagB" /* Tag */,
                        ("Hello RocketMQHJW " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
                );
                msg.setDelayTimeLevel(2);
                // 发送消息到一个Broker
                SendResult sendResult = producer.send(msg);
                // 通过sendResult返回消息是否成功送达
                System.out.printf("%s%n", sendResult);
                Thread.sleep(1000);
    //            TimeUnit.SECONDS.sleep(10);
            }
            // 如果不再发送消息,关闭Producer实例。
            producer.shutdown();
        }
    }

2.延时消息消费者

package com.test.mq.rocketmq.deplay;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.util.List;

/**
 * 消息接收者 顺序消息消费者
 **/
public class Consumer {
//1.创建消费者Consumer,制定消费者组名
//2.指定Nameserver地址
//3.订阅主题Topic和Tag
//4.设置回调函数,处理消息
//5.启动消费者consumer
public static void main(String[] args) throws Exception {
    // 实例化消息生产者,指定组名
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ordergroup");
    // 指定Namesrv地址信息.
    consumer.setNamesrvAddr("10.211.55.10:9876;10.211.55.8:9876");
    // 订阅Topic
    consumer.subscribe("DelayTopic", "*");
    //负载均衡模式消费
//    consumer.setMessageModel(MessageModel.CLUSTERING);
    consumer.setMessageModel(MessageModel.BROADCASTING);

    // 注册回调函数,处理消息
    consumer.registerMessageListener(new MessageListenerConcurrently() {
        public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
            for (MessageExt msg : msgs){
                System.out.println("ThreadName:"+Thread.currentThread().getName()+":Receive New Messages:"+new String(msg.getBody())+"延迟时间:"+(System.currentTimeMillis()-msg.getStoreTimestamp()));
            }
//            System.out.printf("%s Receive New Messages: %s %n",
//                    Thread.currentThread().getName(), msgs);
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
    });

//    consumer.registerMessageListener(new MessageListenerOrderly() {
//        public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext consumeOrderlyContext) {
//            for (MessageExt msg : msgs){
//                System.out.println("ThreadName:"+Thread.currentThread().getName()+":Receive New Messages:"+new String(msg.getBody()));
//            }
            System.out.printf("%s Receive New Messages: %s %n",
                    Thread.currentThread().getName(), msgs);
//            return ConsumeOrderlyStatus.SUCCESS;
//        }
//
//    });
    //启动消息者
    consumer.start();
    System.out.printf("Consumer Started.%n");
}
}

在这里插入图片描述

批量消息

猜你喜欢

转载自blog.csdn.net/Persistence___/article/details/120636938