RocketMQ-2.RocketMQ的负载均衡
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

负责均衡策略

- 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的负载均衡的更多相关文章
- RocketMq --consumer自动实现负载均衡
这边使用一个producer和两个consumer是实现负载均衡. 看一下代码示例 package com.alibaba.rocketmq.example.message.model; import ...
- RocketMQ之八:水平扩展及负载均衡详解
RocketMQ是一个分布式具有高度可扩展性的消息中间件.本文旨在探索在broker端,生产端,以及消费端是如何做到横向扩展以及负载均衡的. NameServer集群 提供轻量级的服务发现和路由.每个 ...
- 深入剖析 RocketMQ 源码 - 负载均衡机制
RocketMQ作为一款流行的消息中间件在各大互联网应用广泛,本文主要分析RocketMq在消息生产和消费过程中的负载均衡机制,并创新提出消费端负载均衡策略的改写以实现固定IP消费的可能.
- rocketmq消费负载均衡--push消费为例
本文介绍了DefaultMQPushConsumerImpl消费者,客户端负载均衡相关知识点.本文从DefaultMQPushConsumerImpl启动过程到实现负载均衡,从源代码一步一步分析,共分 ...
- 异数OS 织梦师-Xnign(四)-- 挑战100倍速Nginx,脚踩F5硬件负载均衡
. 异数OS 织梦师-Xnign(四)– 挑战100倍速Nginx,脚踩F5硬件负载均衡 本文来自异数OS社区 github: https://github.com/yds086/HereticOS ...
- Windows下使用Nginx+Tomact做负载均衡
前言 今天,王子与大家闲谈一下如何在Windows下使用Nginx+Tomcat做负载均衡的完整步骤,小伙伴们可以试着自己动手实践一下哦. 另外说明一点,本篇文章是纯实操文章,不涉及太多原理的解读,后 ...
- 【大型网站技术实践】初级篇:借助LVS+Keepalived实现负载均衡
一.负载均衡:必不可少的基础手段 1.1 找更多的牛来拉车吧 当前大多数的互联网系统都使用了服务器集群技术,集群即将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是Web应用服务 ...
- Windows平台分布式架构实践 - 负载均衡
概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行.那么大家(开发者和企业)为 ...
- 微软Azure 经典模式下创建内部负载均衡(ILB)
微软Azure 经典模式下创建内部负载均衡(ILB) 使用之前一定要注意自己的Azure的模式,老版的为cloud service模式,新版为ARM模式(资源组模式) 本文适用于cloud servi ...
随机推荐
- 整理汇总系统中空值的使用方法,后台+jsp
一.后台: 1. entity.getStringValue().isEmpty()://字符串自带方法,未发现非空方法实现原理:判断值的长度 public boolean isEmpty() { r ...
- MOOC(14)- 从数据库中获取预期结果
数据库中的预期结果写的是SQL语句 从表格中读取到SQL语句,再去数据库获取真正的预期结果 # -*- coding: utf-8 -*- # @Time : 2020/2/18 9:50 # @Fi ...
- 吴裕雄--天生自然 JAVASCRIPT开发学习:对象 实例(2)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- C++中stoi函数
作用: 将 n 进制的字符串转化为十进制 头文件: #include <string> 用法: stoi(字符串,起始位置,n进制),将 n 进制的字符串转化为十进制 示例: stoi(s ...
- MSSS攝影大賽計劃書(第三版)
比賽內容:對香港的城市風景以及自然風光的攝影 預期成果: 提升同學對香港的認識,鼓勵學生走出大學學園去瞭解香港,同時豐富會員的課餘活動,培養同學的興趣愛好 比賽時間:4月1-15日 最後作品提交時間: ...
- Serializable 接口(序列化)
目录 Serializable 接口(序列化) 前言 用途 如何实现 异常 serialVersionUID transient关键字 Serializable 接口(序列化) 前言 查看API文档时 ...
- 吴裕雄--天生自然HTML学习笔记:HTML 脚本
JavaScript 使 HTML 页面具有更强的动态和交互性. <!DOCTYPE html> <html> <head> <meta charset=&q ...
- Docker的网络类型
四种网络类型: None:不为容器配置任何网络功能,--net=noneContainer:与另一个运行中的容器共享Network Namespace,--net=container:containe ...
- python djangjo 文件上传
视图: request.GET 获取数据 request.POST 提交数据 request.FILES 获取文件用 checkbox 等多选的内容 request.POST.getlist ...
- JS去重函数的扩展应用
数据: 账单id[1,1,1,1,2,2,2,3,3,3,3,3,3,3], 相对于账单id的金额[100,120,110,150,200,180,220,115,150,120,180,220,14 ...