大家好,又见面了,我是你们的朋友全栈君。
本文对RocketMQ的仅做理论性阐述,以便更深入的理解RocketMQ的内部机制,遇到棘手的问题更容易入手解决。关于代码实战请参考鄙人的另一篇文章:RocketMQ 入门使用详解
1. RocketMQ的负载均衡:
RocketMQ采用轮询所有队列的方式确定消息发送到哪一个队列,RocketMQ提供了两种消息队列轮询(MessageQueueSelector)方式,一种是根据Hash值进行轮询(即
SelectMessageQueueByHash implements MessageQueueSelector),另一种是随机方式(即SelectMessageQueueByRandoom implements MessageQueueSelector)。
图片来源于:分布式开放消息系统(RocketMQ)的原理与实践
具体源码如下:
private SendResult sendSelectImpl(Message msg, MessageQueueSelector selector, Object arg, CommunicationMode communicationMode, SendCallback sendCallback, long timeout) throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
this.makeSureStateOK();
Validators.checkMessage(msg, this.defaultMQProducer);
TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic());
if(topicPublishInfo != null && topicPublishInfo.ok()) {
MessageQueue mq = null;
try {
mq = selector.select(topicPublishInfo.getMessageQueueList(), msg, arg);
} catch (Throwable var11) {
throw new MQClientException("select message queue throwed exception.", var11);
}
if(mq != null) {
return this.sendKernelImpl(msg, mq, communicationMode, sendCallback, timeout);
} else {
throw new MQClientException("select message queue return null.", (Throwable)null);
}
} else {
throw new MQClientException("No route info for this topic, " + msg.getTopic(), (Throwable)null);
}
}
2.RocketMQ的消费者获取重复消息的问题
RocketMQ目前不能够保证消息重复消息的不出现,如果业务方严格要求不重复,则业务方需要自己处理消息重复的问题,具体方式如下:
2.1 消费者处理MQ消息时必须幂等性(即无论接收到多少相同的消息,执行后的结果一致),如果不具有幂等性,则转换成幂等性处理方法;
2.2 业务方自己保证每条发送到RocketMQ消息都有唯一的ID,这样消费者根据消息的唯一ID去重,并确保消息处理成功。
<待续>
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/149570.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...