对账批次把整天的订单塞进一条消息,6MB 的 JSON 序列化一次要 700 毫秒,消费线程的 lag 从几百飙到十万。GC 日志里 ParNew 也跟着变长。日志里能对上时间点,这种反而好排。

JSON 序列化要遍历整个对象图并拼字符串,耗时和字段数、嵌套深度成正比,还会产生大量临时对象。消息体越大,发送前的这段 CPU 时间越难被忽略。这一点先确认清楚,后面就不用反复试。

try (OutputStream os = new BufferedOutputStream(out)) {
    mapper.writeValue(os, batch);
}

这次卡住的地方就在「大对象序列化耗时」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

处理上按这个顺序:先把大消息拆成按订单分片的小消息 单条控制在几百 KB;序列化改用流式写出 避免先拼成一个大字符串;确认没有在日志里重复打印整个消息体;压测时单独看序列化阶段的耗时 不要只看端到端。

结果对不对很好判断,单条消息降到 300KB 以下 序列化耗时回到几十毫秒 lag 不再持续上涨。

作者 9823189