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

Rocket消息队列项目实战:新手入门教程

概述

本文详细介绍了Rocket消息队列项目实战,从RocketMQ的安装、配置到基本概念和高级特性,帮助读者全面了解并掌握RocketMQ的使用方法。文章还提供了电商订单消息通知系统和日志收集与分析系统的实战案例,深入讲解了RocketMQ在实际项目中的应用。

Rocket消息队列项目实战:新手入门教程
RocketMQ简介与安装

RocketMQ是什么

RocketMQ是由阿里巴巴开源的一款分布式消息中间件,它具有高性能、高可靠、高实时性等特性,被广泛应用于各种场景,包括但不限于电商、金融、物流等领域。RocketMQ支持多种消息类型,如顺序消息、事务消息、定时消息等,并且提供了一套丰富的API接口以及管理工具,方便用户开发和维护。

RocketMQ的安装步骤

下载RocketMQ

首先,访问RocketMQ的官方GitHub仓库或官网,下载最新版本的RocketMQ。

# 下载RocketMQ
wget https://archive.apache.org/dist/rocketmq/4.9.3/rocketmq-all-4.9.3-bin-release.zip

解压RocketMQ

下载完成后,使用命令解压文件。

# 解压RocketMQ
unzip rocketmq-all-4.9.3-bin-release.zip -d /usr/local

配置环境变量

将RocketMQ的bin目录添加到系统的环境变量中,以便可以直接使用RocketMQ的命令。

# 配置环境变量
export ROCKETMQ_HOME=/usr/local/rocketmq-all-4.9.3
export PATH=$PATH:$ROCKETMQ_HOME/bin

启动RocketMQ

启动RocketMQ需要启动NameServer和Broker端。NameServer是RocketMQ消息队列的注册中心,用于维护Broker的元数据,而Broker是实际的消息存储和分发者。

# 启动NameServer
nohup sh /usr/local/rocketmq-all-4.9.3/bin/mqnamesrv &

# 启动Broker
nohup sh /usr/local/rocketmq-all-4.9.3/bin/mqbroker -n 127.0.0.1:9876 & 

以上步骤完成之后,RocketMQ已成功安装,并且NameServer和Broker也已经启动。

配置RocketMQ环境

在默认安装的情况下,RocketMQ的配置文件都在conf目录下,主要包括broker.conflogback等配置文件。

  • broker.conf:用于配置Broker的一些基本信息,例如Broker的名称、集群名称、监听地址等。
# 配置broker名称
brokerName=broker-a

# 配置集群名称
clusterName=DefaultCluster

# 配置监听地址
brokerIP1=127.0.0.1
  • logback.xml:用于配置日志输出的格式和级别。
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

通过以上配置,RocketMQ的环境就配置完成了。

RocketMQ基本概念

消息模型

在RocketMQ中,消息模型主要分为顺序消息和非顺序消息两种。

  • 顺序消息:RocketMQ保证消息的发送顺序,这在某些特定的场景下非常有用。
  • 非顺序消息:默认情况下,RocketMQ不会保证消息的发送顺序。

主题与队列

RocketMQ中的主题(Topic)类似于传统消息队列中的队列名称,它用于标识一类消息。在RocketMQ中,可以为一个Topic创建多个队列,这些队列共同服务于该Topic的消息生产和消费。

# 创建topic
CREATE_TOPIC:TestTopic

生产者与消费者

生产者(Producer)负责发送消息到指定的Topic,而消费者(Consumer)则负责消费这些消息。

// 生产者发送消息到指定的Topic
public static void sendMsgToTopic(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr(bootStrapServers);
    producer.start();
    Message msg = new Message(topic, "Tag", "Hello RocketMQ".getBytes(RemotingHelper.DEFAULT_CHARSET));
    producer.send(msg);
    producer.shutdown();
}
// 消费者从指定的Topic接收消息
public static void consumeMessageFromTopic(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr(bootStrapServers);
    consumer.subscribe(topic, "*");
    consumer.registerMessageListener((msgs, context) -> {
        for (MessageExt msg : msgs) {
            System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
        }
        return ConsumeMessageResult.CONSUME_SUCCESS;
    });
    consumer.start();
}
编写第一个RocketMQ应用

创建生产者

创建一个生产者类,用于发送消息到指定的Topic。

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

public class SimpleProducer {

    public static void main(String[] args) throws Exception {
        String topic = "TestTopic";
        String bootStrapServers = "127.0.0.1:9876";
        DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
        producer.setNamesrvAddr(bootStrapServers);
        producer.start();
        Message msg = new Message(topic, "Tag", "Hello RocketMQ".getBytes(RemotingHelper.DEFAULT_CHARSET));
        producer.send(msg);
        producer.shutdown();
    }
}

发送消息

在上面的生产者类中,已经实现了发送消息的逻辑。

创建消费者

创建一个消费者类,用于消费指定Topic的消息。

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.common.consumer.ConsumeMessageResult;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.common.RemotingHelper;

public class SimpleConsumer {

    public static void main(String[] args) throws Exception {
        String topic = "TestTopic";
        String bootStrapServers = "127.0.0.1:9876";
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        consumer.setNamesrvAddr(bootStrapServers);
        consumer.subscribe(topic, "*");
        consumer.registerMessageListener((msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
            }
            return ConsumeMessageResult.CONSUME_SUCCESS;
        });
        consumer.start();
    }
}
RocketMQ的高级特性

消息过滤

RocketMQ支持通过Message Filter对消息进行过滤。例如,可以按Tag进行过滤。

// 生产者发送带Tag的消息
public static void sendMsgWithTag(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr(bootStrapServers);
    producer.start();
    Message msg = new Message(topic, "TagA", "Hello RocketMQ".getBytes(RemotingHelper.DEFAULT_CHARSET));
    producer.send(msg);
    producer.shutdown();
}

// 消费者按Tag接收消息
public static void consumeMsgWithTag(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr(bootStrapServers);
    consumer.subscribe(topic, "TagA");
    consumer.registerMessageListener((msgs, context) -> {
        for (MessageExt msg : msgs) {
            System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
        }
        return ConsumeMessageResult.CONSUME_SUCCESS;
    });
    consumer.start();
}

消息重试

RocketMQ支持消息重试机制,如果消费消息时出现异常,可以配置重试次数。

// 配置消息重试
public static void consumeWithRetry(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr(bootStrapServers);
    consumer.subscribe(topic, "*");
    consumer.setMessageModel(MessageModel.BROADCASTING); // 广播模式
    consumer.setRetryTimesWhenNoTopicConsumeQueue(10); // 设置重试次数
    consumer.registerMessageListener((msgs, context) -> {
        for (MessageExt msg : msgs) {
            System.out.printf("Received message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
        }
        return ConsumeMessageResult.CONSUME_SUCCESS;
    });
    consumer.start();
}

消息延迟

RocketMQ支持消息延迟,可以指定消息的延迟时间。

// 发送延迟消息
public static void sendDelayedMessage(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr(bootStrapServers);
    producer.start();
    Message msg = new Message(topic, "Tag", "Delayed Message".getBytes(RemotingHelper.DEFAULT_CHARSET));
    msg.setDelayTimeLevel(3); // 设置延迟等级,0-15,数越大,延迟时间越长
    producer.send(msg);
    producer.shutdown();
}
实战项目案例

电商订单消息通知系统

在电商应用中,当用户完成订单支付后,需要通知仓储、物流、财务等多个部门,此时可以使用RocketMQ进行消息通知。生产者在用户支付成功后发送订单消息到下游系统,下游系统作为消费者接收消息并进行相应的处理。

// 发送订单消息
public static void sendOrderMessage(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr(bootStrapServers);
    producer.start();
    Message msg = new Message(topic, "OrderMessage", "OrderID:12345".getBytes(RemotingHelper.DEFAULT_CHARSET));
    producer.send(msg);
    producer.shutdown();
}

// 接收订单消息
public static void consumeOrderMessage(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr(bootStrapServers);
    consumer.subscribe(topic, "OrderMessage");
    consumer.registerMessageListener((msgs, context) -> {
        for (MessageExt msg : msgs) {
            System.out.printf("Received order message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
        }
        return ConsumeMessageResult.CONSUME_SUCCESS;
    });
    consumer.start();
}

日志收集与分析系统

日志收集与分析是常见的大数据处理场景,可以使用RocketMQ进行日志的实时收集与传输。生产者负责将日志消息发送到RocketMQ,消费者负责接收并保存到数据库中。

// 发送日志消息
public static void sendLogMessage(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr(bootStrapServers);
    producer.start();
    Message msg = new Message(topic, "LogMessage", "LogContent".getBytes(RemotingHelper.DEFAULT_CHARSET));
    producer.send(msg);
    producer.shutdown();
}

// 接收日志消息
public static void consumeLogMessage(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr(bootStrapServers);
    consumer.subscribe(topic, "LogMessage");
    consumer.registerMessageListener((msgs, context) -> {
        for (MessageExt msg : msgs) {
            System.out.printf("Received log message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
        }
        return ConsumeMessageResult.CONSUME_SUCCESS;
    });
    consumer.start();
}

任务调度系统

任务调度系统需要实时地将任务分发到各个执行节点,并接收执行结果。生产者发送任务消息,消费者接收任务并执行,然后返回结果。

// 发送任务消息
public static void sendTaskMessage(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr(bootStrapServers);
    producer.start();
    Message msg = new Message(topic, "TaskMessage", "TaskContent".getBytes(RemotingHelper.DEFAULT_CHARSET));
    producer.send(msg);
    producer.shutdown();
}

// 接收任务消息
public static void consumeTaskMessage(String topic) throws Exception {
    String bootStrapServers = "127.0.0.1:9876";
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr(bootStrapServers);
    consumer.subscribe(topic, "TaskMessage");
    consumer.registerMessageListener((msgs, context) -> {
        for (MessageExt msg : msgs) {
            System.out.printf("Received task message: %s %n", new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET));
        }
        return ConsumeMessageResult.CONSUME_SUCCESS;
    });
    consumer.start();
}
常见问题与解决方法

常见错误及解决方案

消息发送失败

  • 错误代码:MQClientException: The broker not found
  • 解决方案:检查NameServer和Broker是否都已经启动,并且配置是否正确。
  • 错误代码:MQClientException: The producer group is not found
  • 解决方案:检查生产者的组名是否配置正确。

消息接收不到

  • 错误代码:ConsumerNotAssignError
  • 解决方案:检查消费者的组名是否配置正确,并且是否有消息过滤设置。

性能优化建议

  • 消息分片:将大消息拆分成多个小消息发送。
  • 批量消费:消费者可以批量消费消息,提高处理效率。
  • 异步模式:尽量使用异步模式,减少网络I/O阻塞。

项目部署与运维

部署RocketMQ

部署RocketMQ时,需要考虑集群部署、高可用性和负载均衡。

# 安装RocketMQ集群
# 部署NameServer
nohup sh /usr/local/rocketmq-all-4.9.3/bin/mqnamesrv &

# 部署Broker
nohup sh /usr/local/rocketmq-all-4.9.3/bin/mqbroker -n 127.0.0.1:9876 -c /usr/local/rocketmq-all-4.9.3/conf/broker-a.properties &
nohup sh /usr/local/rocketmq-all-4.9.3/bin/mqbroker -n 127.0.0.1:9876 -c /usr/local/rocketmq-all-4.9.3/conf/broker-b.properties &

运维监控

RocketMQ提供了命令行工具和Web管理界面,可以实时监控RocketMQ运行状态。

# 启动RocketMQ管理界面
nohup sh /usr/local/rocketmq-all-4.9.3/bin/mqadmin startConsoleWeb &

# 访问管理界面
http://localhost:8081

以上是对RocketMQ的基本介绍和实战应用,希望对你有所帮助。如果你需要进一步的学习资源,可以参考慕课网(https://www.imooc.com/)上的相关课程

点击查看更多内容
TA 点赞

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

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
205
获赞与收藏
1008

关注作者,订阅最新文章

阅读免费教程

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

100积分直接送

付费专栏免费学

大额优惠券免费领

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

举报

0/150
提交
取消