RocketMQ的负载均衡

producer对MessageQueue的负载均衡



通过调试代码可以知道,所谓的MessageQueue就是broker上的队列信息,每个topic在创建的时候可以指定相应的queue的数量。也就是说,一个topic的消息存储在多个主broker中

producer负载均衡

producer端的负载均衡主要是在选择对应的broker。在producer发送消息的时候会对消息进行路由,看到底是路由到哪个broker。下面主要说下以下两种发送消息的方法:系统计算路由MessageQueue自定义路由MessageQueue

系统计算路由MessageQueue

 SendResult send = producer.send(message, 60 * 1000);

系统计算路由MessageQueue的其他路由算法

    public MessageQueue selectOneMessageQueue(final TopicPublishInfo tpInfo, final String lastBrokerName) {
if (this.sendLatencyFaultEnable) {
try {
int index = tpInfo.getSendWhichQueue().getAndIncrement();
for (int i = 0; i < tpInfo.getMessageQueueList().size(); i++) {
int pos = Math.abs(index++) % tpInfo.getMessageQueueList().size();
if (pos < 0)
pos = 0;
MessageQueue mq = tpInfo.getMessageQueueList().get(pos);
if (latencyFaultTolerance.isAvailable(mq.getBrokerName())) {
if (null == lastBrokerName || mq.getBrokerName().equals(lastBrokerName))
return mq;
}
} final String notBestBroker = latencyFaultTolerance.pickOneAtLeast();
int writeQueueNums = tpInfo.getQueueIdByBroker(notBestBroker);
if (writeQueueNums > 0) {
final MessageQueue mq = tpInfo.selectOneMessageQueue();
if (notBestBroker != null) {
mq.setBrokerName(notBestBroker);
mq.setQueueId(tpInfo.getSendWhichQueue().getAndIncrement() % writeQueueNums);
}
return mq;
} else {
latencyFaultTolerance.remove(notBestBroker);
}
} catch (Exception e) {
log.error("Error occurred when selecting message queue", e);
} return tpInfo.selectOneMessageQueue();
} // 默认策略(路由到当前的broker主节点列表取模后的broker中)
return tpInfo.selectOneMessageQueue(lastBrokerName);
}

自定义路由MessageQueue

   SendResult send = producer.send(message, new MessageQueueSelector() {
/**
*
* @param mqs 通过name server返回的broker主节点列表
* @param msg 当前消息
* @param arg
* @return
*/
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
int size = mqs.size();
long timeMillis = System.currentTimeMillis(); return mqs.get((int)timeMillis % size);
}
}, 60 * 1000);

Consumer的负载均衡

消费端设置负责均衡策略

consumer.statrt()中,consumer会对所订阅的topic上的messagequeue做负载均衡DefaultConsumerPushImpl.start()下的 this.rebalanceImpl.setAllocateMessageQueueStrategy(this.defaultMQPushConsumer.getAllocateMessageQueueStrategy());, 默认返回的是AllocateMessageQueueAveragely

负责均衡策略

  1. AllocateMessageQueueAveragely

负载均衡的时机

 // RebalanceService
@Override
public void run() {
log.info(this.getServiceName() + " service started"); while (!this.isStopped()) {
this.waitForRunning(waitInterval);
// 开始进行分配
this.mqClientFactory.doRebalance();
} log.info(this.getServiceName() + " service end");
}

具体实现

/**
consumerGroup : 消费组名称
currentCID:当前消费者实例Id(随机数)
mqAll: 该topic对应的queue的信息列表
cidAll: 消费组中所有的消费者列表 */
@Override
public List<MessageQueue> allocate(String consumerGroup, String currentCID, List<MessageQueue> mqAll,
List<String> cidAll) {
if (currentCID == null || currentCID.length() < 1) {
throw new IllegalArgumentException("currentCID is empty");
}
if (mqAll == null || mqAll.isEmpty()) {
throw new IllegalArgumentException("mqAll is null or mqAll empty");
}
if (cidAll == null || cidAll.isEmpty()) {
throw new IllegalArgumentException("cidAll is null or cidAll empty");
} List<MessageQueue> result = new ArrayList<MessageQueue>();
if (!cidAll.contains(currentCID)) {
log.info("[BUG] ConsumerGroup: {} The consumerId: {} not in cidAll: {}",
consumerGroup,
currentCID,
cidAll);
return result;
} int index = cidAll.indexOf(currentCID);
int mod = mqAll.size() % cidAll.size();
int averageSize =
mqAll.size() <= cidAll.size() ? 1 : (mod > 0 && index < mod ? mqAll.size() / cidAll.size()
+ 1 : mqAll.size() / cidAll.size());
int startIndex = (mod > 0 && index < mod) ? index * averageSize : index * averageSize + mod;
int range = Math.min(averageSize, mqAll.size() - startIndex);
for (int i = 0; i < range; i++) {
result.add(mqAll.get((startIndex + i) % mqAll.size()));
}
return result;
}

RocketMQ-2.RocketMQ的负载均衡的更多相关文章

  1. RocketMq --consumer自动实现负载均衡

    这边使用一个producer和两个consumer是实现负载均衡. 看一下代码示例 package com.alibaba.rocketmq.example.message.model; import ...

  2. RocketMQ之八:水平扩展及负载均衡详解

    RocketMQ是一个分布式具有高度可扩展性的消息中间件.本文旨在探索在broker端,生产端,以及消费端是如何做到横向扩展以及负载均衡的. NameServer集群 提供轻量级的服务发现和路由.每个 ...

  3. 深入剖析 RocketMQ 源码 - 负载均衡机制

    RocketMQ作为一款流行的消息中间件在各大互联网应用广泛,本文主要分析RocketMq在消息生产和消费过程中的负载均衡机制,并创新提出消费端负载均衡策略的改写以实现固定IP消费的可能.

  4. rocketmq消费负载均衡--push消费为例

    本文介绍了DefaultMQPushConsumerImpl消费者,客户端负载均衡相关知识点.本文从DefaultMQPushConsumerImpl启动过程到实现负载均衡,从源代码一步一步分析,共分 ...

  5. 异数OS 织梦师-Xnign(四)-- 挑战100倍速Nginx,脚踩F5硬件负载均衡

    . 异数OS 织梦师-Xnign(四)– 挑战100倍速Nginx,脚踩F5硬件负载均衡 本文来自异数OS社区 github: https://github.com/yds086/HereticOS ...

  6. Windows下使用Nginx+Tomact做负载均衡

    前言 今天,王子与大家闲谈一下如何在Windows下使用Nginx+Tomcat做负载均衡的完整步骤,小伙伴们可以试着自己动手实践一下哦. 另外说明一点,本篇文章是纯实操文章,不涉及太多原理的解读,后 ...

  7. 【大型网站技术实践】初级篇:借助LVS+Keepalived实现负载均衡

    一.负载均衡:必不可少的基础手段 1.1 找更多的牛来拉车吧 当前大多数的互联网系统都使用了服务器集群技术,集群即将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是Web应用服务 ...

  8. Windows平台分布式架构实践 - 负载均衡

    概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行.那么大家(开发者和企业)为 ...

  9. 微软Azure 经典模式下创建内部负载均衡(ILB)

    微软Azure 经典模式下创建内部负载均衡(ILB) 使用之前一定要注意自己的Azure的模式,老版的为cloud service模式,新版为ARM模式(资源组模式) 本文适用于cloud servi ...

随机推荐

  1. volatile、synchronized、ReentrantLock与CAS

    目录 一.JVM内存模型: 二.volatile关键字 1.volatile保证内存可见性. 2.能禁止指令重排序 3.不能保证原子性 三.synchronized关键字 1.内存可见性: 2.操作的 ...

  2. 用Spring Tool Suite简化你的开发

    如果你是一个喜欢用spring的人,你可能会在欣赏spring的强大功能外,对其各样的配置比较郁闷,尤其是相差较大的版本在配置文件方面会存在差异,当然你可以去花不少的时间去网上查找相关的资料,当你准备 ...

  3. [LC] 240. Search a 2D Matrix II

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  4. @Value默认值填null

    @Value("${topology.position.spout.maxpending:#{null}}") private Integer spoutMaxPending; @ ...

  5. 深入理解 C/C++ 数组和指针

    本文转载自CSDN@WalkingInTheWind,原文链接:https://blog.csdn.net/luckyxiaoqiang/article/details/7044380 C语言中数组和 ...

  6. jenkins使用(2)-配置项目代码的3种方式

    1.通过cmd命令直接进入项目代码的文件夹运行,注意路径中不要有中文 2.代码放到工作区:从本地复制项目代码到工作区目录下 代码结构的优化 3.代码连接git或svn,实时更新代码 svn检出 然后上 ...

  7. MongoDBcrud操作,采集部分代码

    using System; using System.Collections.Generic; using System.ComponentModel.Design; using System.Lin ...

  8. Android开发之《libyuv库的使用》

    转自:http://bashell.nodemedia.cn/archives/build-google-libyuv-with-ndk-for-android.html 官方网站:https://c ...

  9. 如何有效地报告Bug

    英文原文:Simon Tatham,编译:Dasn 引言 为公众写过软件的人,大概都收到过很拙劣的bug报告,例如: 在报告中说“不好用”: 所报告内容毫无意义: 在报告中用户没有提供足够的信息: 在 ...

  10. python socketserver 实现 ftp功能

    需求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 允许用户查看当前目 ...