RabbitMQ Shovel插件K8s集群Pod重启生成重复实例导致数据重复问题求解
故障修复方案
默认情况下RabbitMQ动态Shovel会在集群所有节点上各启动一个运行实例,你首次创建时仅单节点运行属于临时状态,节点重启后全节点加载Shovel配置就会触发多实例同时运行,进而导致消息重复复制。
永久修复方案(推荐)
从RabbitMQ 3.9版本开始,官方原生支持Shovel单活跃模式,开启后同一个Shovel在整个集群内仅会有一个活跃实例,其余节点上的实例处于待命状态,活跃实例故障后自动切换,完全避免多实例同时运行的问题。
- 针对通过UI/API创建的动态Shovel:创建时在
Arguments配置项添加键值对x-shovel-single-active: true即可;已创建的Shovel删除原有配置后重新添加该参数即可生效。 - 针对通过配置文件定义的静态Shovel:在Shovel的declaration配置段添加如下参数:
{declaration, [{arguments, [{'x-shovel-single-active', true}]}]}
前提校验项
执行上述配置前需先确认RabbitMQ集群状态正常:
- 执行
rabbitmqctl cluster_status命令,确认所有Pod属于同一集群,无节点失联或脑裂问题 - 检查Helm Chart配置是否开启了正确的集群节点发现机制(推荐使用K8s DNS发现)
- 集群分区恢复策略需设置为
pause_minority或autoheal,避免网络波动导致的集群状态异常 - 确认Mnesia数据库使用了稳定的持久化存储卷,Pod重启后不会丢失集群状态数据
临时自动化修复方案
如果暂时无法升级RabbitMQ到3.9+版本,可以给RabbitMQ Pod配置PostStart生命周期钩子,Pod启动完成后自动调用管理API重启所有Shovel,实现手动重启操作的自动化效果,参考命令如下:
curl -u ${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS} -X POST http://localhost:15672/api/shovels/%2f/restart-all
内容的提问来源于stack exchange,提问作者Nilay Tiwari
相关产品推荐
相关产品推荐

