同一个 /collect 接口,老客户端发 JSON,新客户端改成 msgpack,服务端日志里出现 Unexpected token in JSON at position 0,请求返回 500。抓包看 Content-Type 还是 application/json。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

curl -X POST http://api/collect \
  -H 'Content-Type: application/msgpack' \
  --data-binary @payload.msgpack

序列化格式不会自己声明,靠 Content-Type 或固定的编解码器决定。客户端换了打包方式但没改请求头,服务端仍按 JSON 读,从第一个字节起就崩了。这一点先确认清楚,后面就不用反复试。

「MessagePack 与 JSON 混用」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。

改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。

具体做法是,先让客户端把 Content-Type 改成 application/msgpack 并在服务端加对应的解码器;服务端按 Content-Type 分流 不要只保留一个全局 JSON 解析;兼容期两种都接 老客户端逐步下线;用 curl 分别发两种格式 确认返回一致。

改完照着核一遍,msgpack 请求返回 200 JSON 请求也正常 服务端日志里不再出现 Unexpected token。

作者 9823189