【RocketMQ】测试RocketMQ主从切换对客户端的影响

测试

当前集群状态:3主6从,启动DLedger

测试方案:

  • 运行客户端Producer和Consumer程序
  • 稳定运行后,将broker的Leader通过脚本停止
  • 观察客户端程序日志
  • 为了方便日志查看,生产者速率为每秒100条,单线程

客户端平稳运行之后,停掉指定broker的Leader,观察客户端程序日志

Producer

有两种情况:

1、如果挂掉的broker当前无客户端在提交消息,则无影响


可以看到,broker-a的Leader停掉之后,客户端检测到连接断开,会停止向broker-a发送消息,等了大概10秒左右,broker-a新的leader选举完成,恢复向broker-a发送消息。

2、如果挂掉的broker有正在提交消息的客户端,则会报错

经过测试,在这种情况下,生产者是会丢消息的。

看看这个超时是怎么回事:
重试的时候有一个 reset topic with namespace的操作,这一步会引起超时。

Consumer

PUSH模式

如果采用PUSH模式消费消息,由于服务端收到消息后会立即向客户端推送消息,实时性很高,broker-a的leader停止之前已完成消息的推送,所以在消息没有积压的情况下,对客户端几乎没有影响,

接下来在客户端消费时加上sleep,模拟消费积压的情况:

测试发现:PUSH模式下,broker收到消息就会一股脑推送给客户端,所以在客户端慢消费的情况下,broker进行主从切换时,消息都被推到了客户端,也就是说,消息是积压在客户端,所以只要客户端正常运行,broker的主从切换对客户端对消费者几乎是无影响的,当broker完成主从切换后,新的leader收到消息后,会继续推送消息给客户端(当然,如果客户端会有慢消费的情况,就要避免使用PUSH模式)

PULL模式

PULL模式下,在broker对应的leader挂掉之后,在拉取消息的时候,因为连不上而报错,直到新的Leader选举完成,才会恢复对该broker的消息拉取,也就是说,如果broker-a的Leader挂掉,到新的Leader选举成功之前,客户端无法消费到broker-a的消息,其他的broker正常。

Producer恢复

Consumer恢复

猜想:如果开启从服务器可读,是否在leader停掉的时候,consumer可以从follower拉取

测试结果:开启slaveReadEnable后,经过多次测试,结果还是一样,原因是RocketMQ的主从读写分离并不是真正意义的主写从读,而是会在主繁忙的时候启用从读

  • maxOffsetPy:代表当前主服务器消息存储文件最大偏移量。
  • maxPhyOffsetPulling:此次拉取消息最大偏移量
  • diff:对于PullMessageService线程来说,当前未被拉取到消息消费端的消息长度
  • TOTAL_PHYSICAL_MEMORY_SIZE:RocketMQ 所在服务器总内存大小,accessMessagelnMemoryMaxRatio表示RocketMQ 所能使用的最大内存比例,超过该内存,消息将被置换出内存; memory表示RocketMQ消息常驻内存的大小,超过该大小, RocketMQ 会将旧的消息置换回磁盘
  • 如果diff大于memory,表示当前需要拉取的消息已经超出了常驻内存的大小,表示主服务器繁忙,此时才建议从从服务器拉取

如果主服务器繁忙则建议下一次从从服务器拉取消息,设置suggestWhichBrokerld为配置文件中whichBrokerWhenConsumeSlowly属性,默认为1。 如果一个Master拥有多台Slave服务器,参与消息拉取负载的从服务器只会是其中一个。

总结:RocketMQ读写分离与 其他中间件的实现方式完全不同, RocketMQ是消费者首先向主服务器发起拉取消息请求,然后主服务器返回一批消息,然后会根据主服务器负载压力与主从同步情况,向从服务器建议下次消息拉取是从主服务器还是从从服务器拉取。所以如果whichBrokerWhenConsumeSlowly配置的是0,则永远不会从从服务器拉取消息。

总结

  • 对于生产者,如果客户端没有正在向挂掉Leader的broker提交消息,则客户端没影响,不会丢消息;反之,则会报超时的错误,并且会丢消息,所以说,高并发情况下,丢消息的可能性还是很大的。当然,即使没有发生主从切换,正常情况下,由于各种原因,也会产生超时等异常,客户端需要在catch到异常之后做一些补偿措施。
  • 对于生产者,推模式下,由于服务端收到消息就立即向客户端推送,也就是说在broker挂之前,就会把消息都推送给客户端,所以几乎无影响(排除极端情况:刚收到消息,还没来得及推送就挂掉了);拉模式下,如果broker对应的Leader挂掉,则消费者客户端在拉取该broker上的消息时,会报网络连接错误,直到新的Leader选举成功,不影响从其他正常的broker拉取消息。

遇到的问题

问题1:broker-b新增了一个slave,不复制消息

​ 查看broker日志发现,由于开启了ACL,没有将新slave的机器IP加到master的plain_acl.yml的全局白名单中,报鉴权失败错误。

问题2:测试时,消息只发到broker-b和broker-c上

​ broker-a的三个节点是新增的,topic创建时只选择可topic-b和topic-c,broker-a收不到加入集群之前创建topic的消息。由此可见,在集群内进行扩容操作时(集群扩主节点、Topic扩Queue等),一定要考虑是否会对业务产生影响,如:Topic扩Queue时,对于生产到新的Queue上的消息,由于之前的消费者没有与之有订阅关系,会出现消费不到的情况。

Guess you like

Origin blog.csdn.net/sinat_14840559/article/details/116748051