继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

RocketMQ初识资料:新手入门指南

喵喔喔
关注TA
已关注
手记 554
粉丝 103
获赞 606
概述

RocketMQ是一款由阿里巴巴开源的分布式消息中间件,提供高吞吐量和低延迟的消息传递能力,支持多种消息模型和高级功能。本文将详细介绍RocketMQ的架构、应用场景、与其他消息中间件的对比以及环境搭建和基本操作,帮助读者快速了解RocketMQ初识资料。

RocketMQ概述
RocketMQ简介

RocketMQ是由阿里巴巴开源的一款分布式消息中间件,其设计目标是提供高吞吐量、低延迟的消息传递能力,并具有高可用性和高可靠性。RocketMQ支持发布/订阅模型,并具有队列模型和主题模型,可以应用于多种场景,如异步解耦、流量削峰、数据传输等。RocketMQ的设计完全遵循Apache 2.0开源协议。

RocketMQ的架构设计包括Name Server、Broker、Producer、Consumer四个主要部分。Name Server作为路由中心,用于管理和维护Broker的地址列表,生产者和消费者通过Name Server获取Broker的地址信息;Broker作为消息中间件的节点,负责消息的存储、查询和路由操作;Producer作为消息的生产方,负责将消息发送到指定的Topic和Queue中;Consumer作为消息的消费方,负责从指定的Topic和Queue中消费消息。

RocketMQ还提供了消息过滤、消息重试、消息幂等性和消息延迟等高级功能,满足了不同场景下的业务需求。

RocketMQ应用场景

RocketMQ广泛应用于以下场景:

  1. 异步解耦:通过RocketMQ,生产者和消费者可以使用不同的系统,通过消息队列实现异步通信,降低系统之间的耦合度。
  2. 流量削峰:在业务高峰期,通过RocketMQ可以将流量削峰,缓解系统压力,使系统能够稳定运行。
  3. 数据传输:RocketMQ支持大规模、高可靠的数据传输,保证数据的完整性。
  4. 日志采集与聚合:RocketMQ可以将不同来源的日志信息采集并聚合,方便运维人员进行日志分析。
RocketMQ与其他消息中间件的对比

RocketMQ与Kafka、RabbitMQ等消息中间件对比,有如下特点:

  1. 高吞吐量:RocketMQ的设计目标之一就是提供高吞吐量的消息传递能力,经过测试,RocketMQ的每秒消息发送能力超过了20万条。
  2. 高性能:RocketMQ采用异步通信机制,减少了网络延迟和系统资源占用,提高了整体性能。
  3. 高可用性:RocketMQ支持集群部署,具有容错机制,能够保证系统的高可用性。
  4. 灵活性:RocketMQ支持多种消息模型,如队列模型、主题模型等,可以满足不同业务场景的需求。
  5. 稳定性:RocketMQ在消息发送、接收、存储等各个环节都做了大量的优化和改进,保证了整个系统的稳定性。
  6. 扩展性:RocketMQ支持水平扩展,可以根据业务需求动态调整系统规模,满足业务增长的需求。

RocketMQ与Kafka对比

  • 消息模型:RocketMQ支持队列和主题两种消息模型,而Kafka仅支持主题模型。
  • 消息持久化:RocketMQ可以配置消息在磁盘上的持久化,而Kafka的消息持久化方式是通过日志文件实现的,RocketMQ在消息存储方面提供了更多的灵活性。
  • 消息过滤:RocketMQ支持在消费端进行消息过滤,而Kafka需要在生产端过滤消息。
  • 消息顺序性:RocketMQ支持消息顺序性,适合处理需要保证顺序的消息场景;Kafka在同一个分区内的消息是有序的,但多个分区之间没有顺序保证。
  • 消息重试:RocketMQ支持消息重试机制,而Kafka需要依赖外部机制来实现消息重试。

RocketMQ与RabbitMQ对比

  • 消息模型:RocketMQ支持队列和主题模型,而RabbitMQ支持交换机、队列等模型。
  • 消息持久化:RocketMQ支持消息持久化,而RabbitMQ需要通过配置持久化队列和消息来实现。
  • 消息过滤:RocketMQ支持消费者端消息过滤,而RabbitMQ支持在生产端消息过滤。
  • 消息顺序性:RocketMQ支持消息顺序性,而RabbitMQ支持通过配置队列来保证消息的顺序性。
  • 消息重试:RocketMQ支持消息重试机制,而RabbitMQ需要依赖外部机制来实现消息重试。
  • 集群部署:RocketMQ支持集群部署,具有容错机制;RabbitMQ也支持集群部署,但相比RocketMQ,RabbitMQ的集群部署配置更加复杂。
RocketMQ环境搭建

快速下载RocketMQ

RocketMQ的下载地址为:https://github.com/apache/rocketmq。下载RocketMQ源代码后,需要解压压缩包,得到RocketMQ的源代码目录。

wget https://github.com/apache/rocketmq/archive/refs/heads/master.zip
unzip master.zip
cd rocketmq-master

安装及配置RocketMQ

RocketMQ的安装和配置过程相对简单。首先,确保已安装JDK环境。然后,配置RocketMQ的配置文件。RocketMQ的配置文件主要位于conf目录下,如broker.conflogback_broker.xml等。

配置文件的关键部分,如broker.properties

# broker的唯一标识
brokerId=0
# broker名称
brokerName=broker-a
# broker的IP地址
brokerIP1=127.0.0.1
# Name Server地址
namesrvAddr=127.0.0.1:9876
# 是否启动消息发送
sendMessageThreadPoolNums=16
# 是否启动消息接收
pullMessageThreadPoolNums=16

配置完成后,启动Name Server和Broker服务。

启动RocketMQ服务

RocketMQ的启动脚本位于bin目录下,使用start脚本启动Name Server和Broker服务。

# 启动Name Server
./mqnamesrv

# 启动Broker
./mqbroker -n 127.0.0.1:9876 -c conf/2m-n1-s1/db/broker-a.properties

启动成功后,可以通过命令查看RocketMQ的服务状态。

./mqadmin topicList 127.0.0.1:9876
RocketMQ核心概念

消息模型

RocketMQ支持两种消息模型:队列模型和主题模型。

  1. 队列模型:队列模型是一种一对一的消息传递模型,消息从生产者发送到指定的队列中,消费者从该队列中消费消息。队列模型具有消息顺序性,保证消息按照发送顺序进行消费。
  2. 主题模型:主题模型是一种一对多的消息传递模型,消息从生产者发送到指定的主题中,消费者从该主题中消费消息。主题模型支持广播模式,即一条消息可以被多个消费者同时消费。

主题及队列

在RocketMQ中,主题和队列是消息传递的基本单位。

  • 主题:主题是一个逻辑上的概念,用于区分不同的消息类型。生产者可以将消息发布到指定的主题中,消费者可以订阅指定的主题来消费消息。
  • 队列:队列是消息的物理存储单位,每个主题可以关联一个或多个队列。RocketMQ使用队列来进行消息的存储和消费,保证消息的顺序性。

生产者与消费者

  • 生产者:生产者负责将消息发送到指定的Topic和Queue中。生产者可以配置消息的属性,如消息的优先级、过期时间等。
  • 消费者:消费者负责从指定的Topic和Queue中消费消息。消费者可以配置消息的过滤规则,如按照消息的标签进行过滤。
RocketMQ基本操作

发送消息

发送消息是生产者的基本操作,生产者可以将消息发送到指定的Topic和Queue中。以下是一个发送消息的示例代码,使用Java SDK实现。

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

public class Producer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
        // 设置Name Server地址
        producer.setNamesrvAddr("127.0.0.1:9876");
        // 启动生产者
        producer.start();

        // 创建消息
        Message msg = new Message("TopicTest", // topic
            "TagA", // tag
            "Hello RocketMQ".getBytes(RemotingHelper.DEFAULT_CHARSET), // body
            null // properties
        );
        // 发送消息
        SendResult sendResult = producer.send(msg);
        System.out.printf("%s%n", sendResult);

        // 关闭生产者
        producer.shutdown();
    }
}

接收消息

接收消息是消费者的基本操作,消费者可以从指定的Topic和Queue中消费消息。以下是一个接收消息的示例代码,使用Java SDK实现。

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class Consumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        // 设置Name Server地址
        consumer.setNamesrvAddr("127.0.0.1:9876");
        // 订阅指定的Topic和Tag
        consumer.subscribe("TopicTest", "*");
        // 设置从队列头部开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener(new MessageListenerOrderly() {
            @Override
            public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
                for (MessageExt msg : msgs) {
                    System.out.printf("Receive New Messages: %s %n", new String(msg.getBody()));
                }
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
        // 启动消费者
        consumer.start();
    }
}

消息订阅与过滤

RocketMQ支持在消费端进行消息过滤,消费者可以订阅指定的Topic和Tag,并且可以设置过滤规则,如按照消息的标签进行过滤。以下是一个订阅和过滤消息的示例代码,使用Java SDK实现。

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class FilterConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        // 设置Name Server地址
        consumer.setNamesrvAddr("127.0.0.1:9876");
        // 订阅指定的Topic和Tag,并设置过滤规则
        consumer.subscribe("TopicTest", "TagA");
        // 设置从队列头部开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener(new MessageListenerOrderly() {
            @Override
            public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
                for (MessageExt msg : msgs) {
                    System.out.printf("Receive Message: %s %n", new String(msg.getBody()));
                }
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
        // 启动消费者
        consumer.start();
    }
}
RocketMQ常用功能

消息重试

消息重试是指当消费者消费消息失败时,RocketMQ会自动将消息重新放到队列中,等待其他消费者进行消费。消息重试机制保证了消息不会丢失,提高了系统的可靠性。以下是一个配置消息重试的示例代码,使用Java SDK实现。

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.common.consumer.MessageQueue;

public class RetryConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        // 设置Name Server地址
        consumer.setNamesrvAddr("127.0.0.1:9876");
        // 订阅指定的Topic和Tag
        consumer.subscribe("TopicTest", "*");
        // 设置从队列头部开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((msgs, context) -> {
            for (MessageExt msg : msgs) {
                try {
                    // 模拟消费失败
                    throw new RuntimeException("Message consume failed");
                } catch (Exception e) {
                    System.out.println("Message consume failed, will retry");
                    // 设置消息重试
                    context.setSysFlag(MessageQueue.RETRY_CURRENT);
                }
            }
            return ConsumeOrderlyStatus.SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}

消息幂等性

消息幂等性是指消费者多次消费同一条消息,系统的处理结果应当是相同的。RocketMQ提供了消息幂等性保证,可以通过设置消息的唯一标识来实现消息的幂等性。以下是一个实现消息幂等性的示例代码,使用Java SDK实现。

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class IdempotentConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        // 设置Name Server地址
        consumer.setNamesrvAddr("127.0.0.1:9876");
        // 订阅指定的Topic和Tag
        consumer.subscribe("TopicTest", "*");
        // 设置从队列头部开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((msgs, context) -> {
            for (MessageExt msg : msgs) {
                String msgId = msg.getMsgId();
                if (!context.isOnce()) {
                    System.out.println("Message already consumed, ignore");
                    return ConsumeOrderlyStatus.SUCCESS;
                }
                // 模拟业务逻辑
                System.out.println("Consume message: " + msgId);
            }
            return ConsumeOrderlyStatus.SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}

消息回溯

消息回溯是指消费者可以消费历史消息,而不是只消费最新消息。RocketMQ支持消息回溯功能,可以通过设置消费偏移量来实现。以下是一个实现消息回溯的示例代码,使用Java SDK实现。

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class MessageBacktraceConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        // 设置Name Server地址
        consumer.setNamesrvAddr("127.0.0.1:9876");
        // 订阅指定的Topic和Tag
        consumer.subscribe("TopicTest", "*");
        // 设置从队列头部开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_MIN_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Receive Message: %s %n", new String(msg.getBody()));
            }
            return ConsumeOrderlyStatus.SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}

消息延迟

消息延迟是指生产者发送的消息不立即投递到队列中,而是延迟一段时间后投递。RocketMQ支持消息延迟功能,可以通过设置消息的延迟时间来实现。以下是一个实现消息延迟的示例代码,使用Java SDK实现。

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

public class DelayProducer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
        // 设置Name Server地址
        producer.setNamesrvAddr("127.0.0.1:9876");
        // 启动生产者
        producer.start();

        // 创建消息
        Message msg = new Message("TopicTest", // topic
            "TagA", // tag
            "Hello RocketMQ".getBytes(RemotingHelper.DEFAULT_CHARSET), // body
            null); // properties
        // 设置消息的延迟时间,单位为毫秒
        msg.setDelayTimeLevel(3);
        // 发送消息
        SendResult sendResult = producer.send(msg);
        System.out.printf("%s%n", sendResult);

        // 关闭生产者
        producer.shutdown();
    }
}
常见问题及解决方法

常见错误及解决办法

RocketMQ在运行过程中可能会遇到各种错误。以下是几个常见的错误及其解决方法:

  1. MQClientAPIOpenService.java:98 openService() - AsyncCall Exception
    • 错误原因:Name Server地址配置错误或Name Server服务未启动。
    • 解决方法:检查Name Server的地址配置是否正确,并确保Name Server服务已启动。
  2. RocketMQClientException: The configuration of message body size is too small
    • 错误原因:消息体大小配置过小。
    • 解决方法:增加配置文件中的消息体大小限制。
  3. MQClientException: The configured namespace of this client is not supported
    • 错误原因:客户端配置的命名空间不支持。
    • 解决方法:检查客户端配置的命名空间是否正确。
  4. MQClientException: MessageQueue too many, please check your topic or increase thread pool size
    • 错误原因:队列数量过多,超过了线程池的处理能力。
    • 解决方法:增加配置文件中的线程池大小。

性能优化技巧

RocketMQ提供了多种性能优化方法,以下是一些常见的性能优化技巧:

  1. 增加线程池大小
    • 在生产者和消费者中增加线程池的大小,可以提高消息的发送和消费速度。
  2. 使用批量发送
    • 在生产者中使用批量发送消息,可以减少网络通信次数,提高发送效率。
  3. 优化消息存储
    • 调整RocketMQ的消息存储配置,如磁盘缓存大小、消息压缩等,可以提高消息存储的性能。
  4. 使用消息过滤
    • 在消费者端进行消息过滤,可以减少不必要的消息处理,提高系统的整体性能。
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP