接入 Java 探针后,同一份压测脚本 P99 从 180 毫秒涨到 220 毫秒,CPU 使用率多了 6 个百分点。关掉探针的线程栈采样,P99 回到 185 毫秒。乍看像缓存或者权限的锅,追下去往往不是。
java -javaagent:apm-agent.jar -Dapm.sampling.interval=10s \ -Dapm.method_trace=false -jar app.jar jcmd 1 VM.native_memory summary
追下去是这么回事:探针默认每 1 秒对全部线程做一次栈采样,线程数 400 时每次都要在安全点停顿。采样和业务线程抢 safepoint,长尾请求正好撞上就多几十毫秒。方法级埋点还会在热点方法上额外插桩,调用量大时开销被放大。
「探针采样频率」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。
具体做法是,先把采样周期从 1s 调到 10s 观察 P99 变化;关掉方法级追踪 只保留入口和出口的 span;把线程栈采样改成按需触发 排查时再开;同一份脚本在开和关两种状态下各跑一轮 记录差值。
验收就看一点,开关探针的 P99 差距缩小到 10 毫秒以内,CPU 增幅不超过 2 个百分点。
