RocketMQ—Queue队列分配算法

RocketMQ是一个Java开发的组件,具备异步处理、应用解耦、流量削峰等优势。Queue分配策略包括平均分配、环形平均、一致性Hash和同机房策略。消费者可以设置为集群模式或广播模式。本文深入解析了RocketMQ的Queue分配算法的底层源码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 RocketMQ(Java语言开发的组件):

mq:生产者到消费者的设计模式;

生产者:往queue存放消息;

消息队列:储存消息;

消费者:消费消息;

RocketMQ优势:

①异步处理:比如解决es中冷启动的问题,mysql与redis在高并发场景下双写不一致的问题(canal),订单超时未支付的问题,秒杀场景下超买超卖的问题(redission);

②应用解耦:可以使得系统达到完全解耦;

③流量削峰:高并发情景下,消息队列可以将大量请求缓存起来,分散到很长一段时间处理,避免请求丢失或者系统被压垮;

④分布式架构:高可用,qps可达10万级,得到淘宝天猫双十一的实战稳定性验证;

RocketMQ工作流程:

 发送消息的步骤:
1.创建消息生产者producer(DefaultMQProducer),并制定生产者group
2.指定Nameserver地址
3.启动producer
4.创建Message对象,指定主题Topic、消息体
5.发送消息
6.关闭生产者producer

Queue分配算法:

一个Topic中的Queue只能由Consumer Group中的一个Consumer进行消费,而一个Consumer可以同时消费多个Queue中的消息。常见的Queue分配算法有四种,分别是:平均分配策略、环形平均策略、一致性hash策略、同机房策略。这些策略是通过在创建Consumer时的构造器传进去的;

①平均分配策略

算法公式:avg=QueueCount(队列数量)/ConsumerCount(消费者数量)

若能整除,则按照avg个Queue诸葛分配Cons

### RocketMQ 消息队列使用教程 #### 1. 安装与配置 为了安装和配置 RocketMQ,需先下载并解压官方提供的二进制包。启动 NameServer 和 Broker 是必要的操作。 ```bash nohup sh bin/mqnamesrv & nohup sh bin/mqbroker -n localhost:9876 & ``` 这会分别启动名称服务器(NameServer)和服务代理(Broker),其中 `-n` 参数指定了NameServer 的地址[^1]。 #### 2. 生产者发送消息 创建生产者实例时要指定 `ProducerGroup` 名字以及连接到哪个 Name Server 地址。之后通过调用 send 方法来向目标 Topic 发送消息: ```java DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name"); producer.setNamesrvAddr("localhost:9876"); producer.start(); for (int i = 0; i < 100; i++) { Message msg = new Message("TopicTest", "TagA", ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)); SendResult sendResult = producer.send(msg); } producer.shutdown(); ``` 这段代码展示了如何初始化一个生产者对象并向特定主题(Topic)发布一系列的消息。 #### 3. 消费者接收消息 消费者同样需要定义所属组名,并订阅感兴趣的 Topics 及其标签(Tag)。当接收到新消息时触发监听器逻辑处理这些数据: ```java DefaultLitePullConsumer consumer = new DefaultLitePullConsumer("example_group_name_1"); consumer.subscribe("TopicTest", "*"); // 订阅所有tag下的topic consumer.setMessageModel(MessageModel.BROADCASTING); consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); consumer.start(); ``` 此部分说明了怎样建立拉取消费模式(Lite Pull Consumer), 并注册回调函数用于实际业务场景中的消息消费过程。 --- ### 最佳实践建议 - **读写分离机制** RocketMQ 设计上将读取(Read Queue)与写入(Write Queue)分开管理是为了提高系统的灵活性和性能优化能力。虽然理论上可以设置相同的数量(`readQueueNums=writeQueueNums`)简化配置流程,但在某些情况下这样做可能会限制系统的表现潜力。例如,在高并发环境下适当增加 Write Queues 数量有助于缓解压力;而在低负载条件下减少 Read Queues 则能节省资源开销[^2]。 - **动态调整队列数目** 允许独立设定读/写队列的数量使得管理员可以根据实时流量变化灵活地进行扩展或收缩操作而不影响现有服务运行状态。这种特性对于应对突发访问高峰特别有用,因为它提供了更细粒度的控制手段去平衡吞吐率和延迟之间的关系. - **Rebalance 算法选择** 默认采用的是平均分配策略 (`AllocateMessageQueueAveragely`) 来决定哪些 Consumers 应该负责处理哪一部分的数据流。然而根据具体应用场景的不同可能还需要考虑其他类型的再均衡方法以达到最优效果。比如轮询方式能够更好地支持大规模集群环境下的负载均衡需求[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值