概述
本文深入探讨了RocketMQ源码项目实战,从RocketMQ的基本概念、开发环境搭建到源码解析,详细介绍了RocketMQ的核心模块和运行机制。文章还通过实战案例展示了如何构建一个简单的消息系统,包括生产者发送消息、消费者接收消息以及监控与告警配置等步骤,旨在帮助读者全面掌握RocketMQ源码项目实战。
RocketMQ简介与环境搭建 RocketMQ是什么RocketMQ是由阿里巴巴开源的一款分布式消息中间件。它具有高吞吐量、低延迟、高可用等特性,并且支持多种消息模式,如发布订阅、顺序消息、事务消息、定时消息等。RocketMQ广泛应用于阿里巴巴集团内的多个业务场景,如交易、物流配送、广告推送等领域。
RocketMQ的核心概念核心概念介绍
- NameServer:NameServer是RocketMQ的注册中心,负责维护Broker的元数据信息,包括Broker的IP地址、端口号等信息。生产者和消费者通过NameServer获取Broker的信息。
- Broker:Broker是RocketMQ的消息代理服务端,负责接收、存储和转发消息。RocketMQ支持主从复制和集群模式,可以实现高可用和负载均衡。
- Producer:生产者负责向Broker发送消息。RocketMQ支持集群模式和广播模式两种发送消息的方式。
- Consumer:消费者负责从Broker中拉取消息。RocketMQ支持集群消费和广播消费两种消费方式。
- Topic:Topic是RocketMQ的消息主题,用于标识不同类型的消息。生产者发送消息时需要指定Topic,消费者订阅消息时也根据Topic进行订阅。
- Message:消息是RocketMQ的基本数据单元,包含消息体、消息标签、发送时间戳等信息。
- Order Message:顺序消息是RocketMQ支持的一种特性,可以保证消息的有序性,适用于一些对消息顺序要求较高的场景。
- Transaction Message:事务消息是一种特殊的事务消息,可以在发送消息后执行业务逻辑,RocketMQ会根据业务逻辑的执行结果决定消息是否提交或回滚。
- Message Queue:消息队列是RocketMQ中消息的物理存储结构,每个Topic可以包含多个消息队列。
源码示例
// 生产者发送消息
public class Producer {
public static void main(String[] args) {
// 创建生产者实例
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
// 设置NameServer地址
producer.setNamesrvAddr("localhost:9876");
// 启动生产者
producer.start();
// 创建消息
Message msg = new Message("TopicTest", // Topic
"TagA", // Tag
"Hello RocketMQ".getBytes(RemotingHelper.DEFAULT_CHARSET), // body
null // 未指定Key
);
// 发送消息
SendResult sendResult = producer.send(msg);
System.out.printf("%s%n", sendResult);
// 关闭生产者
producer.shutdown();
}
}
// 消费者消费消息
public class Consumer {
public static void main(String[] args) {
// 创建消费者实例
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
// 设置NameServer地址
consumer.setNamesrvAddr("localhost:9876");
// 订阅Topic
consumer.subscribe("TopicTest", "TagA");
// 注册消息回调函数
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.printf("Received message: %s%n", new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 启动消费者
consumer.start();
}
}
开发环境搭建
搭建步骤
- 下载RocketMQ:访问RocketMQ的GitHub主页(https://github.com/apache/rocketmq),下载RocketMQ的源码或压缩包。
- 编译RocketMQ:下载RocketMQ源码后,可以通过Maven进行编译和打包。
mvn clean install -DskipTests
- 启动NameServer:进入
bin
目录,运行NameServer的启动脚本。cd rocketmq-all-4.9.2/bin ./mqnamesrv
- 启动Broker:同样在
bin
目录下运行Broker的启动脚本。./mqbroker -n localhost:9876 -c conf/broker-a.properties
- 编写生产者和消费者代码:使用IDEA或Eclipse等开发工具编写Java代码,实现生产者和消费者的逻辑。
- 运行生产者和消费者:运行Java程序,观察消息的发送和接收过程。
源码示例
// 启动NameServer
public class NameServerLauncher {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
String hostIp = "127.0.0.1";
int port = SystemPropertyUtil.getInt("name.server.port", 9876);
ConfManager confManager = new ConfManager();
executor.execute(new NamesrvController(confManager, hostIp, port));
} catch (Exception e) {
System.out.printf("Failed to start Name Server, cause: %s%n", e.getCause());
System.exit(-1);
}
System.out.printf("RocketMQ-%s://%s:%d%n", Environment.NAMESRV_ADDR_PROPERTY, "127.0.0.1", 9876);
System.exit(0);
}
}
// 启动Broker
public class BrokerController {
public BrokerController(BrokerConfig config, ServerConfig serverConfig, ClusterManager clusterManager,
TopicConfigManager topicConfigManager, MessageStore msgStore, NamesrvAddrList namesrvAddrList) {
// 初始化Broker控制器
...
}
public void start() {
// 启动Broker
...
}
public void shutdown() {
// 关闭Broker
...
}
}
快速上手RocketMQ
快速入门
- 创建生产者:创建一个
DefaultMQProducer
实例,设置生产者组名和NameServer地址。 - 创建消费者:创建一个
DefaultMQPushConsumer
实例,设置消费者组名和NameServer地址。 - 发送消息:使用生产者发送消息,指定消息的主题和标签。
- 接收消息:使用消费者接收消息,订阅指定的主题和标签。
源码示例
// 创建生产者
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
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 // 未指定Key
);
SendResult sendResult = producer.send(msg);
System.out.printf("SendResult: %s%n", sendResult);
// 关闭生产者
producer.shutdown();
// 创建消费者
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("127.0.0.1:9876");
consumer.subscribe("TopicTest", "TagA");
// 设置消息处理函数
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.printf("Received message: %s%n", new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 启动消费者
consumer.start();
源码解析
public class DefaultMQProducer {
// 创建生产者
public DefaultMQProducer(String producerGroup) {
// 初始化生产者
...
}
// 设置NameServer地址
public void setNamesrvAddr(String namesrvAddr) {
this.namesrvAddr = namesrvAddr;
}
// 启动生产者
public void start() {
// 初始化生产者
...
// 启动网络通信
...
// 注册消息发送器
...
}
// 发送消息
public SendResult send(Message msg) {
// 获取Broker地址列表
List<String> brokerAddresses = this.getBrokerAddrList();
// 选择一个Broker发送消息
String brokerAddress = this.selectOneMasterWithLeastMsg(brokerAddresses);
// 构建消息发送请求
SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
// 发送消息请求
SendResponse sendResponse = this.getDefaultMQProducerImpl.sendMessageSync(brokerAddress, requestHeader, msg);
// 返回发送结果
return new SendResult(sendResponse);
}
// 关闭生产者
public void shutdown() {
// 关闭网络通信
...
// 释放资源
...
}
}
public class DefaultMQPushConsumer {
// 创建消费者
public DefaultMQPushConsumer(String consumerGroup) {
// 初始化消费者
...
}
// 设置NameServer地址
public void setNamesrvAddr(String namesrvAddr) {
this.namesrvAddr = namesrvAddr;
}
// 订阅消息
public void subscribe(String topic, String subscribeExpression) {
// 订阅消息
...
}
// 注册消息监听器
public void registerMessageListener(MessageListener listener) {
// 注册消息监听器
...
}
// 启动消费者
public void start() {
// 初始化消费者
...
// 启动网络通信
...
// 注册消息接收器
...
}
// 关闭消费者
public void shutdown() {
// 关闭网络通信
...
// 释放资源
...
}
}
RocketMQ源码概览
RocketMQ源码结构讲解
源码结构
RocketMQ的源码结构分为以下几个主要模块:
- name-server:NameServer模块,负责维护Broker的元数据信息。
- broker:Broker模块,负责消息的存储和转发。
- client:客户端模块,包含生产者和消费者的相关代码。
- store:存储模块,负责消息的持久化存储。
- common:公共模块,包含一些通用的工具类和常量定义。
- tools:工具模块,包含一些辅助工具和脚本。
- remoting:网络通信模块,负责网络通信和消息传输。
源码文件示例
// NameServer核心代码
public class NamesrvController {
public NamesrvController(ConfManager confManager, String hostIp, int listenPort) {
// 初始化NameServer控制器
...
}
public void start() {
// 启动NameServer
...
}
public void shutdown() {
// 关闭NameServer
...
}
}
// Broker核心代码
public class BrokerController {
public BrokerController(BrokerConfig config, ServerConfig serverConfig, ClusterManager clusterManager,
TopicConfigManager topicConfigManager, MessageStore msgStore, NamesrvAddrList namesrvAddrList) {
// 初始化Broker控制器
...
}
public void start() {
// 启动Broker
...
}
public void shutdown() {
// 关闭Broker
...
}
}
源码解析
public class NettyRemotingServer {
public NettyRemotingServer(String hostIp, int listenPort) {
// 初始化Netty服务端
...
}
public void start() {
// 启动Netty服务端
...
}
public void shutdown() {
// 关闭Netty服务端
...
}
}
public class MessageStore {
public MessageStore(String storeConfigFile) {
// 初始化MessageStore
...
}
public void start() {
// 启动MessageStore
...
}
public void shutdown() {
// 关闭MessageStore
...
}
}
public class DefaultMQProducer {
public DefaultMQProducer(String producerGroup) {
// 初始化生产者
...
}
public void start() {
// 启动生产者
...
}
public SendResult send(Message msg) {
// 发送消息
...
}
public void shutdown() {
// 关闭生产者
...
}
}
public class DefaultMQPushConsumer {
public DefaultMQPushConsumer(String consumerGroup) {
// 初始化消费者
...
}
public void subscribe(String topic, String subscribeExpression) {
// 订阅消息
...
}
public void registerMessageListener(MessageListener listener) {
// 注册消息监听器
...
}
public void start() {
// 启动消费者
...
}
public void shutdown() {
// 关闭消费者
...
}
}
主要模块介绍
NameServer模块
NameServer模块主要负责维护Broker的元数据信息。它会监听Broker的注册请求,并将这些信息存储在内存中。同时,NameServer会向Broker发送心跳包,以保持通信的连通性。
Broker模块
Broker模块是RocketMQ的核心模块,负责消息的存储和转发。Broker会接收生产者发送的消息,并将其存储到磁盘上。同时,Broker会根据消费者的订阅信息,将消息推送给对应的消费者。
客户端模块
客户端模块包含生产者和消费者的代码。生产者负责向Broker发送消息,而消费者则负责从Broker拉取消息。客户端模块会通过NameServer获取Broker的信息,并建立连接。
源码阅读技巧阅读建议
- 熟悉RocketMQ的整体架构:了解RocketMQ的各个模块及其功能,包括NameServer、Broker、生产者、消费者等。
- 掌握RocketMQ的核心概念:熟悉RocketMQ的核心概念,如Topic、Message、Order Message等。
- 从源码中寻找关键逻辑:重点关注消息发送、消息接收和消息存储等核心逻辑。
- 理解网络通信机制:RocketMQ使用Netty进行网络通信,需要了解Netty的基本原理。
- 调试和日志分析:通过调试和查看日志,可以更好地理解RocketMQ的运行过程。
消息发送步骤
- 创建生产者实例:使用
DefaultMQProducer
创建生产者实例,并设置生产者组名。 - 设置NameServer地址:通过
setNamesrvAddr
方法设置NameServer的地址。 - 启动生产者:调用
start
方法启动生产者。 - 创建消息:使用
Message
类创建消息,指定消息的主题、标签、消息体等信息。 - 发送消息:调用
send
方法发送消息。 - 关闭生产者:调用
shutdown
方法关闭生产者。
源码解析发送消息的过程
public class DefaultMQProducer {
// 创建生产者
public DefaultMQProducer(String producerGroup) {
// 初始化生产者
...
}
// 设置NameServer地址
public void setNamesrvAddr(String namesrvAddr) {
this.namesrvAddr = namesrvAddr;
}
// 启动生产者
public void start() {
// 初始化生产者
...
// 启动网络通信
...
// 注册消息发送器
...
}
// 发送消息
public SendResult send(Message msg) {
// 获取Broker地址列表
List<String> brokerAddresses = this.getBrokerAddrList();
// 选择一个Broker发送消息
String brokerAddress = this.selectOneMasterWithLeastMsg(brokerAddresses);
// 构建消息发送请求
SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
// 发送消息请求
SendResponse sendResponse = this.getDefaultMQProducerImpl.sendMessageSync(brokerAddress, requestHeader, msg);
// 返回发送结果
return new SendResult(sendResponse);
}
// 关闭生产者
public void shutdown() {
// 关闭网络通信
...
// 释放资源
...
}
}
常见问题及解决方法
- 消息发送失败:检查生产者的配置是否正确,包括NameServer地址、生产者组名等。同时,检查Broker是否正常运行。
- 消息发送缓慢:优化生产者的发送性能,例如使用异步发送模式。
- 消息丢失:确保消息的持久化配置正确,RocketMQ支持消息的持久化存储,可以防止消息丢失。
源码示例
public class DefaultMQProducer {
public DefaultMQProducer(String producerGroup) {
// 初始化生产者
...
}
public void setNamesrvAddr(String namesrvAddr) {
this.namesrvAddr = namesrvAddr;
}
public void start() {
// 初始化生产者
...
// 启动网络通信
...
// 注册消息发送器
...
}
public SendResult send(Message msg) {
// 获取Broker地址列表
List<String> brokerAddresses = this.getBrokerAddrList();
// 选择一个Broker发送消息
String brokerAddress = this.selectOneMasterWithLeastMsg(brokerAddresses);
// 构建消息发送请求
SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
// 发送消息请求
SendResponse sendResponse = this.getDefaultMQProducerImpl.sendMessageSync(brokerAddress, requestHeader, msg);
// 返回发送结果
return new SendResult(sendResponse);
}
public void shutdown() {
// 关闭网络通信
...
// 释放资源
...
}
}
消费者接收消息流程详解
消费者接收消息的步骤
消息接收步骤
- 创建消费者实例:使用
DefaultMQPushConsumer
创建消费者实例,并设置消费者组名。 - 设置NameServer地址:通过
setNamesrvAddr
方法设置NameServer的地址。 - 订阅消息:调用
subscribe
方法订阅指定的主题和标签。 - 注册消息监听器:通过
registerMessageListener
方法注册一个消息监听器,用于处理接收到的消息。 - 启动消费者:调用
start
方法启动消费者。 - 关闭消费者:调用
shutdown
方法关闭消费者。
源码解析接收消息的过程
public class DefaultMQPushConsumer {
// 创建消费者
public DefaultMQPushConsumer(String consumerGroup) {
// 初始化消费者
...
}
// 设置NameServer地址
public void setNamesrvAddr(String namesrvAddr) {
this.namesrvAddr = namesrvAddr;
}
// 订阅消息
public void subscribe(String topic, String subscribeExpression) {
// 订阅消息
...
}
// 注册消息监听器
public void registerMessageListener(MessageListener listener) {
// 注册消息监听器
...
}
// 启动消费者
public void start() {
// 初始化消费者
...
// 启动网络通信
...
// 注册消息接收器
...
}
// 关闭消费者
public void shutdown() {
// 关闭网络通信
...
// 释放资源
...
}
}
消费者异常处理机制
消息处理异常
- 消息处理异常:如果在消息处理过程中发生异常,可以通过消息监听器抛出异常。RocketMQ会记录异常信息,并根据异常类型进行处理。
- 消息重试机制:RocketMQ支持消息重试机制,如果消息处理失败,可以设置重试次数和重试间隔时间。
- 消息回溯机制:如果消息处理失败,可以通过消息回溯机制重新处理之前的消息。
源码示例
public class DefaultMQPushConsumer {
public void registerMessageListener(MessageListener listener) {
// 注册消息监听器
this.messageListener = listener;
}
public void start() {
// 启动网络通信
...
// 注册消息接收器
this.pullMessageService.start();
}
public void shutdown() {
// 关闭网络通信
...
// 释放资源
...
}
}
public class MessageListenerConcurrently implements MessageListener {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
try {
// 处理消息
...
} catch (Exception e) {
// 消息处理异常
...
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
}
RocketMQ集群部署与监控
集群部署方案
集群部署步骤
- 部署NameServer:部署多个NameServer实例,实现高可用。
- 部署Broker:部署多个Broker实例,实现负载均衡。
- 配置集群模式:在Broker配置文件中,设置集群模式。
- 启动NameServer和Broker:启动部署好的NameServer和Broker实例。
- 配置生产者和消费者:配置生产者和消费者的集群模式。
集群部署示例
# Broker配置文件
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
brokerRole = ASYNC_MASTER
namesrvAddr = localhost:9876
storePathRootDir = /data/rocketmq/store
storePathCommitLog = /data/rocketmq/store/commitlog
storePathConsumeQueue = /data/rocketmq/store/consumequeue
storePathIndex = /data/rocketmq/store/index
messageStoreConfig = /data/rocketmq/conf/messageStoreConfig.json
brokerConfig = /data/rocketmq/conf/brokerConfig.json
// 生产者配置
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.setSendMsgBatch(false);
producer.setSendMsgTimeout(3000);
producer.setInstanceName("Producer");
producer.start();
// 消费者配置
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.setConsumeMessageBatchMaxSize(1);
consumer.setConsumeThreadMin(1);
consumer.setConsumeThreadMax(16);
consumer.setConsumeTimeout(3000);
consumer.setInstanceName("Consumer");
consumer.start();
监控与告警配置
监控方案
- 监控RocketMQ的内置指标:RocketMQ提供了内置的监控指标,可以通过JMX接口获取。
- 配置监控工具:使用Prometheus等监控工具,监控RocketMQ的各项指标。
- 配置告警规则:根据监控数据,配置告警规则,实现告警通知。
监控示例
public class RocketMQMonitor {
public static void main(String[] args) {
// 初始化监控器
RocketMQMonitor monitor = new RocketMQMonitor();
// 获取NameServer的监控数据
List<NamesrvController> nameServers = monitor.getNamesrvControllers();
for (NamesrvController nameServer : nameServers) {
System.out.printf("NameServer: %s, Number of Brokers: %d%n", nameServer.getControllerName(), nameServer.getNumberOfBrokers());
}
// 获取Broker的监控数据
List<BrokerController> brokers = monitor.getBrokerControllers();
for (BrokerController broker : brokers) {
System.out.printf("Broker: %s, Number of Messages: %d, Size of Messages: %d%n", broker.getBrokerName(), broker.getNumberOfMessages(), broker.getSizeOfMessages());
}
}
}
告警配置
- 配置告警规则:定义监控告警规则,如Broker消息积压超过一定数量。
- 配置告警通知:配置告警通知方式,如邮件、短信、钉钉等。
- 监控和维护:定期检查监控数据和告警通知,及时处理问题。
# 告警配置文件
alertEmail = admin@example.com
alertPhone = 12345678901
alertDingTalk = https://www.dingtalk.com/
alertRule = broker.messageQueue.size > 10000
alertInterval = 300
常见问题排查方法
排查步骤
- 检查配置文件:确保NameServer、Broker、生产者和消费者配置正确。
- 查看日志信息:通过日志文件,查看RocketMQ的运行状态和异常信息。
- 监控数据分析:通过监控工具,分析RocketMQ的各项指标。
- 网络通信检查:检查网络通信是否正常,确保NameServer、Broker和客户端之间的通信畅通。
- 重启服务:如果以上方法都无法解决问题,可以尝试重启NameServer、Broker和客户端服务。
排查示例
# 查看NameServer的日志
tail -f /data/rocketmq/logs/name-srv.log
# 查看Broker的日志
tail -f /data/rocketmq/logs/broker.log
# 查看生产者的日志
tail -f /data/rocketmq/logs/producer.log
# 查看消费者的日志
tail -f /data/rocketmq/logs/consumer.log
实战案例:构建一个简单的消息系统
实战项目需求分析
案例需求
- 生产者发送消息:实现一个生产者,每秒发送一条消息。
- 消费者接收消息:实现一个消费者,接收并处理消息。
- 持久化消息:确保消息持久化存储,防止消息丢失。
- 监控与告警:监控消息系统的运行状态,并配置告警规则。
案例架构
- 生产者:每秒发送一条消息。
- 消费者:接收消息,并处理消息。
- Broker:存储和转发消息。
- NameServer:注册和管理Broker。
实战步骤
- 创建生产者:编写生产者代码,每秒发送一条消息。
- 创建消费者:编写消费者代码,接收并处理消息。
- 启动NameServer和Broker:启动NameServer和Broker,确保消息系统的运行。
- 监控和告警配置:配置监控工具和告警规则。
生产者代码示例
public class MessageProducer {
public static void main(String[] args) throws MQClientException {
// 创建生产者实例
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
// 设置NameServer地址
producer.setNamesrvAddr("localhost:9876");
// 启动生产者
producer.start();
// 设置消息发送间隔
long t = System.currentTimeMillis();
while (true) {
// 创建消息
Message msg = new Message("TopicTest", // Topic
"TagA", // Tag
("Hello RocketMQ, message index: " + i).getBytes(RemotingHelper.DEFAULT_CHARSET), // body
null // 未指定Key
);
// 发送消息
SendResult sendResult = producer.send(msg);
System.out.printf("%s%n", sendResult);
// 计算消息发送间隔
long now = System.currentTimeMillis();
long diff = now - t;
if (diff < 1000) {
try {
Thread.sleep(1000 - diff);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
t = now;
}
}
}
}
消费者代码示例
public class MessageConsumer {
public static void main(String[] args) throws MQClientException {
// 创建消费者实例
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
// 设置NameServer地址
consumer.setNamesrvAddr("localhost:9876");
// 订阅消息
consumer.subscribe("TopicTest", "TagA");
// 注册消息监听器
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.printf("Received message: %s%n", new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 启动消费者
consumer.start();
}
}
测试与优化
测试步骤
- 启动NameServer和Broker:确保NameServer和Broker正常运行。
- 启动生产者和消费者:启动生产者和消费者,观察消息的发送和接收过程。
- 监控和告警配置:配置监控工具和告警规则,监控消息系统的运行状态。
测试示例
# 启动NameServer
cd rocketmq-all-4.9.2/bin
./mqnamesrv
# 启动Broker
./mqbroker -n localhost:9876 -c conf/broker-a.properties
# 启动生产者
java -cp rocketmq-all-4.9.2/lib/*:. MessageProducer
# 启动消费者
java -cp rocketmq-all-4.9.2/lib/*:. MessageConsumer
优化建议
- 优化消息发送性能:使用异步发送模式,提高消息发送性能。
- 优化消息接收性能:使用批量接收模式,提高消息接收性能。
- 优化消息存储性能:优化消息存储配置,提高消息存储性能。
优化示例
public class MessageProducer {
public static void main(String[] args) throws MQClientException {
// 创建生产者实例
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
// 设置NameServer地址
producer.setNamesrvAddr("localhost:9876");
// 设置发送模式为异步发送
producer.setSendMsgBatch(true);
// 启动生产者
producer.start();
// 设置消息发送间隔
long t = System.currentTimeMillis();
while (true) {
// 创建消息
Message msg = new Message("TopicTest", // Topic
"TagA", // Tag
("Hello RocketMQ, message index: " + i).getBytes(RemotingHelper.DEFAULT_CHARSET), // body
null // 未指定Key
);
// 发送消息
producer.send(msg);
// 计算消息发送间隔
long now = System.currentTimeMillis();
long diff = now - t;
if (diff < 1000) {
try {
Thread.sleep(1000 - diff);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
t = now;
}
}
}
}
public class MessageConsumer {
public static void main(String[] args) throws MQClientException {
// 创建消费者实例
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
// 设置NameServer地址
consumer.setNamesrvAddr("localhost:9876");
// 设置接收模式为批量接收
consumer.setConsumeMessageBatchMaxSize(10);
// 订阅消息
consumer.subscribe("TopicTest", "TagA");
// 注册消息监听器
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.printf("Received message: %s%n", new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 启动消费者
consumer.start();
}
}
监控与告警示例
public class RocketMQMonitor {
public static void main(String[] args) {
// 初始化监控器
RocketMQMonitor monitor = new RocketMQMonitor();
// 获取NameServer的监控数据
List<NamesrvController> nameServers = monitor.getNamesrvControllers();
for (NamesrvController nameServer : nameServers) {
System.out.printf("NameServer: %s, Number of Brokers: %d%n", nameServer.getControllerName(), nameServer.getNumberOfBrokers());
}
// 获取Broker的监控数据
List<BrokerController> brokers = monitor.getBrokerControllers();
for (BrokerController broker : brokers) {
System.out.printf("Broker: %s, Number of Messages: %d, Size of Messages: %d%n", broker.getBrokerName(), broker.getNumberOfMessages(), broker.getSizeOfMessages());
}
}
}
# 告警配置文件
alertEmail = admin@example.com
alertPhone = 12345678901
alertDingTalk = https://www.dingtalk.com/
alertRule = broker.messageQueue.size > 10000
alertInterval = 300
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦