rocketmq3.26研究之Failover下producer的表现

来源:互联网 发布:雷电ol相似网络手游 编辑:程序博客网 时间:2024/05/19 03:43

1 环境如下:


说明:

producer默认会依次轮询  broker_a-q0,broker_a-q1,broker_a-q2,broker_a-q3,broker_b-q0,broker_b--q1,broker_b-q2,broker_b-q3  进行消息发送。

这个对应关系列表暂时称作 topic路由,下面会用到该词语。

2  消息发送流程:

每次发送消息都需要知道此次发往的borker的master地址及queue id,故下面的流程图就是获取这两个信息的流程:


说明:

1 默认调用send方法进行发送

2.1 调用其实现类中的sendDefaultImpl进行发送

2.2 根据topic从本地map(topicPublishInfoTable)中获取topic路由.

3 第一次本地map中是获取不到的,故需要从name server中获取

4 从name server查询关系

5 更新到本地map中

3 failover表现:

3.1 假设现在把broker_b的master kill掉,producer端会抛出如下异常:

2015-08-10 12:04:15,090 [pool-1-thread-1] WARN RocketmqClient - sendKernelImpl exception
com.alibaba.rocketmq.remoting.exception.RemotingConnectException: connect to <10.10.81.94:10915> failed
at com.alibaba.rocketmq.remoting.netty.NettyRemotingClient.invokeSync(NettyRemotingClient.java:641) ~[classes/:na]
at com.alibaba.rocketmq.client.impl.MQClientAPIImpl.sendMessageSync(MQClientAPIImpl.java:306) ~[classes/:na]
at com.alibaba.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:289) ~[classes/:na]
at com.alibaba.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendKernelImpl(DefaultMQProducerImpl.java:679) [classes/:na]
at com.alibaba.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:500) [classes/:na]
at com.alibaba.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1031) [classes/:na]
at com.alibaba.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1025) [classes/:na]
at com.alibaba.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:95) [classes/:na]
at com.sohu.index.tv.mq.rocketmq.ProducerRocketMQ.publish(ProducerRocketMQ.java:60) [classes/:na]

此时,由于无法连接broker,消息发送失败。

3.2 定时任务

producer默认会启动定时任务MQClientInstance.this.updateTopicRouteInfoFromNameServer()

其作用是默认每隔30s从name server查询producer对应的topic路由,并更新到DefaultMQProducerImpl.topicPublishInfoTable中。

由于broker_b挂掉,故只会获取到broker_b的slave的地址(假设有slave),而slave最终会被如下代码过滤掉:

MQClientInstance.topicRouteData2TopicPublishInfo

if (!brokerData.getBrokerAddrs().containsKey(MixAll.MASTER_ID)) {

continue;

}

所以最终结论,broker_b相关的queue的对应关系会移除掉,最终的结果是只往broker_a发送消息。

0 0