You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RabbitMQ Shovel从AMQP 1.0转0.9.1出现bad match utf8错误求助

解决RabbitMQ Shovel从ActiveMQ(AMQP 1.0)同步消息时的bad match错误

问题根源

从你的日志能明确定位到:这个badmatch错误出现在rabbit_amqp10_shovel.erl第180行,触发原因是RabbitMQ 3.7.2版本的AMQP 1.0 Shovel插件,仅预期接收二进制类型的消息体,但ActiveMQ默认会把JMS TextMessage以UTF-8编码的字符串类型通过AMQP 1.0发送(日志里的{'v1_0.amqp_value',{utf8,"<message>Foo</message>"}}就是直接证据),两者类型不匹配导致了这个错误。

可行的解决办法

1. 升级RabbitMQ到修复后的版本(推荐)

这个兼容性问题在RabbitMQ 3.7.10及后续版本中已经被官方修复,更新后的AMQP 1.0 Shovel模块新增了对字符串类型消息体的处理逻辑。

  • 建议升级到3.8.x或更高的稳定版本(注意对应Erlang版本要求:3.8.x需要Erlang 21.3+,3.9.x及以上需要Erlang 22.3+)
  • 升级完成后重新配置Shovel,发送测试消息即可解决该问题。

2. 修改ActiveMQ消息发送方式,强制使用二进制消息体

如果暂时无法升级RabbitMQ,可以在发送消息到ActiveMQ时,将文本消息转换为二进制格式发送。比如在JMS客户端中,用BytesMessage替代TextMessage:

import java.nio.charset.StandardCharsets;
import javax.jms.BytesMessage;
import javax.jms.MessageProducer;
import javax.jms.Session;

// 示例代码片段
BytesMessage msg = session.createBytesMessage();
// 将字符串转为UTF-8字节数组写入消息
msg.writeBytes("<message>Foo</message>".getBytes(StandardCharsets.UTF_8));
producer.send(msg);

这样ActiveMQ会以二进制格式发送消息体,完全符合RabbitMQ 3.7.2 Shovel的预期,避免类型不匹配错误。

3. 临时修改RabbitMQ Shovel插件代码(不推荐)

如果以上两种方案都无法实施,可以尝试修改rabbit_amqp10_shovel.erl的消息体处理逻辑,添加对UTF-8字符串的兼容:
找到第180行附近的消息体解析代码,将原有的匹配逻辑修改为:

% 替换原有的Body匹配代码
Body = case amqp10_msg:get_body(Msg) of
           {ok, {'v1_0.amqp_value', {utf8, Str}}} -> list_to_binary(Str);
           {ok, Bin} -> Bin
       end,

修改后重新编译插件并部署,但这种方式需要Erlang开发环境,且后续RabbitMQ升级会覆盖修改,仅作为应急临时方案。

验证步骤

无论采用哪种方案,完成后都需要:

  • 重启RabbitMQ和ActiveMQ服务
  • 重新创建Shovel(静态或动态均可)
  • 向ActiveMQ源队列发送测试消息,检查RabbitMQ日志是否不再出现badmatch错误,同时确认消息成功同步到RabbitMQ目标队列。

内容的提问来源于stack exchange,提问作者Houssem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:09:51