うちは オビト956 2025-11-20 16:28 采纳率: 50%
浏览 6
已结题

RocketMQ 对于长度很小的消息抛出TooLongFrameException

问题:使用 RocketMQ 发送消息,消息长度为 11,但是 nameService 却报错:TooLongFrameException: Adjusted frame length exceeds 16777216: 1347569956 - discarded

代码:

 Producer producer = null;

        Producer producer = null;

        try {
            ClientConfiguration clientConfiguration = new ClientConfigurationBuilder()
                    .setEndpoints("192.168.116.156:9876")
                    .enableSsl(false)
                    .build();
            producer = new ProducerBuilderImpl().setClientConfiguration(clientConfiguration).build();
        } catch (ClientException e) {
            throw new RuntimeException(e);
        }
        //普通消息发送。
        MessageBuilder messageBuilder = new MessageBuilderImpl();
        Message message = messageBuilder.setTopic("NormalTopic")
                //设置消息索引键,可根据关键字精确查找某条消息。
                .setKeys("111111")
                //设置消息Tag,用于消费端根据指定Tag过滤消息。
                .setTag("tag01")
                //消息体。
                .setBody("messageBody".getBytes())
                .build();
        try {
            //发送消息,需要关注发送结果,并捕获失败等异常。
            SendReceipt sendReceipt = producer.send(message);
            System.out.println(sendReceipt.getMessageId());
        } catch (ClientException e) {
            e.printStackTrace()

报错:

img

抓包也没发现大数据是怎么发送出去的,只发送了 54 个字节的数据:

img

1.

  • 写回答

3条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-11-20 19:22
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案能帮助您,请采纳,非常感谢!
    .
    每日一句正能量,让它带给您好心情:生活中的困难,就像一场雨,总会停的,雨后的天空会更蓝。
    .

    根据错误信息和代码分析,这是一个典型的 RocketMQ 客户端与服务器端协议不匹配导致的 TooLongFrameException 问题。

    问题分析

    从错误信息可以看到:

    • 实际消息长度只有 11 字节("messageBody")
    • 但服务器解析出的帧长度是 1347569956(明显异常)
    • Netty 的 LengthFieldBasedFrameDecoder 抛出异常

    根本原因

    这个问题通常是由于 协议版本不匹配 导致的:

    1. 客户端使用的可能是新版 RocketMQ 5.x 客户端
    2. 服务器端可能是旧版 RocketMQ 4.x
    3. 新旧版本的消息协议格式不一致

    解决方案

    方案1:检查并统一 RocketMQ 版本

    确保客户端和服务器端使用相同的主要版本:

    # 检查服务器端版本
    ./mqadmin clusterList -n 192.168.116.156:9876
    

    方案2:客户端配置调整

    尝试在客户端配置中指定协议版本:

    ClientConfiguration clientConfiguration = new ClientConfigurationBuilder()
        .setEndpoints("192.168.116.156:9876")
        .enableSsl(false)
        // 添加重试和超时配置
        .setRetryTimes(3)
        .setRequestTimeout(3000)
        .build();
    

    方案3:检查服务器端配置

    检查 RocketMQ Broker 的配置文件中是否有协议相关的限制:

    # 在 broker.conf 中检查
    maxMessageSize=4194304
    serverAsyncSemaphoreValue=64
    serverOnewaySemaphoreValue=32
    serverChannelMaxIdleTimeSeconds=120
    

    方案4:网络抓包分析

    使用更详细的抓包命令分析协议交互:

    # 更详细的 TCP 抓包
    tcpdump -i any -A -s 0 host 192.168.116.156 and port 9876
    

    临时解决方案

    如果急需解决,可以尝试:

    // 在发送前添加延迟,确保连接完全建立
    Thread.sleep(1000);
    SendReceipt sendReceipt = producer.send(message);
    

    建议排查步骤

    1. 确认版本兼容性:检查客户端和服务器的 RocketMQ 版本
    2. 检查网络环境:确认没有防火墙或代理修改数据包
    3. 查看完整日志:检查 RocketMQ 服务器端的完整错误日志
    4. 测试简单消息:尝试发送更简单的测试消息

    这个问题通常通过统一客户端和服务器端版本即可解决。如果问题持续存在,建议提供完整的客户端和服务器的版本信息以便进一步分析。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 12月9日
  • 已采纳回答 12月1日
  • 创建了问题 11月20日