RocketMQ 入门使用详解[通俗易懂]

RocketMQ 入门使用详解[通俗易懂]RocketMQ是阿里巴巴在2012年开源的分布式消息中间件,目前已经捐赠给Apache基金会,已经于2016年11月成为 Apache 孵化项目,相信RocketMQ的未来会发挥着越来越大的作用,将有更多的开发者因此受益。 本文仅对RocketMQ的简单实用做入门性介绍,不对RocketMQ的底层原理进行深入介绍,后续文章将对RocketMQ的原理做详细介绍。

大家好,又见面了,我是你们的朋友全栈君。

       RocketMQ是阿里巴巴在2012年开源的分布式消息中间件,目前已经捐赠给Apache基金会,已经于2016年11月成为 Apache 孵化项目,相信RocketMQ的未来会发挥着越来越大的作用,将有更多的开发者因此受益。

        本文仅对RocketMQ的简单实用做入门性介绍,不对RocketMQ的底层原理进行深入介绍,后续文章将对RocketMQ的原理做详细介绍。

        RocketMQ的Maven依赖:

   

<!-- https://mvnrepository.com/artifact/com.alibaba.rocketmq/rocketmq-client -->
<dependency>
    <groupId>com.alibaba.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>3.2.6</version>
</dependency>

     MQ的消费类RocketMQConsumer.java:

    

package com.lance.rocketMQ.RocketMQ;

import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.consumer.listener.MessageListener;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;

import java.util.UUID;


/**
 * Created by lance on 2017/2/10.
 */
public class RocketMQConsumer {

    private DefaultMQPushConsumer consumer;

    private MessageListener listener;

    protected String nameServer;

    protected String groupName;

    protected String topics;

    public RocketMQConsumer(MessageListener listener, String nameServer, String groupName, String topics) {
        this.listener = listener;
        this.nameServer = nameServer;
        this.groupName = groupName;
        this.topics = topics;
    }

    public void init() {
        consumer = new DefaultMQPushConsumer(groupName);
        consumer.setNamesrvAddr(nameServer);
        try {
            consumer.subscribe(topics, "*");
        } catch (MQClientException e) {
            e.printStackTrace();
        }
        consumer.setInstanceName(UUID.randomUUID().toString());
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        consumer.registerMessageListener((MessageListenerConcurrently) this.listener);

        try {
            consumer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
        System.out.println("RocketMQConsumer Started! group=" + consumer.getConsumerGroup() + " instance=" + consumer.getInstanceName()
        );
    }


}

       MQ消息的监听接口类RocketMQListener.java

      

        

package com.lance.rocketMQ.RocketMQ;

import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import com.alibaba.rocketmq.common.message.MessageExt;

import java.util.List;

/**
 * Created by lance on 2017/2/10.
 */
public class RocketMQListener  implements MessageListenerConcurrently {


    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
//        System.out.println("get data from rocketMQ:" + msgs);
        for (MessageExt message : msgs) {

            String msg = new String(message.getBody());
            System.out.println("msg data from rocketMQ:" + msg);
        }

        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
}

        MQ消息的生产者类RocketMQProducer.java

package com.lance.rocketMQ.RocketMQ;

import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.client.producer.SendStatus;
import com.alibaba.rocketmq.common.message.Message;

import java.util.UUID;

/**
 * Created by lance on 2017/2/10.
 */
public class RocketMQProducer {

    private DefaultMQProducer sender;

    protected String nameServer;

    protected String groupName;

    protected String topics;

    public void init() {
        sender = new DefaultMQProducer(groupName);
        sender.setNamesrvAddr(nameServer);
        sender.setInstanceName(UUID.randomUUID().toString());
        try {
            sender.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }

    public RocketMQProducer(String nameServer, String groupName, String topics) {
        this.nameServer = nameServer;
        this.groupName = groupName;
        this.topics = topics;
    }

    public void send(Message message) {

        message.setTopic(topics);

        try {
            SendResult result = sender.send(message);
            SendStatus status = result.getSendStatus();
            System.out.println("messageId=" + result.getMsgId() + ", status=" + status);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

       测试RocketMQ的消费 RocketMQConsumerTest.java

package com.lance.rocketMQ.RocketMQ;

/**
 * Created by lance on 2017/2/10.
 */
public class RocketMQConsumerTest {


    public static void main(String[] args) {


        String mqNameServer = "172.10.254.2:9876";
        String mqTopics = "MQ-MSG-TOPICS-TEST";

        String consumerMqGroupName = "CONSUMER-MQ-GROUP";
        RocketMQListener mqListener = new RocketMQListener();
        RocketMQConsumer mqConsumer = new RocketMQConsumer(mqListener, mqNameServer, consumerMqGroupName, mqTopics);
        mqConsumer.init();


        try {
            Thread.sleep(1000 * 60L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

          run RocketMQConsumerTest.java 之后,控制台输出:

       

RocketMQConsumer Started! group=CONSUMER-MQ-GROUP instance=1eb7d308-4414-4658-90b5-e2cae3b793eb

            结果分析: 此时MQ对应的TOPIC中并没有响应的消息,故收不到消息,仅看到MQ消费者正常启动信息。

       

        MQ的生产者测试类:RocketMQProducerTest.java

       

package com.lance.rocketMQ.RocketMQ;

import com.alibaba.rocketmq.common.message.Message;

/**
 * Created by lance on 2017/2/10.
 */
public class RocketMQProducerTest {

    public static void main(String[] args) {

        String mqNameServer = "172.10.254.2:9876";
        String mqTopics = "MQ-MSG-TOPICS-TEST";

        String producerMqGroupName = "PRODUCER-MQ-GROUP";
        RocketMQProducer mqProducer = new RocketMQProducer(mqNameServer, producerMqGroupName, mqTopics);
        mqProducer.init();


        for (int i = 0; i < 5; i++) {

            Message message = new Message();
            message.setBody(("I send message to RocketMQ " + i).getBytes());
            mqProducer.send(message);
        }



    }

}

          run RocketMQProducerTest.java 之后,RocketMQProducerTest.java 对应的控制台输出为:

                

messageId=0A71290100002A9F00000003D0BB0832, status=SEND_OK
messageId=0A71290100002A9F00000003D0BB08BB, status=SEND_OK
messageId=0A71290100002A9F00000003D0BB0944, status=SEND_OK
messageId=0A71290100002A9F00000003D0BB09CD, status=SEND_OK
messageId=0A71290300002A9F000000005440AEED, status=SEND_OK

         结果分析:表明所有消息都已经正常发送,且被RocketMQ正常接收。

          此时查看RocketMQConsumerTest.java对应的控制台输出发生改变,输出内容变更如下:

         

RocketMQConsumer Started! group=CONSUMER-MQ-GROUP instance=1eb7d308-4414-4658-90b5-e2cae3b793eb
msg data from rocketMQ:I send message to RocketMQ 1
msg data from rocketMQ:I send message to RocketMQ 0
msg data from rocketMQ:I send message to RocketMQ 3
msg data from rocketMQ:I send message to RocketMQ 2
msg data from rocketMQ:I send message to RocketMQ 4

看,简单吧!

备注:小编自己使用了Apache版本的RocketMQ(即RocketMQ 4.*),发现只需要更改import的package的路径而已,不需要修改其他代码,请参考。

RocketMQ的重复问题解决方式:
a.MQ的消费端执行的操作具有幂等性,即无论多少次重复执行,其结果是一样的;
b.MQ的消费端做重复校验,比如将受到MQ消息的唯一编号保存到Redis中,即每次收到消息时,将检查唯一编号是否已经在Redis中,如果存在说明消息重复;否则将唯一编号放入到Redis中,可以根据系统需要设置唯一编号在Redis中的过期时间,以防止Redis溢出。

 

参考链接:1.分布式开放消息系统(RocketMQ)的原理与实践 (强烈推荐)

                    2.RocketMQ捐赠给Apache那些鲜为人知的故事

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149571.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java 基础练习题

    Java 基础练习题1.java类名命名规则答:1.大驼峰命名法2.不能以数字开头3.不能使用关键字,但是可以包含关键字4.数字.字母._,$5.见名知意2.java变量名(标识符)的命名规则和注意事项1.小驼峰命名法2.不能以数字开头3.不能使用关键字,但是可以包含关键字4.数字.字母._,$5.见名知意注意事项:1.相同作用域中不允许重复定义2.变量未经初始化,不允许使用3.一条语句可以定义多个相同类型的变量3.求成绩占总成绩的百分比doublescore=90;double

    2022年7月7日
    18
  • 2019年长沙前端技术分享大会圆满成功

    做一个积极的人编码、改bug、提升自己我有一个乐园,面向编程,春暖花开!本文首发: 唐胡子俱乐部,授权发布!摘要长沙百名互联网前端程序员齐聚长沙互联网活动基地(唐胡子俱乐部)。主办单位:唐胡子俱乐部支持单位:芒果TV,拓维,湘邮,58到家,御泥坊,兴盛优选,中软国际,长海科技,长沙联通时 间:2019年5月19日—————————-…

    2022年2月28日
    401
  • vue双向数据绑定原理面试_vue双向绑定原理

    vue双向数据绑定原理面试_vue双向绑定原理vue.js则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。vue实现双向数据绑定的原理就是利用了Object.defineProperty()这个方法重新定义了对象获取属性值(get)和设置属性值(set…

    2022年10月18日
    5
  • mysql tinyint长度_mysql设置取值范围0到100

    mysql tinyint长度_mysql设置取值范围0到100Tinyint占用1字节的存储空间,即8位(bit)。那么Tinyint的取值范围怎么来的呢?我们先看无符号的情况。无符号的最小值即全部8位(bit)都为0,换算成十进制就是0,所以无符号的Tinyint的最小值为0.无符号的最大值即全部8bit都为1,11111111,换算成十进制就是255.这很好理解。有符号的Tinyint的取值范围是怎么来的呢?在计算机中,用最高位表示符号。0表示正,1表示…

    2022年9月16日
    1
  • 用R语言绘制ROC曲线

    用R语言绘制ROC曲线1roc曲线的意义ROC曲线就是用来判断诊断的正确性,最理想的就是曲线下的面积为1,比较理想的状态就是曲线下的面积在0.8-0.9之间,0.5的话对实验结果没有什么影响。如图:2代码部分install.packages(“pROC”)install.packages(“ggplot2”)library(pROC)library(ggplot2)#建立曲线data(aSAH)…

    2022年5月17日
    143
  • TM影像波段介绍「建议收藏」

    TM影像波段介绍「建议收藏」一、各波段特征:1.TM10.45-0.52um,蓝波段,对水体穿透强,对叶绿素与叶色素反映敏感,有助于判别水深及水中叶绿素分布以及水中是否有水华等.2.TM20.52-0.60um,绿波段,对健康茂盛植物的反射敏感,对力的穿透力强,用于探测健康植物绿色反射率,按绿峰反射评价植物的生活状况,区分林型,树种和反映水下特征.3.TM30.62-0.69UM,红波段,叶绿

    2022年7月23日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号