autoheal:即rabbitmq在发生网络分区后的恢复机制
恢复逻辑分为四步:
1.选出获胜的网络分区。
评价标准:客户端连接数,相同再看节点数目,如果都相同则用其他方式挑选(参数输入的顺序)
2.停掉其他分区的节点
3.等待全部停止
4.启动上述节点
涉及到的角色及选取方式:
leader — 集群中任意选取的节点,用来主导autoheal的公正角色。可能在获胜分区,也可能在失败分区被重启
winner — 获胜的分区中选出来的一个节点,负责重启节点
losers — 失败分区中的节点,待重启
ps:leader可能持续受到新的autoheal请求,但是全部会被忽略,直到winner通知leader当前的autoheal流程结束或者已经终止,或者是与winner断开了连接
可能的状态:
not_healing — 默认状态
{winner_waiting, OutstandingStops, Notify} — winner,等待所有失败节点停止,随后将通知他们重启
{leader_waiting, Winner, Notify} — leader,已经指定了winner和losers,等待winner通知autoheal是否结束了
restarting — 重启中
消息流:
- Any node (leader included) >> {request_start, node()} >> Leader
当Mnesia检测出集群出现分区,则从集群中找到第一个节点作为leader节点进行autoheal操作
- Leader >> {become_winner, Losers} >> Winner
Leader决策出winner和losers,并且通知winner
- Winner >> {winner_is, Winner} >> All losers
winner通知losers启动新进程用于rabbit的重启
- Winner >> autoheal_safe_to_start >> All losers
winner发现所有losers已经停止或者autoheal 流程终止,通知losers可以重启rabbit
- Leader >> report_autoheal_status >> Winner
在leader为loser时,leader因为重启,会主动发送该请求给winner,看是否autoheal结束了
- Winner >> {autoheal_finished, Winner} >> Leader
winner告知leader,autoheal已经结束
autoheal 引发的问题
重启的节点如果持续连不上winner,在尝试10 * 30s * 2后,将重启失败,导致一些持久化的队列出现异常
在间歇性网络故障发现过该问题,通过脚本检测日志进行修复