Skip to content

ThingsBoard MQTT 解码超过限制解决办法 ​

正文与配图来自原稿。设备经 MQTT 上报时 payload 超过 Netty MqttDecoder 上限的排查与改法。

1、问题 ​

设备使用 MQTT 连接 ThingsBoard 上报数据时,若数据包长度过长,超过 TB 实现的 MQTT 解码长度上限,就会报错,例如:

text
Message decoding failed: too large message: 273207 bytes

日志示意(约 273207 字节 ≈ 267KB,已远超默认 64KB):

too large message 日志

2、查看源码解码的位置 ​

MQTT 接入在 Netty pipeline 里注册解码器时,会把「最大 payload」传给 MqttDecoder:

java
pipeline.addLast("decoder", new MqttDecoder(context.getMaxPayloadSize()));

也就是说,实际上限来自 context.getMaxPayloadSize(),而不是写死在 Decoder 里。

MqttTransportServerInitializer 中的 MqttDecoder

(类名一般为 MqttTransportServerInitializer,在 initChannel 里组装 pipeline。)

3、解决办法 ​

修改默认配置大小。在 thingsboard.yml(或对应 transport 配置)的 MQTT netty 段:

yaml
netty:
  leak_detector_level: "${NETTY_LEAK_DETECTOR_LVL:DISABLED}"
  boss_group_thread_count: "${NETTY_BOSS_GROUP_THREADS:1}"
  worker_group_thread_count: "${NETTY_WORKER_GROUP_THREADS:12}"
  max_payload_size: "${NETTY_MAX_PAYLOAD_SIZE:65536}"
  so_keep_alive: "${NETTY_SO_KEEPALIVE:false}"

关键配置项:

项含义
配置路径transport.mqtt.netty.max_payload_size(以你版本 yml 层级为准)
环境变量NETTY_MAX_PAYLOAD_SIZE
默认值65536(64KB)

max_payload_size 配置

把 NETTY_MAX_PAYLOAD_SIZE(或直接改 yml 默认值)调到大于你设备实际上报的最大包长,然后重启 ThingsBoard / MQTT Transport 进程使配置生效。

例如日志里是 273207 字节,至少应设为大于该值(可预留余量,如 524288 = 512KB)。


补充(辅) ​

  • Docker / K8s:在 compose 或 Deployment 的环境变量里加 NETTY_MAX_PAYLOAD_SIZE=... 即可,不必改镜像内 yml。
  • 微服务拆分时,改的是 MQTT Transport 进程的配置,不是只改 Core。
  • 调大上限会增加单连接内存占用;更稳妥的做法往往是设备侧拆包、压缩或减少一次上报字段。
  • 改完后若仍失败,再确认是否还有反向代理 / 负载均衡的 body 大小限制。

相关文章 ​