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. [LC] 70. Climbing Stairs

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  2. SHELL用法六(Find语句)

    1.SHELL编程Find语句案例实战 1)SHELL编程四剑客工具:Find.Grep.Sed.Awk,通过四剑客可以完成常规Linux指令无法完成或者比较复杂的功能,学好SHELL编程四剑客有助于 ...

  3. windows下apache运行环境搭建

    apache的安装 要求: 1,不要安装到有中文的目录中: 2,尽量将apache,php,mysql安装到一个总的目录,便于管理.(如都建立在amp目录下,然后在该目录下分别建立apache,php ...

  4. 搭建harbor企业级私有registry

    主机环境要求 硬件Hardware Resource Capacity Description CPU minimal 2 CPU 4 CPU is prefered Mem minimal 4GB ...

  5. windows下的tfjs-node安装异常总结

    大约有半年没有写博客了,奔波于上海这座魔都之中.险些忘了自己是个有梦想的全栈工程师 书接上回,由于个人非常厌恶python的语法,半年前发现了tensorflow.js这个宝贝(下简称tfjs),喜出 ...

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

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

  7. 别恐慌,大众关心的人工智能问题学界都在努力求解——我眼中的AAAI 2015大会

    2015大会" title="别恐慌,大众关心的人工智能问题学界都在努力求解--我眼中的AAAI 2015大会"> 作者:微软亚洲研究院副研究员 黄铂钧 今年是美国 ...

  8. 吴裕雄--天生自然python编程:实例(1)

    str = "www.runoob.com" print(str.upper()) # 把所有字符中的小写字母转换成大写字母 print(str.lower()) # 把所有字符中 ...

  9. Java正则表达式java.util.regex类的简单使用

    1.什么是正则表达式? 正则表达式(regular expression)是根据字符串集合内每个字符串共享的共同特性来描述字符串集合的一种途径.正则表达式可以用于搜索.编辑或者处理文本和数据. Jav ...

  10. POJ 3522 用不同的排序方式

      这是一个蜜汁WA了的代码.. 说好的样例对了就是对了呢orz 反正我个人认为思路是没问题的不知道WA在哪了,丢个坑在这里以后填吧 //思路: //1节点连接的边都记录下来,依次克鲁斯卡尔枚举得出最 ...