RocketMQ入门-RocketMQ的API学习

RocketMQ的API学习

目标是对rocketMq的生产和消费消息掌握,熟悉异步同步两种方式。

本篇基于RocketMQ集群开发,如需了解集群的搭建,可参考上一篇文章RocketMQ集群安装

项目构建

  1. 创建一个maven项目

  2. 引入依赖,建议和服务端RocketMQ版本保持一致

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

发送同步消息

定义公用常量类

MyRocketMqConstant中主要包括发送消息时需要传入的参数:

  • NAME_SRV:启动的namesrv的地址,多节点用;分割
  • SyncLearn:同步消息发送需要用到的生产者、消费者组,主题和tag
public interface MyRocketMqConstant {

    /**
     * 注册中心
     */
    String NAME_SRV="192.168.15.14:9876;192.168.15.15:9876;192.168.15.16:9876";


    /**
     * 同步学习
     */
    interface SyncLearn {
        /**
         * 生产者组
         */
        String SYNC_PRODUCER_GROUP = "sync-producer-group";
        /**
         * 主题
         */
        String SYNC_TOPIC = "sync-topic";
        /**
         * tag
         */
        String SYNC_TAG = "sync-tag";

        /**
         * 消费者组
         */
        String SYNC_CONSUMER_GROUP = "sync-consumer-group";
    }
}

定义Producer

一个生产者从创建出来到发送消息到Broker需要经历以下步骤:

  1. 调用构造方法DefaultMQProducer(final String producerGroup),创建一个组织为sync-producer-group的生产者
  2. 生产者对象调用setNamesrvAddr(String namesrvAddr)方法补充生产者将要注册的地址192.168.15.14:9876;192.168.15.15:9876;192.168.15.16:9876,注意多个IP使用;分割
  3. 生产者对象调用start()方法启动producer实例
  4. 调用Message(String topic, String tags, byte[] body)消息构造方法创建将要发送的消息;topic可以理解为消息的频道,生产者会把消息推送到指定的topic,消费者要消费此消息也需要指定相同的topic;tag可以理解为打在消息上的标签,消费者可利用 tag来进行过滤
  5. 生产者对象调用send(Message msg)使用同步方式将消息发送至Broker,同步操作能拿到SendResult类型的响应值
  6. 消息发送完毕时,生产者对象调用shutdown()方法关闭生产者
public class SyncProducer {

    public static void main(String[] args) throws Exception{

        // 1.实例化消息生产者,设置生产者组
        DefaultMQProducer defaultMQProducer = new DefaultMQProducer(MyRocketMqConstant.SyncLearn.SYNC_PRODUCER_GROUP);
        // 2.设置注册中心地址
        defaultMQProducer.setNamesrvAddr(MyRocketMqConstant.NAME_SRV);
        // 3.启动Producer实例
        defaultMQProducer.start();

        // 4.发送消息
        for (int i = 0; i < 20; i++) {
            String str = "Hello Rocket:" +i;
            // 创建消息,并指定topic和tag
            Message message = new Message(MyRocketMqConstant.SyncLearn.SYNC_TOPIC,
                    MyRocketMqConstant.SyncLearn.SYNC_TAG,
                    str.getBytes(StandardCharsets.UTF_8));
            // 发送消息到broker
            SendResult sendResult = defaultMQProducer.send(message);
            // 观察响应
            System.out.printf("生产者接收Broker的响应:%s%n",sendResult);
        }
        // 5.发送完毕,关闭Producer
        defaultMQProducer.shutdown();
    }
}

定义Consumer

消费者从Broker中消费消息需要经历以下步骤:

  1. 调用DefaultMQPushConsumer(final String consumerGroup)构造方法创建消费者对象,指定消费者的分组为sync-consumer-group
  2. 消费者对象调用setNamesrvAddr(String namesrvAddr)方法补充注册中心地址
  3. 消费者对象调用subscribe(String topic, String subExpression)方法订阅topic
  4. 消费者对象调用registerMessageListener(MessageListenerConcurrently messageListener)方法注册一个消息监听器来处理消费的消息
  5. 消费者对象调用start()方法开始消费
public class Consumer {

    public static void main(String[] args) throws Exception {

        // 1.创建消费者
        DefaultMQPushConsumer defaultMQPushConsumer = new DefaultMQPushConsumer(MyRocketMqConstant.SyncLearn.SYNC_CONSUMER_GROUP);

        // 2.设置注册中心
        defaultMQPushConsumer.setNamesrvAddr(MyRocketMqConstant.NAME_SRV);
        // 3.订阅一个或多个Topic,以及Tag来过滤需要消费的消息
        defaultMQPushConsumer.subscribe(MyRocketMqConstant.SyncLearn.SYNC_TOPIC,"*");

        // 4.注册回调实现类来处理从broker拉取回来的消息
        defaultMQPushConsumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                System.out.printf("%s 消费者接收到新消息:%s %n",Thread.currentThread().getName(),msgs);
                // 标记该消息已经被消费了
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        // 5.开始消费
        defaultMQPushConsumer.start();
        System.out.printf("消费者开始..%n");

    }
}

测试结果

  1. 运行生产者main方法

    RocketMQLog:WARN No appenders could be found for logger (io.netty.util.internal.PlatformDependent0).
    RocketMQLog:WARN Please initialize the logger system properly.
    生产者接收Broker的响应:SendResult [sendStatus=SEND_OK, msgId=7F000001329018B4AAC24B3E61E80000, offsetMsgId=C0A80F0F00002A9F0000000000035CD6, messageQueue=MessageQueue [topic=sync-topic, brokerName=broker-a, queueId=2], queueOffset=11]
    #省略多余的响应信息..............................
    
  2. 运行消费者main方法

    消费者开始..
    ConsumeMessageThread_1 消费者接收到新消息:[MessageExt [brokerName=broker-a, queueId=2, storeSize=206, queueOffset=11, sysFlag=0, bornTimestamp=1618468779497, bornHost=/192.168.15.1:61006, storeTimestamp=1618468779476, storeHost=/192.168.15.15:10911, msgId=C0A80F0F00002A9F0000000000035CD6, commitLogOffset=220374, bodyCRC=855890706, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='sync-topic', flag=0, properties={MIN_OFFSET=0, MAX_OFFSET=12, CONSUME_START_TIME=1618468779510, UNIQ_KEY=7F000001329018B4AAC24B3E61E80000, CLUSTER=rocketmq-cluster, WAIT=true, TAGS=sync-tag}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107, 101, 116, 58, 48], transactionId='null'}]] 
    #省略多余的响应信息..............................
    

发送异步消息

定义Producer

public class AsyncProducer {

    public static void main(String[] args) throws Exception {
        // 1.创建生产者
        DefaultMQProducer defaultMQProducer = new DefaultMQProducer(MyRocketMqConstant.AsyncLearn.ASYNC_PRODUCER_GROUP);
        // 2.设置注册中心
        defaultMQProducer.setNamesrvAddr(MyRocketMqConstant.NAME_SRV);
        // 3.启动生产者
        defaultMQProducer.start();
        defaultMQProducer.setRetryTimesWhenSendAsyncFailed(0);

        // 定义消息总数
        int messageCount = 100;
        // 根据消息数量实例化倒计时计算器
        final CountDownLatch2 countDownLatch2 = new CountDownLatch2(messageCount);
        for (int i = 0; i < messageCount; i++) {
            final int index = i;
            String str = "hello world"+i;
            // 4.创建消息,并指定topic和tag
            Message message = new Message(MyRocketMqConstant.AsyncLearn.ASYNC_TOPIC,
                    MyRocketMqConstant.AsyncLearn.ASYNC_TAG,
                    str.getBytes(StandardCharsets.UTF_8));
            // 5.异步发送消息到broker
            defaultMQProducer.send(message, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    System.out.printf("%-10d OK %s %n",index,sendResult.getMsgId());
                }

                @Override
                public void onException(Throwable e) {
                    System.out.printf("%-10d Exception %s %n",index,e);
                    e.printStackTrace();
                }
            });
        }
        // 6.等待5s
        countDownLatch2.await(5, TimeUnit.SECONDS);
        // 7.如果不再发送消息,关闭producer实例
        defaultMQProducer.shutdown();
    }
}

定义Consumer

可以复用发送同步消息的消费者,修改group和订阅的topic,topic要和上面的生产者发送消息的topic对应。

单向发送消息

定义Producer

public class OneWayProducer {

    public static void main(String[] args) throws Exception {
        // 1.实例化消息生产者producer
        DefaultMQProducer defaultMQProducer = new DefaultMQProducer(MyRocketMqConstant.OneWayLearn.ONE_WAY_LEARN_PRODUCER_GROUP);
        // 2.设置注册中心
        defaultMQProducer.setNamesrvAddr(MyRocketMqConstant.NAME_SRV);
        // 3.启动生产者
        defaultMQProducer.start();

        for (int i = 0; i < 100; i++) {
            String str="Hello RocketMQ "+i;
            // 4.创建消息,指定topic和tag
            Message message = new Message(MyRocketMqConstant.OneWayLearn.ONE_WAY_LEARN_TOPIC,
                    MyRocketMqConstant.OneWayLearn.ONE_WAY_LEARN_TAG,
                    str.getBytes(StandardCharsets.UTF_8));
            // 5.发送单项消息,没有任何返回结果
            defaultMQProducer.sendOneway(message);
        }
        // 如果不再发送消息,关闭Producer实例
        defaultMQProducer.shutdown();
    }
}

定义Consumer

可以复用复用发送同步消息的消费者,修改group和订阅的topic,topic要和上面的生产者发送消息的topic对应。

总结

生产者发送异步消息、同步消息、单向消息的区别在于send方法。

  • 发送同步消息:调用send(Message msg),会有一个SendResult返回值;这种可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知,短信通知。
  • 发送异步消息:调用send(Message msg,SendCallback sendCallback),无返回值;异步消息通常用在对响应时间敏感的业务场景,即发送端不能容忍长时间地等待Broker的响应。
  • 发送单向消息:调用sendOneway(Message msg),无返回值;这种方式主要用在不特别关心发送结果的场景,例如日志发送。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值