接入 APM 后压测 20 分钟,应用日志开始刷 reporter queue is full dropped 12800 spans,接口成功率从 99.9% 掉到 97%。线程池 activeCount 一直是 128,队列堆到 10000。乍看像缓存或者权限的锅,追下去往往不是。
grep -c 'reporter queue is full' app.log jstack 1 | grep -A 20 'apm-reporter' curl -s localhost:6060/debug/vars | grep -i dropped
追下去是这么回事:上报用的是固定 128 线程加有界队列,采集端限流后单批写超时,队列很快堆满。拒绝策略是丢弃新任务,日志只打一行 dropped,业务面无感知。压测流量把每秒 span 数从 3000 推到 4 万,写端吞吐没跟着上去。
「埋点上报队列打满」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。
具体做法是,先把 reporter 的队列长度和线程数打点到日志 确认饱和的是哪一端;调大 batchSize 减少请求数 同时把发送超时从 5 秒降到 1 秒 避免线程全卡住;队列满时改成降级采样 按 10% 丢低优先级 span 并打出计数;和采集端确认限流阈值 把写入配额一起抬上去。
验收就看一点,压测半小时 dropped 计数不再增长,接口成功率回到 99.9% 以上。
