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

手写RocketMQ资料

标签:
中间件
概述

手写RocketMQ资料旨在帮助开发者深入了解RocketMQ的核心原理和实现细节,通过详细的手写过程,可以让读者更好地掌握RocketMQ的内部机制。本文从RocketMQ的基本概念入手,逐步深入到消息发送与接收、消息过滤、集群部署等关键技术点,帮助读者全面理解RocketMQ的工作原理。

1. RocketMQ简介

RocketMQ 是一款开源的分布式消息中间件,由阿里巴巴开源并贡献给 Apache 基金会。它具有高性能、高可靠性和高扩展性等特点,被广泛应用于企业的消息传递系统中。本文将从 RocketMQ 的核心概念、消息模型、消息发送与接收机制以及集群部署等方面进行详细讲解。

2. RocketMQ消息模型

RocketMQ 的消息模型主要包括三种类型的消息:普通消息、有序消息和事务消息。

2.1 普通消息

普通消息是最基本的消息类型,适用于大多数场景。发送普通消息时,RocketMQ 会根据消息的 Key 和 Topic 生成唯一的 Message ID,确保消息的唯一性。

示例代码:

Message msg = new Message("TopicTest", // topic
    "TagA", // tag
    "OrderID188", // key
    "Hello World".getBytes(RemotingHelper.DEFAULT_CHARSET)); // body

SendResult sendResult = producer.send(msg);
System.out.println(sendResult.getMsgId());

2.2 有序消息

有序消息是指消息的发送和接收顺序保持一致。RocketMQ 通过消息的 Key 来保证消息的顺序性。

示例代码:

Message msg2 = new Message("TopicTest", // topic
    "TagB", // tag
    "OrderID188", // key
    "Hello World".getBytes(RemotingHelper.DEFAULT_CHARSET)); // body

SendResult sendResult = producer.send(msg2);
System.out.println(sendResult.getMsgId());

2.3 事务消息

事务消息是指发送消息时需要保证消息与数据库操作的事务一致性。RocketMQ 支持两种事务消息模式:半事务消息和全事务消息。

示例代码:

TransactionMQProducer producer = new TransactionMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();

DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();

producer.send(msg, new MessageQueueTransactionAsync() {
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        // 这里进行数据库操作,返回LocalTransactionState.UNKNOW,表示暂时不知道事务状态
        return LocalTransactionState.UNKNOW;
    }

    @Override
    public LocalTransactionState checkLocalTransaction(Message msg) {
        // 这里进行检查数据库操作的结果,返回LocalTransactionState.COMMIT_MESSAGE或LocalTransactionState.ROLLBACK_MESSAGE
        return LocalTransactionState.COMMIT_MESSAGE;
    }
});
3. RocketMQ消息发送与接收

3.1 消息发送

消息发送是 RocketMQ 的核心功能之一。RocketMQ 提供了多种发送消息的方式,包括同步发送、异步发送和批量发送。

示例代码:

Message msg = new Message("TopicTest", // topic
    "TagA", // tag
    "OrderID188", // key
    "Hello World".getBytes(RemotingHelper.DEFAULT_CHARSET)); // body

SendResult sendResult = producer.send(msg);
System.out.println(sendResult.getMsgId());

3.2 消息接收

消息接收是指消费者从消息队列中拉取消息并进行处理。RocketMQ 提供了多种消息消费的方式,包括普通消费和延迟消费。

示例代码:

MessageQueue mq = consumer.getDefaultMQConsumerImpl().getRebalanceImpl().getConsumerRunningInfo().getMQ().get(0);
Message msg = new Message("TopicTest", // topic
    "TagA", // tag
    "OrderID188", // key
    "Hello World".getBytes(RemotingHelper.DEFAULT_CHARSET)); // body

DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("TopicTest", "*");
consumer.registerMessageListener(new MessageListenerConcurrently() {
    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
        for (MessageExt msg : msgs) {
            System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msg);
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
});
consumer.start();
4. RocketMQ消息过滤

RocketMQ 支持多种消息过滤方式,包括标签过滤、SQL 92 过滤和消息属性过滤。

4.1 标签过滤

标签过滤是最基本的消息过滤方式,通过设置消息的标签来实现消息的过滤。

示例代码:

Message msg = new Message("TopicTest", // topic
    "TagA", // tag
    "Hello World".getBytes(RemotingHelper.DEFAULT_CHARSET)); // body

MessageQueue mq = consumer.getDefaultMQConsumerImpl().getRebalanceImpl().getConsumerRunningInfo().getMQ().get(0);
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
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("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msg);
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
});
consumer.start();

4.2 SQL 92 过滤

SQL 92 过滤是一种更为灵活的消息过滤方式,通过 SQL 语句来过滤消息。

示例代码:

Message msg = new Message("TopicTest", // topic
    "TagA", // tag
    "Hello World".getBytes(RemotingHelper.DEFAULT_CHARSET)); // body

DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("TopicTest", "TagA and (key = 'OrderID188')");
consumer.registerMessageListener(new MessageListenerConcurrently() {
    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
        for (MessageExt msg : msgs) {
            System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msg);
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
});
consumer.start();

4.3 消息属性过滤

消息属性过滤是通过设置消息的属性来实现消息的过滤。

示例代码:

Message msg = new Message("TopicTest", // topic
    "TagA", // tag
    "Hello World".getBytes(RemotingHelper.DEFAULT_CHARSET)); // body
msg.putUserProperty("key", "value");

DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
consumer.setNamesrvAddr("localhost:9876");
consumer.subscribe("TopicTest", "TagA and (key = 'value')");
consumer.registerMessageListener(new MessageListenerConcurrently() {
    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
        for (MessageExt msg : msgs) {
            System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msg);
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
});
consumer.start();
5. RocketMQ集群部署

RocketMQ 集群部署是实现高可用和高可靠性的关键。RocketMQ 支持多种集群部署方式,包括单机部署、主从模式和主备模式。

5.1 单机部署

单机部署是最简单的部署方式,适合开发和测试环境。

示例代码:

DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();

Message msg = new Message("TopicTest", // topic
    "TagA", // tag
    "OrderID188", // key
    "Hello World".getBytes(RemotingHelper.DEFAULT_CHARSET)); // body

SendResult sendResult = producer.send(msg);
System.out.println(sendResult.getMsgId());

5.2 主从模式

主从模式是一种常见的集群部署方式,通过主从节点之间的数据同步实现高可用。

示例代码:

// 配置主节点
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();

// 配置从节点
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
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("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msg);
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
});
consumer.start();

5.3 主备模式

主备模式是一种高可用的集群部署方式,通过主备节点之间的切换实现故障转移。

示例代码:

// 配置主节点
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("localhost:9876");
producer.start();

// 配置备节点
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
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("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msg);
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
});
consumer.start();
6. 总结

本文详细介绍了 RocketMQ 的核心原理和实现细节,包括消息模型、消息发送与接收、消息过滤和集群部署等方面。通过本文的讲解,读者可以更好地掌握 RocketMQ 的内部机制,并能够将其应用于实际项目中。

点击查看更多内容
TA 点赞

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

评论

作者其他优质文章

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

关注作者,订阅最新文章

阅读免费教程

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

100积分直接送

付费专栏免费学

大额优惠券免费领

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

举报

0/150
提交
取消