directorio
balanceo de carga RocketMQ
productor para MessageQueue
el equilibrio de carga
Se puede conocer a través de la depuración del código, la llamada MessageQueue
información de colas en el corredor, cada tema puede especificar el número de la cola correspondiente en el momento de la creación. Es decir, un tema del mensaje almacenado en la pluralidad de intermediario primario
productor de equilibrio de carga
carga lateral productor de equilibrio en la elección de la broker primaria correspondiente. Enrutamiento cuando el productor envía un mensaje del mensaje a ver en el extremo que se encamina al corredor. Los siguientes dos métodos principales para enviar mensajes a decir en: 系统计算路由MessageQueue
, 自定义路由MessageQueue
.
El sistema calcula la ruta MessageQueue
SendResult send = producer.send(message, 60 * 1000);
Otro sistema de algoritmo de enrutamiento para calcular la ruta 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);
}
enrutamiento personalizado 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);
balanceo de carga del consumidor
Ajuste el lado del consumidor es responsable de equilibrar la política
En consumer.statrt()
MessageQueue en adelante, los consumidores han suscrito tema del equilibrio de carga DefaultConsumerPushImpl.start()
en los this.rebalanceImpl.setAllocateMessageQueueStrategy(this.defaultMQPushConsumer.getAllocateMessageQueueStrategy());
rendimientos por defectoAllocateMessageQueueAveragely
Asegurando la concordancia entre la estrategia
- AllocateMessageQueueAveragely
El tiempo de carga de equilibrio
// 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");
}
realización
/**
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;
}