ThingsBoard MQTT 解码超过限制解决办法
正文与配图来自原稿。设备经 MQTT 上报时 payload 超过 Netty
MqttDecoder上限的排查与改法。
1、问题
设备使用 MQTT 连接 ThingsBoard 上报数据时,若数据包长度过长,超过 TB 实现的 MQTT 解码长度上限,就会报错,例如:
text
Message decoding failed: too large message: 273207 bytes日志示意(约 273207 字节 ≈ 267KB,已远超默认 64KB):

2、查看源码解码的位置
MQTT 接入在 Netty pipeline 里注册解码器时,会把「最大 payload」传给 MqttDecoder:
java
pipeline.addLast("decoder", new MqttDecoder(context.getMaxPayloadSize()));也就是说,实际上限来自 context.getMaxPayloadSize(),而不是写死在 Decoder 里。

(类名一般为 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) |

把 NETTY_MAX_PAYLOAD_SIZE(或直接改 yml 默认值)调到大于你设备实际上报的最大包长,然后重启 ThingsBoard / MQTT Transport 进程使配置生效。
例如日志里是 273207 字节,至少应设为大于该值(可预留余量,如 524288 = 512KB)。
补充(辅)
- Docker / K8s:在 compose 或 Deployment 的环境变量里加
NETTY_MAX_PAYLOAD_SIZE=...即可,不必改镜像内 yml。 - 微服务拆分时,改的是 MQTT Transport 进程的配置,不是只改 Core。
- 调大上限会增加单连接内存占用;更稳妥的做法往往是设备侧拆包、压缩或减少一次上报字段。
- 改完后若仍失败,再确认是否还有反向代理 / 负载均衡的 body 大小限制。
