为了账号安全,请及时绑定邮箱和手机立即绑定

RocketMq原理项目实战:新手入门指南

本文将详细介绍RocketMq原理项目实战,包括消息生产者与消费者的运作机制、消息发布与订阅的实际操作以及集群部署与监控等内容。RocketMq原理项目实战涵盖了从环境搭建到实际项目应用的全过程,帮助读者全面了解RocketMq的核心原理和实际应用。文章还将深入讲解RocketMq的集群部署和监控方法,确保读者能够掌握RocketMq的高级使用技巧。

RocketMq简介与环境搭建

RocketMq的基本概念

RocketMq是一款基于Java语言开发的开源消息中间件,由阿里巴巴开源并贡献给Apache基金会,主要应用于分布式应用中高性能的消息传递,具有高吞吐量、高可用、高可扩展性等特性。它支持多种消息类型,包括单向消息、发布/订阅消息、顺序消息、事务消息等。

RocketMq的核心组件包括Broker、NameServer和Client。NameServer主要负责路由信息的管理和同步,而Broker是消息的生产和消费的路由器。消息的生产者和消费者通过NameServer来获取消息的路由信息,从而实现消息的可靠传递。

关键术语解释

  • NameServer:负责NameServer集群的路由信息保存以及路由信息的广播,NameServer集群的任意节点宕机都不会影响其功能。
  • Broker:消息中转角色,负责消息的存储、转发、消费,一个Broker上有多个消息队列。
  • Producer:生产者,负责向指定Topic发送消息。
  • Consumer:消费者,负责消费消息,从Topic消费消息。
  • Topic:消息类型,定位具体的应用场景。
  • Queue:消息队列,是消息物理存储的单位,一个Topic可以包含多个queue。
  • Message:消息体,包含用户信息数据部分和消息属性。

开发环境搭建与配置

搭建开发环境

首先,你需要确保你的开发环境已经安装了Java 8及以上版本。RocketMQ基于Java开发,因此需要Java环境。此外,还需要下载并安装RocketMQ的最新版本。RocketMQ的最新版本可以从其官方仓库或Apache官方网站下载。

配置开发环境

  1. 下载RocketMq
wget https://archive.apache.org/dist/rocketmq/rocketmq-all-4.9.1-bin-release.zip
unzip rocketmq-all-4.9.1-bin-release.zip
cd rocketmq-all-4.9.1
  1. 启动NameServer
nohup sh bin/mqnamesrv &
  1. 启动Broker
nohup sh bin/mqbroker -n localhost:9876 &
  1. 验证环境

运行以下命令来验证RocketMQ是否安装成功,并检查NameServer和Broker是否正常运行。

sh bin/mqadmin clusterList localhost

输出信息应包含NameServer和Broker的相关信息,表明RocketMQ已经成功安装和启动。

配置RocketMq

RocketMQ的配置文件主要位于conf目录下,包括broker.propertiesserver.properties等。这些文件中定义了RocketMQ的一些基本配置,如Broker的名称、IP地址、端口等。

  • broker.properties
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedDays=7
flushDiskType=ASYNC_FLUSH
brokerRole=ASYNC_MASTER
  • server.properties
storePathRootDir=/home/rocketmq/store
storePathCommitLog=/home/rocketmq/store/commitlog
storePathConsumeQueue=/home/rocketmq/store/consumequeue
storePathIndex=/home/rocketmq/store/index
storePathLog=/home/rocketmq/store/log
storePathMeta=/home/rocketmq/store/meta
storePathCommitLog=/home/rocketmq/store/commitlog
storePathIndex=/home/rocketmq/store/index

配置完成后,可以使用RocketMQ提供的工具进行消息的发送和接收。

主题与队列的概念

Topic

Topic是RocketMQ中消息的分类,可以理解为消息的类型或主题。生产者发送的消息需要指定一个Topic,消费者消费消息也需要指定一个Topic。Topic是唯一的,不同的Topic代表不同的消息类型。

Message msg = new Message(
    "TopicTest", // Topic
    "TagA", // Tag
    ("Hello RocketMQ "+i).getBytes(RemotingHelper.DEFAULT_CHARSET));

Queue

Queue是消息在Broker上的物理存储单位。一个Topic可以包含多个Queue,每个Queue都有自己的索引文件和消息文件。RocketMQ通过Queue来实现消息的并发消费。

Message msg = new Message(
    "TopicTest", // Topic
    "TagA", // Tag
    ("Hello RocketMQ "+i).getBytes(RemotingHelper.DEFAULT_CHARSET));

集群部署的基础步骤

部署NameServer

  1. 启动NameServer
nohup sh bin/mqnamesrv &

部署Broker

  1. 配置Broker

conf/broker.properties文件中进行配置。

brokerClusterName=DefaultCluster
brokerName=broker-0
brokerId=0
deleteWhen=04
fileReservedDays=7
flushDiskType=ASYNC_FLUSH
brokerRole=ASYNC_MASTER
  1. 启动Broker
nohup sh bin/mqbroker -c conf/broker.properties &

部署多个Broker

  1. 配置多个Broker

在不同的Broker中分别配置broker.properties文件,并设置不同的brokerId

  1. 启动Broker
nohup sh bin/mqbroker -c conf/broker-0.properties &
nohup sh bin/mqbroker -c conf/broker-1.properties &

监控工具的使用及详解

监控RocketMq

RocketMQ提供了多种监控工具,包括RocketMQ自带的mqadmin命令和第三方监控工具如Prometheus等。

  1. 使用RocketMQ自带的监控工具
sh bin/mqadmin clusterList localhost
  1. 使用Prometheus监控RocketMq

  2. 安装Prometheus

下载并安装Prometheus。

wget https://github.com/prometheus/prometheus/releases/download/v2.35.0/prometheus-2.35.0.linux-amd64.tar.gz
tar -xvf prometheus-2.35.0.linux-amd64.tar.gz
cd prometheus-2.35.0.linux-amd64
  1. 配置RocketMQ与Prometheus集成

prometheus.yml文件中添加RocketMQ的监控配置。

scrape_configs:
  - job_name: 'rocketmq-broker'
    static_configs:
      - targets: ['localhost:10911']
  - job_name: 'rocketmq-namesrv'
    static_configs:
      - targets: ['localhost:10912']
  1. 启动Prometheus
./prometheus --config.file=prometheus.yml &
  1. 访问Prometheus

打开浏览器,访问http://localhost:9090,可以查看RocketMQ的相关监控指标。

监控指标详解

RocketMQ提供的监控指标包括但不限于以下内容:

  • Broker状态
{
  "brokerAddr": "127.0.0.1:10911",
  "brokerName": "broker-0",
  "brokerVersion": "4.9.1",
  "consumerNums": 1,
  "producerNums": 1,
  "diskUsedSize": 100,
  "queueNums": 10,
  "registerTopicNums": 5
}
  • Topic状态
{
  "topic": "TopicTest",
  "queueNums": 10,
  "queueSize": 50,
  "consumerNums": 1,
  "produceNums": 1,
  "queueSizeMax": 200
}

RocketMq核心原理讲解

消息生产者与消费者的运作机制

消息生产者

消息生产者(Producer)是RocketMQ系统中的消息发送方,它负责将消息发送到指定的Topic中。生产者需要先连接到NameServer获取Broker的路由信息,然后通过Broker将消息发送到指定的Topic中。

  • 建立连接
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
  • 发送消息
Message msg = new Message(
    "TopicTest", // Topic
    "TagA", // Tag
    ("Hello RocketMQ "+i).getBytes(RemotingHelper.DEFAULT_CHARSET));
SendResult sendResult = producer.send(msg);

消息消费者

消息消费者(Consumer)是RocketMQ系统中的消息接收方,它从指定的Topic中消费消息。消费者需要先连接到NameServer获取Broker的路由信息,然后通过Broker从指定的Topic中消费消息。

  • 建立连接
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("TopicTest", "*");
consumer.start();
  • 消费消息
consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (Message msg : msgs) {
        System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});

消息处理的优化建议

消息重试机制

在RocketMQ中,如果消费消息时失败,可以通过设置ConsumeConcurrentlyStatus.RECONSUME_LATER来实现消息的重试机制,消息会重新放回队列并等待下次消费。

consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (MessageExt msg : msgs) {
        try {
            System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
            // 模拟消息处理失败
            if (new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET).equals("test")) {
                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});

消息过滤

可以通过设置消费者的消息过滤规则来减少不必要的消息消费。

consumer.subscribe("TopicTest", "*");
consumer.setMessageModel(MessageModel.BROADCASTING); // 设置消息模型
consumer.setMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (MessageExt msg : msgs) {
        System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});

消息消费的幂等性

为了确保消息的唯一性和避免重复消费,RocketMQ提供了消息消费的幂等性处理机制。可以通过设置消息的唯一标识(如消息ID)来确保消息的唯一性。

consumer.setMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (MessageExt msg : msgs) {
        String msgId = msg.getMsgId();
        if (msgId != null && !msgId.isEmpty()) {
            System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
        }
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
RocketMq项目实战一:消息发布与订阅

实现简单的消息发布与订阅功能

消息发布(生产者)

  1. 生产者配置
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();
  1. 发送消息
Message msg = new Message(
    "TopicTest", // Topic
    "TagA", // Tag
    ("Hello RocketMQ "+i).getBytes(RemotingHelper.DEFAULT_CHARSET));
SendResult sendResult = producer.send(msg);

消息订阅(消费者)

  1. 消费者配置
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("TopicTest", "*");
consumer.start();
  1. 消费消息
consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (Message msg : msgs) {
        System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});

实战代码示例

生产者代码示例

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

public class Producer {
    public static void main(String[] args) throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
        producer.setNamesrvAddr("localhost:9876");
        producer.start();

        for (int i = 0; i < 100; i++) {
            Message msg = new Message(
                "TopicTest", // Topic
                "TagA", // Tag
                ("Hello RocketMQ "+i).getBytes(RemotingHelper.DEFAULT_CHARSET));
            SendResult sendResult = producer.send(msg);
            System.out.printf("%s %s%n", sendResult.getSendStatus(), sendResult.getMessageId());
        }

        producer.shutdown();
    }
}

消费者代码示例

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.common.message.MessageExt;
import org.apache.rocketmq.remoting.common.RemotingHelper;

public class Consumer {
    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.subscribe("TopicTest", "*");
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        consumer.start();
    }
}
RocketMq项目实战二:消息消费与处理

详细介绍消息消费的流程

接收消息

消费者从指定的Topic中接收消息的过程需要通过NameServer获取Broker的路由信息,然后由Broker将消息推送给消费者。RocketMQ支持同步和异步两种模式的消息消费。

  1. 同步消费
consumer.subscribe("TopicTest", "*");
consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (MessageExt msg : msgs) {
        System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
  1. 异步消费
consumer.subscribe("TopicTest", "*");
consumer.setMessageListener((MessageListenerOrderly) (msgs, context) -> {
    for (MessageExt msg : msgs) {
        System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
    }
    return ConsumeOrderlyStatus.SUCCESS;
});

消息处理的优化建议

消息重试机制

在RocketMQ中,如果消费消息时失败,可以通过设置ConsumeConcurrentlyStatus.RECONSUME_LATER来实现消息的重试机制,消息会重新放回队列并等待下次消费。

consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (MessageExt msg : msgs) {
        try {
            System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
            // 模拟消息处理失败
            if (new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET).equals("test")) {
                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});

消息过滤

可以通过设置消费者的消息过滤规则来减少不必要的消息消费。

consumer.subscribe("TopicTest", "*");
consumer.setMessageModel(MessageModel.BROADCASTING); // 设置消息模型
consumer.setMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (MessageExt msg : msgs) {
        System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});

消息消费的幂等性

为了确保消息的唯一性和避免重复消费,RocketMQ提供了消息消费的幂等性处理机制。可以通过设置消息的唯一标识(如消息ID)来确保消息的唯一性。

consumer.setMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    for (MessageExt msg : msgs) {
        String msgId = msg.getMsgId();
        if (msgId != null && !msgId.isEmpty()) {
            System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
        }
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
RocketMq项目实战三:集群部署与监控

集群部署的基础步骤

部署NameServer

  1. 启动NameServer
nohup sh bin/mqnamesrv &

部署Broker

  1. 配置Broker

conf/broker.properties文件中进行配置。

brokerClusterName=DefaultCluster
brokerName=broker-0
brokerId=0
deleteWhen=04
fileReservedDays=7
flushDiskType=ASYNC_FLUSH
brokerRole=ASYNC_MASTER
  1. 启动Broker
nohup sh bin/mqbroker -c conf/broker.properties &

部署多个Broker

  1. 配置多个Broker

在不同的Broker中分别配置broker.properties文件,并设置不同的brokerId

  1. 启动Broker
nohup sh bin/mqbroker -c conf/broker-0.properties &
nohup sh bin/mqbroker -c conf/broker-1.properties &

监控工具的使用及详解

监控RocketMq

RocketMQ提供了多种监控工具,包括RocketMQ自带的mqadmin命令和第三方监控工具如Prometheus等。

  1. 使用RocketMQ自带的监控工具
sh bin/mqadmin clusterList localhost
  1. 使用Prometheus监控RocketMq

  2. 安装Prometheus

下载并安装Prometheus。

wget https://github.com/prometheus/prometheus/releases/download/v2.35.0/prometheus-2.35.0.linux-amd64.tar.gz
tar -xvf prometheus-2.35.0.linux-amd64.tar.gz
cd prometheus-2.35.0.linux-amd64
  1. 配置RocketMQ与Prometheus集成

prometheus.yml文件中添加RocketMQ的监控配置。

scrape_configs:
  - job_name: 'rocketmq-broker'
    static_configs:
      - targets: ['localhost:10911']
  - job_name: 'rocketmq-namesrv'
    static_configs:
      - targets: ['localhost:10912']
  1. 启动Prometheus
./prometheus --config.file=prometheus.yml &
  1. 访问Prometheus

打开浏览器,访问http://localhost:9090,可以查看RocketMQ的相关监控指标。

监控指标详解

RocketMQ提供的监控指标包括但不限于以下内容:

  • Broker状态
{
  "brokerAddr": "127.0.0.1:10911",
  "brokerName": "broker-0",
  "brokerVersion": "4.9.1",
  "consumerNums": 1,
  "producerNums": 1,
  "diskUsedSize": 100,
  "queueNums": 10,
  "registerTopicNums": 5
}
  • Topic状态
{
  "topic": "TopicTest",
  "queueNums": 10,
  "queueSize": 50,
  "consumerNums": 1,
  "produceNums": 1,
  "queueSizeMax": 200
}

通过监控这些指标,可以及时发现RocketMQ集群中的问题,提高系统的可靠性和稳定性。

解决常见问题与技巧分享

遇到的问题及解决方法

问题1:消费者消费不到消息

  • 原因:消费者与生产者之间的路由信息不一致,或者Broker未正确启动。
  • 解决方法:确保NameServer和Broker已经正确启动,并且消费者能够正确获取到Broker的路由信息。

问题2:消息重复消费

  • 原因:消息的消费机制未设置幂等性。
  • 解决方法:在消息消费的处理逻辑中设置消息的幂等性处理机制,确保消息的唯一性。

问题3:消息发送失败

  • 原因:生产者与Broker之间的网络连接异常,或者生产者配置不当。
  • 解决方法:检查生产者与Broker之间的网络连接是否正常,并确保生产者配置正确。

项目实战中的技巧与注意事项

技巧1:持久化消息

  • 说明:RocketMQ支持消息的持久化存储,可以确保消息不丢失。
  • 实现:设置flushDiskTypeASYNC_FLUSHSYNC_FLUSH,确保消息的持久化存储。

技巧2:消息过滤

  • 说明:通过设置消息的过滤规则,可以减少不必要的消息消费。
  • 实现:在消费者中设置消息的过滤规则,只消费符合规则的消息。

技巧3:消息重试机制

  • 说明:通过设置消息的重试机制,可以确保消息的可靠性。
  • 实现:在消息消费失败时,设置ConsumeConcurrentlyStatus.RECONSUME_LATER,实现消息的重试机制。

注意事项

  • 性能优化:合理设置Broker的数量和配置,确保RocketMQ集群的性能。
  • 监控与报警:通过RocketMQ的监控工具,及时发现并解决集群中的异常问题。
  • 高可用性:合理设置NameServer和Broker的集群配置,确保RocketMQ集群的高可用性。

通过以上技巧和注意事项,可以更好地利用RocketMQ进行消息的发布与订阅,保证消息的可靠性和系统的稳定性。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消