RoceketMQ基本消息样例代码

1、基本消息样例:

消息生产者一共采取三种方式发送消息:同步发送、异步发送、单向发送。然后消费者采用push或pull模式消费消息。

RocketMQ的生产者和消费者的编程模型都是有个比较固定的步骤的:

  • 消息发送者的固定步骤

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

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

1.1、同步发送消息样例

        等待消息返回后再继续进行下面的操作。

package org.apache.rocketmq.example.simple;

import org.apache.rocketmq.client.exception.MQClientException;
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 Producer {
    public static void main(String[] args) throws MQClientException, InterruptedException {

        //todo:1.创建Producer,并指定生产者组名
        DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
        
        //todo:2.指定NameServer地址
        producer.setNamesrvAddr("127.0.0.1:9876");
        
        //todo:3.启动Producer
        producer.start();
       
        for (int i = 0; i < 128; i++)
            try {
                {
                    //todo:4.创建消息对象,指定主题Topic、Tag和消息体
                    Message msg = new Message("TopicTest",
                        "TagA",
                        "OrderID188",
                        "Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));
                    //todo:5.发送消息到一个Broker
                    SendResult sendResult = producer.send(msg);
                    System.out.printf("%s%n", sendResult);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

        //todo:6.如果不再使用,调用shutdown方法关闭Producer实例
        producer.shutdown();
    }
}

同步消息发送日志

运行日志参数分析:

1. msgId

消息的全局唯一标识(RocketMQ的ID生成是使用机器IP和消息偏移量的组成),由消息队列 MQ 系统自动生成,唯一标识某条消息。

2. sendStatus

发送的标识:成功,失败等
3. queueId
queueId是Topic的分区;Producer发送具体一条消息的时,对应选择的该Topic下的某一个Queue的标识ID。
4. queueOffset
Message queue是无限长的数组。一条消息进来下标就会涨1,而这个数组的下标就是queueOffset,queueOffset是从0开始递增。

1.2、异步发送消息样例

        异步消息通常用在对响应时间敏感的业务场景,即消息发送方在发送一条消息后,不等待接收方相应,直接进行第二条消息的发送。发送方通过回调接口的方式接收服务器响应,并对结果进行处理。

        这个示例有个比较有趣的地方就是引入了一个countDownLatch来保证所有消息回调方法都执行 完了再关闭Producer。 所以从这里可以看出,RocketMQ的Producer也是一个服务端,在往Broker发送消息的时候也要作为服务端提供服务,消息队列 RocketMQ 的异步发送,需要用户实现异步发送回调接口(SendCallback)

package org.apache.rocketmq.example.simple;

import java.io.UnsupportedEncodingException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.rocketmq.client.exception.MQClientException;
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 MQClientException, InterruptedException, UnsupportedEncodingException {

        //todo:1.创建Producer,并指定生产者组名
        DefaultMQProducer producer = new DefaultMQProducer("Jodie_Daily_test");
        //todo;2.指定NameServer地址
        producer.setNamesrvAddr("127.0.0.1:9876");

        //todo:3.启动Producer
        producer.start();
        
        producer.setRetryTimesWhenSendAsyncFailed(0);

        int messageCount = 100;
        final CountDownLatch countDownLatch = new CountDownLatch(messageCount);
        for (int i = 0; i < messageCount; i++) {
            try {
                final int index = i;
                //todo:4.创建消息对象,指定主题Topic、Tag和消息体
                Message msg = new Message("Jodie_topic_1023",
                    "TagA",
                    "OrderID188",
                    "Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));
                //todo:5.实现回调接口SendRollback接收异步返回结果
                producer.send(msg, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        countDownLatch.countDown();
                        System.out.printf("%-10d OK %s %n", index, sendResult.getMsgId());
                    }

                    @Override
                    public void onException(Throwable e) {
                        countDownLatch.countDown();
                        System.out.printf("%-10d Exception %s %n", index, e);
                        e.printStackTrace();
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //todo:引入countDownLatch来保证所有消息回调方法都执行完了再关闭Producer
        countDownLatch.await(5, TimeUnit.SECONDS);
        //todo: conutDown到0的时候再进行关闭
        producer.shutdown();
    }
}

1.3、单向发送消息的样例

        关键点就是使用producer.sendOneWay方式来发送消息,这个方法没有返回值,也没有回调。 就是只管把消息发出去就行了。

public class OnewayProducer {
    public static void main(String[] args) throws Exception{
    //Instantiate with a producer group name.
        DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
    // Specify name server addresses.
        producer.setNamesrvAddr("localhost:9876");
    //Launch the instance. producer.start();
        for (int i = 0; i < 100; i++) {
        //Create a message instance, specifying topic, tag and message body.
            Message msg = new Message("TopicTest" /* Topic */, 
                                      "TagA" /* Tag */,
                                      ("Hello RocketMQ " +
                                            i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
                                      );
            //Call send message to deliver message to one of brokers.
            producer.sendOneway(msg);
        }
            //Wait for sending to complete 
            Thread.sleep(5000); 
            producer.shutdown();
    }
}

2、消费者消费消息

        消费者消费消息有两种模式,第一种是主动去Broker上拉取消息(pull);第二种是消费者等待Broker推送消息(push),通产情况下,用推模式比较简单,实际上RocketMQ的push模式也是由pull模式封装过来的。

2.1、拉模式的样例如下(pull):


package org.apache.rocketmq.example.simple;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.rocketmq.client.consumer.DefaultMQPullConsumer;
import org.apache.rocketmq.client.consumer.PullResult;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageQueue;

public class PullConsumer {
    private static final Map<MessageQueue, Long> OFFSE_TABLE = new HashMap<MessageQueue, Long>();

    public static void main(String[] args) throws MQClientException {
        DefaultMQPullConsumer consumer = new DefaultMQPullConsumer("please_rename_unique_group_name_5");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.start();

        Set<MessageQueue> mqs = consumer.fetchSubscribeMessageQueues("broker-a");
        for (MessageQueue mq : mqs) {
            System.out.printf("Consume from the queue: %s%n", mq);
            SINGLE_MQ:
            while (true) {
                try {
                    PullResult pullResult =
                        consumer.pullBlockIfNotFound(mq, null, getMessageQueueOffset(mq), 32);
                    System.out.printf("%s%n", pullResult);
                    putMessageQueueOffset(mq, pullResult.getNextBeginOffset());
                    switch (pullResult.getPullStatus()) {
                        case FOUND:
                            break;
                        case NO_MATCHED_MSG:
                            break;
                        case NO_NEW_MSG:
                            break SINGLE_MQ;
                        case OFFSET_ILLEGAL:
                            break;
                        default:
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        consumer.shutdown();
    }

    private static long getMessageQueueOffset(MessageQueue mq) {
        Long offset = OFFSE_TABLE.get(mq);
        if (offset != null)
            return offset;

        return 0;
    }

    private static void putMessageQueueOffset(MessageQueue mq, long offset) {
        OFFSE_TABLE.put(mq, offset);
    }

}

2.2、推模式的样例如下(push):

package org.apache.rocketmq.example.simple;

import java.util.List;
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.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class PushConsumer {

    public static void main(String[] args) throws InterruptedException, MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("CID_JODIE_1");
        consumer.subscribe("TopicTest", "*");
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        //wrong time format 2017_0422_221800
        consumer.setConsumeTimestamp("20181109221800");
        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            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");
    }
}

消息发送的权衡:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值