RocketMQ(四):生产者消费者实践

准备工作

先用命令创建Topic,执行成功后默认会创建8个队列

sh mqadmin updateTopic -b localhost:10911 -n localhost:9876 -t TopicTest

Producer发送消息时,Topic不存在也会自动创建,但是一般不建议这样做。

同步生产

发送消息时,等待返回结果才发送下一条。速度相对慢一点,消息不易丢失。

public class SyncProducer {
    
    
    public static void main(String[] args) throws Exception {
    
    
        final String producerGroup = "default_producer";
        final String topic = "TopicTest";
        //实例化消息生产者Producer
        DefaultMQProducer producer = new DefaultMQProducer(producerGroup);
        //设置NameServer的地址
        producer.setNamesrvAddr("192.168.25.131:9876");
        //启动Producer实例
        producer.start();
        for (int i = 0; i < 20; i++) {
    
    
            //创建消息,并指定Topic,Tag和消息体
            byte[] body = ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET);
            Message message = new Message(topic, "TagA", body);
            //发送消息(同步)
            SendResult result = producer.send(message);
            System.out.println(result);
        }
        //关闭
        producer.shutdown();
    }
}

异步生产

发送消息时,RocketMQ底层会调用线程池进行异步发送。延迟低,速度快,存在消息丢失的可能。

public class AsyncProducer {
    
    
    public static void main(String[] args) throws Exception {
    
    
        final String producerGroup = "default_producer";
        final String topic = "TopicTest";
        //实例化消息生产者Producer
        DefaultMQProducer producer = new DefaultMQProducer(producerGroup);
        //设置NameServer的地址
        producer.setNamesrvAddr("192.168.25.131:9876");
        //启动Producer实例
        producer.start();
        for (int i = 0; i < 10; i++) {
    
    
            //创建消息,并指定Topic,Tag和消息体
            byte[] body = ("async message-" + i).getBytes(RemotingHelper.DEFAULT_CHARSET);
            Message message = new Message(topic, "TagA", body);
            //发送消息
            producer.send(message, new SendCallback() {
    
    
                @Override
                public void onSuccess(SendResult sendResult) {
    
    
                    System.out.println("异步发送:" + sendResult);
                }

                @Override
                public void onException(Throwable throwable) {
    
    
                    throwable.printStackTrace();
                }
            });
        }
        //由于是异步方式,这里先等待一段时间,再关闭producer。避免出现消息未全部发送,就已经关闭了
        Thread.sleep(5000);
        
        producer.shutdown();
    }
}

有序消费

前面的文章提过:一个Topic可能会存在多个消息队列。

有序消费的意思,就是保证相同队列的消息是顺序消费的,先进先出;但是不保证全局的有序。

public class OrderlyConsumer {
    
    
    public static void main(String[] args) throws Exception {
    
    
        final String consumerGroup = "default_consumer";
        final String topic = "TopicTest";
        //实例化消费者
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(consumerGroup);
        //设置NameServer的地址
        consumer.setNamesrvAddr("192.168.25.131:9876");
        //订阅一个或者多个Topic,以及Tag来过滤需要消费的消息
        consumer.subscribe(topic, "*");
        //注册回调实现类来处理从broker拉取回来的消息
        consumer.registerMessageListener(new MessageListenerOrderly() {
    
    
            @Override
            public ConsumeOrderlyStatus consumeMessage(List<MessageExt> list, ConsumeOrderlyContext consumeOrderlyContext) {
    
    
                for (MessageExt msgExt : list) {
    
    
                    byte[] body = msgExt.getBody();
                    System.out.println(Thread.currentThread().getName() + ":" + new String(body));
                }
                // 标记该消息已经被成功消费
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
        // 启动消费者实例
        consumer.start();
        System.out.printf("启动成功");
    }
}

并发消费

保证相同队列的消息是并发消费的,不保证任何顺序性,性能最快

public class ConcurrentlyConsumer {
    
    
    public static void main(String[] args) throws Exception {
    
    
        final String consumerGroup = "default_consumer";
        final String topic = "TopicTest";
        //实例化消费者
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(consumerGroup);
        //设置NameServer的地址
        consumer.setNamesrvAddr("192.168.25.131:9876");
        //订阅一个或者多个Topic,以及Tag来过滤需要消费的消息
        consumer.subscribe(topic, "*");
        //注册回调实现类来处理从broker拉取回来的消息
        consumer.registerMessageListener(new MessageListenerConcurrently() {
    
    
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
    
    
                for (MessageExt ext : list) {
    
    
                    System.out.println(Thread.currentThread().getName() + "," + ext.getQueueId() + "," + new String(ext.getBody()));
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        // 启动消费者实例
        consumer.start();
        System.out.printf("Consumer Started");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_28834355/article/details/113496724