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

RocketMQ初识学习:入门教程与实践指南

慕少森
关注TA
已关注
手记 251
粉丝 42
获赞 216
概述

RocketMQ是一款由阿里云开发的分布式开源消息中间件,广泛应用于各种数据传输和处理场景。本文将带你初步了解RocketMQ的核心概念、优势和应用场景,帮助你快速上手使用。RocketMQ支持高吞吐量、实时性和可靠性,适用于大数据、金融和日志采集等多个领域。RocketMQ初识学习将涵盖从环境搭建到基本消息发送与接收的全过程。

RocketMQ简介
RocketMQ是什么

RocketMQ是由阿里云开发的一款分布式开源消息中间件,它基于JMS(Java Message Service)标准,具有高吞吐量、稳定可靠、实时性好等特点。RocketMQ广泛应用于大数据场景、互联网金融、日志采集与处理、分布式事务处理等领域。

RocketMQ采用分布式架构设计,可以支持集群模式和单机模式部署。此外,RocketMQ还支持多种消息发送方式以及消息过滤功能,具有强大的消息路由机制。

RocketMQ的核心概念

在理解RocketMQ之前,需要先熟悉几个核心概念:

  • Broker:RocketMQ的Broker是消息队列的管理节点,它负责接收生产者发送的消息并将消息转发给相应的消费者。Broker也是消息的存储节点,负责持久化消息。
  • Producer:生产者负责发送消息到Broker。生产者可以通过网络与Broker通信,将消息发送到指定的主题(Topic)。
  • Consumer:消费者负责接收Broker中存储的消息。消费者可以通过网络与Broker通信,从指定的主题中获取消息。
  • Topic:主题是RocketMQ中消息分类的标识,通常对应一个业务逻辑。生产者发送消息时需要指定发送到哪个主题。
  • Queue:队列是主题的逻辑表示。每个主题可以包含多个队列,每个队列都有唯一的ID。
  • Message:消息是RocketMQ的基本传输单元,包括消息体、消息头(Message Header)等信息。消息还可以设置消息键(Message Key)、标签(Tag)等属性,以方便消息的路由和过滤。
  • Consumer Group:消费者组是一组逻辑上的消费者实例,它们共同消费同一个主题的消息。RocketMQ支持集群模式和广播模式两种消费模式。
  • Clustering:集群模式下,同一个消费者组内的所有消费者实例共同消费同一份消息,每个消息只会被消费一次。
  • Broadcasting:广播模式下,同一个消费者组内的每个消费者实例都会接收到消息的全部副本。
RocketMQ的优势和应用场景

优势

  • 高吞吐量:RocketMQ支持每秒百万级别的消息传输。
  • 可靠性:RocketMQ支持事务消息、顺序消息和幂等消费等特性,保证消息的可靠传输。
  • 实时性:RocketMQ支持毫秒级延迟的消息传输。
  • 扩展性:RocketMQ支持集群模式,可以方便地扩展到多个节点,支持水平扩展和垂直扩展。
  • 容错性:RocketMQ具有高可用性,支持主备切换和故障转移,保证消息不丢失。
  • 消息过滤和路由:RocketMQ支持基于标签(Tag)、消息键(Message Key)等多种方式的消息过滤,提供灵活的消息路由机制。
  • 消息轨迹:RocketMQ提供了消息轨迹查询功能,可以方便地追踪消息的发送和接收过程。

应用场景

  • 大数据场景:RocketMQ可以用于实时数据采集、数据传输和处理。
  • 互联网金融:RocketMQ可以用于交易日志记录、账单通知、支付和退款等场景。
  • 日志采集与处理:RocketMQ可以用于日志收集、分析和容错。
  • 分布式事务处理:RocketMQ支持事务消息和顺序消息,可以用于分布式事务处理。
  • 微服务架构:RocketMQ可以作为微服务之间的消息通信中介,实现服务间解耦和异步通信。
  • 消息队列:RocketMQ可以作为系统之间的消息中间件,实现消息的可靠传输和处理。
RocketMQ环境搭建
安装Java开发环境

RocketMQ基于Java开发,因此首先需要安装Java开发环境。

  1. 访问Oracle官网下载最新的JDK版本:Oracle JDK下载页面
  2. 根据操作系统(Windows、Linux、MacOS)下载相应的JDK安装包。
  3. 安装JDK,设置环境变量。在命令行中输入java -version,确认Java环境安装正确。
  4. 下载并安装Maven,用于构建RocketMQ项目。从Maven官网下载最新版本:Maven下载页面
  5. 解压Maven到指定目录,并设置环境变量。
export JAVA_HOME=/path/to/jdk
export PATH=$JAVA_HOME/bin:$PATH
export MAVEN_HOME=/path/to/maven
export PATH=$MAVEN_HOME/bin:$PATH
下载并安装RocketMQ
  1. 访问阿里云RocketMQ官网下载最新版本的RocketMQ:RocketMQ下载页面
  2. 解压下载的RocketMQ压缩包到指定目录。
  3. 设置环境变量。编辑~/.bashrc文件,添加RocketMQ的路径:
export ROCKETMQ_HOME=/path/to/rocketmq
export PATH=$ROCKETMQ_HOME/bin:$PATH
  1. 刷新环境变量:
source ~/.bashrc
配置RocketMQ环境变量
  1. 编辑RocketMQ的配置文件conf/standalone.conf,根据需要修改Broker、NameServer等配置。
  2. 重启系统,使环境变量生效。
启动RocketMQ服务
  1. 进入RocketMQ的bin目录。
  2. 启动NameServer:
./mqnamesrv &
  1. 启动Broker:
./mqbroker -n localhost:9876 -c ../conf/standalone.conf &
  1. 查看RocketMQ运行状态:

```bash.
./mqadmin brokerList -n localhost:9876


# RocketMQ基本概念与术语

## 消息模型

RocketMQ的消息模型分为发布-订阅模型(Publish/Subscribe)和点对点模型(Point-to-Point)。

- **发布-订阅模型**:生产者将消息发布到一个主题(Topic),多个消费者可以订阅该主题的消息。每个消息只会被一个消费者处理。
- **点对点模型**:生产者将消息发布到一个队列(Queue),消费者从该队列中接收消息。每个消息只会被一个消费者处理。

### 代码示例

```java
// 发布-订阅模型
public void sendMessage(String topic) {
    Producer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr("localhost:9876");
    producer.start();

    String messageBody = "Hello RocketMQ";
    Message message = new Message(topic, messageBody.getBytes());

    SendResult result = producer.send(message);
    System.out.println(result);

    producer.shutdown();
}
// 点对点模型
public void sendMessage(String queue) {
    Producer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr("localhost:9876");
    producer.start();

    String messageBody = "Hello RocketMQ";
    Message message = new Message(queue, messageBody.getBytes());

    SendResult result = producer.send(message);
    System.out.println(result);

    producer.shutdown();
}
消费者与生产者
  • 生产者(Producer):生产者负责发送消息。生产者通过网络与Broker通信,将消息发送到指定的主题。
  • 消费者(Consumer):消费者负责接收消息。消费者通过网络与Broker通信,从指定的主题中获取消息。

代码示例

// 生产者发送消息
public void sendMessage(String topic) {
    Producer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr("localhost:9876");
    producer.start();

    String messageBody = "Hello RocketMQ";
    Message message = new Message(topic, messageBody.getBytes());

    SendResult result = producer.send(message);
    System.out.println(result);

    producer.shutdown();
}
// 消费者接收消息
public void consumeMessage(String topic) {
    Consumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr("localhost:9876");
    consumer.subscribe(topic, "*");

    consumer.setMessageListener(new MessageListenerConcurrently() {
        @Override
        public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
            for (MessageExt msg : msgs) {
                System.out.println("Received message: " + new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
    });

    consumer.start();
}
主题与队列
  • 主题(Topic):主题是消息分类的标识,通常对应一个业务逻辑。生产者发送消息时需要指定发送到哪个主题。
  • 队列(Queue):主题可以包含多个队列,每个队列都有唯一的ID。队列用于存储和转发消息。

代码示例

// 发送消息到主题
public void sendMessage(String topic) {
    Producer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr("localhost:9876");
    producer.start();

    String messageBody = "Hello RocketMQ";
    Message message = new Message(topic, messageBody.getBytes());

    SendResult result = producer.send(message);
    System.out.println(result);

    producer.shutdown();
}
// 发送消息到队列
public void sendMessage(String queue) {
    Producer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr("localhost:9876");
    producer.start();

    String messageBody = "Hello RocketMQ";
    Message message = new Message(queue, messageBody.getBytes());

    SendResult result = producer.send(message);
    System.out.println(result);

    producer.shutdown();
}
消息发送与接收
  • 发送消息:生产者发送消息到Broker,Broker将消息存储在主题对应的队列中。
  • 接收消息:消费者从Broker中接收消息,Broker将消息从队列中取出并发送给消费者。

代码示例

// 生产者发送消息
public void sendMessage(String topic) {
    Producer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr("localhost:9ibli79876");
    producer.start();

    String messageBody = "Hello RocketMQ";
    Message message = new Message(topic, messageBody.getBytes());

    SendResult result = producer.send(message);
    System.out.println(result);

    producer.shutdown();
}
// 消费者接收消息
public void consumeMessage(String topic) {
    Consumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr("localhost:9876");
    consumer.subscribe(topic, "*");

    consumer.setMessageListener(new MessageListenerConcurrently() {
        @Override
        public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
            for (MessageExt msg : msgs) {
                System.out.println("Received message: " + new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
    });

    consumer.start();
}
消息过滤与路由
  • 消息过滤:通过设置标签(Tag)、消息键(Message Key)等方式过滤消息。
  • 消息路由:根据主题、队列等信息将消息路由到相应的消费者。

代码示例

// 发送消息并设置标签
public void sendMessage(String topic, String tag) {
    Producer producer = new DefaultMQProducer("ProducerGroupName");
    producer.setNamesrvAddr("localhost:9876");
    producer.start();

    String messageBody = "Hello RocketMQ";
    Message message = new Message(topic, tag, messageBody.getBytes());

    SendResult result = producer.send(message);
    System.out.println(result);

    producer.shutdown();
}
// 接收消息并根据标签过滤
public void consumeMessage(String topic, String tag) {
    Consumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
    consumer.setNamesrvAddr("localhost:9876");
    consumer.subscribe(topic, tag);

    consumer.setMessageListener(new MessageListenerConcurrently() {
        @Override
        public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
            for (MessageExt msg : msgs) {
                System.out.println("Received message: " + new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
    });

    consumer.start();
}
RocketMQ消息发送与接收
发送消息的步骤
  1. 创建生产者实例。
  2. 设置生产者的属性,例如消息发送超时时间等。
  3. 创建消息对象,设置消息的属性(主题、消息体等)。
  4. 发送消息到Broker。

代码示例:

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");
        producer.setNamesrvAddr("localhost:9876");
        producer.start();

        String topic = "TestTopic";
        String messageBody = "Hello RocketMQ";
        Message message = new Message(topic, messageBody.getBytes());

        SendResult result = producer.send(message);
        System.out.println(result);

        producer.shutdown();
    }
}
接收消息的步骤
  1. 创建消费者实例。
  2. 设置消费者属性,例如消费模式(集群模式、广播模式)等。
  3. 消费者订阅指定的主题。
  4. 消费者接收并处理消息。

代码示例:

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");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.subscribe("TestTopic", "*");
        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.println(new String(msg.getBody()));
                }
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
        consumer.start();
    }
}
发送同步与异步消息
  • 同步消息:生产者发送消息后等待Broker返回结果,确保消息发送成功。
  • 异步消息:生产者发送消息后不再等待Broker返回结果,而是通过回调函数异步处理结果。

代码示例:

import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;

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

        String topic = "TestTopic";
        String messageBody = "Hello RocketMQ";
        Message message = new Message(topic, messageBody.getBytes());

        producer.send(message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("Send successful: " + sendResult);
            }

            @Override
            public void onException(Throwable e) {
                System.out.println("Send failed: " + e.getMessage());
            }
        });

        producer.shutdown();
    }
}
发送单向消息

单向消息是指生产者发送消息后不需要等待Broker返回结果,适用于对消息成功发送不敏感的场景。

代码示例:

import org.apache.rocketmq.client.producer.DefaultMQProducer;

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

        String topic = "TestTopic";
        String messageBody = "Hello RocketMQ";
        producer.sendOneWay(new Message(topic, messageBody.getBytes()));

        producer.shutdown();
    }
}
消息接收模式(集群模式与广播模式)
  • 集群模式:消费者组内的消费者实例共同消费同一份消息,每个消息只会被消费一次。
  • 广播模式:消费者组内的每个消费者实例都会接收到消息的全部副本。

代码示例:

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;

public class ClusterConsumer {
    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.setConsumeMode(ConsumeMode.CONSUME_MINIMAL_MODE);
        consumer.subscribe("TestTopic", "*");
        consumer.registerMessageListener(new MessageListenerOrderly() {
            @Override
            public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
                for (MessageExt msg : msgs) {
                    System.out.println(new String(msg.getBody()));
                }
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
        consumer.start();
    }
}
RocketMQ常见问题与解决方法
常见错误代码解析

RocketMQ的错误代码分为以下几种类型:

  • 0:成功。
  • 1:网络问题。
  • 2:编码问题。
  • 3:参数错误。
  • 4:资源不存在。
  • 5:权限问题。
  • 6:主题不存在。
  • 7:队列不存在。
  • 8:消息不存在。
  • 9:消息重复。
  • 10:消息过期。
  • 11:消息体为空。
  • 12:消息太大。
  • 13:消息传输超时。
  • 14:消息发送失败。
  • 15:消息接收失败。
  • 16:消息过滤失败。
  • 17:消息路由失败。
  • 18:消息存储失败。
  • 19:消息读取失败。
  • 20:消息删除失败。
  • 21:消息查询失败。
  • 22:消息轨迹查询失败。
  • 23:消息轨迹不存在。
  • 24:消息轨迹重复。
  • 25:消息轨迹过期。
  • 26:消息轨迹为空。
  • 27:消息轨迹太大。
  • 28:消息轨迹传输超时。
  • 29:消息轨迹存储失败。
  • 30:消息轨迹读取失败。
  • 31:消息轨迹删除失败。
  • 32:消息轨迹查询失败。
  • 33:消息轨迹不存在。
  • 34:消息轨迹重复。
  • 35:消息轨迹过期。
  • 36:消息轨迹为空。
  • 37:消息轨迹太大。
  • 38:消息轨迹传输超时。
  • 39:消息轨迹存储失败。
  • 40:消息轨迹读取失败。
  • 41:消息轨迹删除失败。
  • 42:消息轨迹查询失败。
  • 43:消息轨迹不存在。
  • 44:消息轨迹重复。
  • 45:消息轨迹过期。
  • 46:消息轨迹为空。
  • 47:消息轨迹太大。
  • 48:消息轨迹传输超时。
  • 49:消息轨迹存储失败。
  • 50:消息轨迹读取失败。
  • 51:消息轨迹删除失败。
  • 52:消息轨迹查询失败。
  • 53:消息轨迹不存在。
  • 54:消息轨迹重复。
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
性能优化技巧
  • 合理设置线程池大小:根据实际业务负载调整生产者和消费者线程池的大小。
  • 批量发送消息:使用批量发送消息可以降低网络传输的开销。
  • 使用本地缓存:生产者可以将消息缓存在本地,减少与Broker的通信次数。
  • 调整消息存储策略:根据业务需求调整消息在Broker中的存储策略,例如消息的过期时间。
  • 监控和调优:使用RocketMQ提供的监控工具,监控消息队列的状态,及时发现和解决性能瓶颈。

代码示例

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

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

        String topic = "TestTopic";
        String messageBody = "Hello RocketMQ";
        Message message = new Message(topic, messageBody.getBytes());

        for (int i = 0; i < 1000; i++) {
            producer.send(message);
        }

        producer.shutdown();
    }
}
import org.apache.rocketmq.client.producer.DefaultMQProducer;

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

        String topic = "BatchTestTopic";
        for (int i = 0; i < 1000; i++) {
            String messageBody = "Batch Message " + i;
            producer.send(new Message(topic, messageBody.getBytes()));
        }

        producer.shutdown();
    }
}
消息丢失与重复问题解析
  • 消息丢失:消息发送到Broker后,由于网络、Broker故障等原因可能导致消息丢失。
  • 消息重复:消费者从Broker接收消息后,由于网络、消费者故障等原因可能导致消息重复。

解决方法

  • 消息重试:生产者可以设置消息发送重试次数,确保消息最终发送成功。
  • 消息幂等消费:消费者可以设置幂等消费机制,确保消息只被消费一次。
  • 消息轨迹:使用消息轨迹功能,追踪消息的发送和接收过程,及时发现和解决消息丢失和重复问题。

代码示例

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;

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

        String topic = "RetryTopic";
        String messageBody = "Retry Message";
        Message message = new Message(topic, messageBody.getBytes());

        producer.send(message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("Send successful: " + sendResult);
            }

            @Override
            public void onException(Throwable e) {
                System.out.println("Send failed: " + e.getMessage());
            }
        });

        producer.shutdown();
    }
}
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.message.MessageExt;

public class IdempotentConsumer {
    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("IdempotentConsumerGroupName");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.subscribe("IdempotentTopic", "*");
        consumer.registerMessageListener(new MessageListenerOrderly() {
            @Override
            public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
                for (MessageExt msg : msgs) {
                    String messageBody = new String(msg.getBody());
                    System.out.println("Received message: " + messageBody);
                    // Process message
                }
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
        consumer.start();
    }
}
消费者消息堆积与处理
  • 消息堆积:当消费者处理消息的速度跟不上生产者发送消息的速度时,可能会导致消息堆积。
  • 消息堆积处理:可以通过增加消费者实例数、优化消息消费逻辑等方式处理消息堆积问题。

代码示例

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;

public class Consumer {
    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.subscribe("TestTopic", "*");
        consumer.registerMessageListener(new MessageListenerOrderly() {
            @Override
            public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
                for (MessageExt msg : msgs) {
                    System.out.println(new String(msg.getBody()));
                    try {
                        Thread.sleep(1000); // 模拟消息处理时间
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
        consumer.start();
    }
}
RocketMQ实战案例
实战案例概述

本节以一个简单的电商交易系统为例,演示如何使用RocketMQ实现订单消息的异步发送和接收。系统包括订单服务和支付服务,订单服务负责生成订单并发送订单消息,支付服务负责接收订单消息并处理支付逻辑。

案例实现步骤

步骤1:创建订单服务

订单服务包括订单生成、订单消息发送等逻辑。

代码示例:

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

public class OrderService {
    public void generateOrder(String orderId, String userId) throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("OrderProducerGroup");
        producer.setNamesrvAddr("localhost:9876");
        producer.start();

        String topic = "OrderTopic";
        String messageBody = "OrderID: " + orderId + " UserID: " + userId;
        Message message = new Message(topic, messageBody.getBytes());

        producer.send(message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("Order message sent successfully: " + sendResult);
            }

            @Override
            public void onException(Throwable e) {
                System.out.println("Order message sent failed: " + e.getMessage());
            }
        });

        producer.shutdown();
    }
}

步骤2:创建支付服务

支付服务包括支付逻辑和订单消息接收等逻辑。

代码示例:

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;

public class PaymentService {
    public void processOrder(String orderId, String userId) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("PaymentConsumerGroup");
        consumer.setNamesrvAddr("localhost:9876");
        consumer.subscribe("OrderTopic", "*");
        consumer.registerMessageListener(new MessageListenerOrderly() {
            @Override
            public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
                for (MessageExt msg : msgs) {
                    String messageBody = new String(msg.getBody());
                    System.out.println("Received order message: " + messageBody);
                    // Process payment logic
                    System.out.println("Payment processed for order: " + orderId);
                }
                return ConsumeOrderlyStatus.SUCCESS;
            }
        });
        consumer.start();
    }
}

步骤3:启动订单服务和支付服务

启动订单服务和支付服务,模拟订单生成和支付处理过程。

代码示例:

public class Main {
    public static void main(String[] args) throws Exception {
        OrderService orderService = new OrderService();
        orderService.generateOrder("12345", "67890");

        PaymentService paymentService = new PaymentService();
        paymentService.processOrder("12345", "67890");
    }
}

步骤4:运行案例

运行案例,模拟订单生成和支付处理过程,验证订单消息的异步发送和接收。

案例代码解析

订单服务代码解析

订单服务代码中,创建了生产者实例,设置了生产者属性,发送订单消息并设置消息发送回调函数。

支付服务代码解析

支付服务代码中,创建了消费者实例,设置了消费者属性,订阅指定的主题,接收并处理订单消息。

案例总结与经验分享

通过本案例,我们学习了如何使用RocketMQ实现订单消息的异步发送和接收。通过订单服务和支付服务的配合,实现了订单生成和支付处理的异步通信。实际应用中可以根据业务需求扩展更多的服务和逻辑,进一步提高系统的可靠性和性能。

通过案例实践,我们可以更好地掌握RocketMQ的核心概念和使用方法,为实际开发中的问题解决提供参考。在实际开发过程中,可以根据业务需求选择合适的消息模型、消费模式和消息处理策略,提高系统的可靠性和性能。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP