<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>工具链 on Dorkytiger 的小屋</title>
    <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/</link>
    <description>Recent content in 工具链 on Dorkytiger 的小屋</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <atom:link href="https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>负载生成器：先选模型，再选工具</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/01-load-generators/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/01-load-generators/</guid>
      <description>&lt;h1 id=&#34;41-负载生成器先选模型再选工具&#34;&gt;4.1 负载生成器：先选模型，再选工具&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：无　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/02-two-paths/&#34;&gt;4.2 两类现象，两条路径&lt;/a&gt;
配套代码：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/code/04-toolchain/01-load-generators/&#34;&gt;04-toolchain/01-load-generators&lt;/a&gt;
前置：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/00-introduction/06-coordinated-omission/&#34;&gt;0.6 协调遗漏&lt;/a&gt;（本节是它的工程落地）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一句话结论&#34;&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;选「开环还是闭环」比选「用哪个工具」重要得多。&lt;/strong&gt; 同一份代码、同一个服务，两种模型测出的 P99 可能差几百倍——而工具之间的差别通常只有几成。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一用跑步机理解开环与闭环&#34;&gt;一、用「跑步机」理解开环与闭环&lt;/h2&gt;
&lt;p&gt;健身房里有两台跑步机：&lt;/p&gt;
&lt;h3 id=&#34;跑步机-a闭环跟着你跑&#34;&gt;跑步机 A（闭环）：跟着你跑&lt;/h3&gt;
&lt;p&gt;你跑得快，它就快；你跑不动了，它就慢下来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：你永远不会「跑崩」，因为机器会迁就你。跑了 30 分钟，你觉得自己状态不错。&lt;/p&gt;
&lt;h3 id=&#34;跑步机-b开环按设定速度跑&#34;&gt;跑步机 B（开环）：按设定速度跑&lt;/h3&gt;
&lt;p&gt;设定 12 km/h，不管你跟不跟得上。你跟不上就掉下来（或者被拖着走）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：你会真实地暴露极限——什么时候开始吃力、什么时候彻底跟不上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对应到压测&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;闭环（VU 模型）&lt;/th&gt;
					&lt;th&gt;开环（到达率模型）&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;机制&lt;/td&gt;
					&lt;td&gt;收到响应才发下一个请求&lt;/td&gt;
					&lt;td&gt;按固定节奏发，不管响应&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;服务变慢时&lt;/td&gt;
					&lt;td&gt;自动减少发压&lt;/td&gt;
					&lt;td&gt;继续按计划发压（请求开始排队）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;结果&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;P99 被系统性低估&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;暴露真实尾延迟&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;类比&lt;/td&gt;
					&lt;td&gt;「你跑不动机器就减速」&lt;/td&gt;
					&lt;td&gt;「机器不等你」&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;复习第 0 章 0.6 节&lt;/strong&gt;：当服务端卡顿 1 秒时，闭环工具在这 1 秒内几乎不发请求，所以这次卡顿只被记录成 1 个慢样本，而不是几百个。&lt;strong&gt;服务越糟，报告越好看。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;结论：默认用开环。&lt;/strong&gt; 只有在明确要测「固定并发下的体验」时才用闭环。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二工具对照表&#34;&gt;二、工具对照表&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;模型支持&lt;/th&gt;
					&lt;th&gt;脚本语言&lt;/th&gt;
					&lt;th&gt;适合场景&lt;/th&gt;
					&lt;th&gt;注意&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;k6&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;开环 + 闭环&lt;/strong&gt;（多种 executor）&lt;/td&gt;
					&lt;td&gt;JavaScript&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;首选&lt;/strong&gt;：脚本化、CI 友好、阈值断言、多场景&lt;/td&gt;
					&lt;td&gt;需要 &lt;code&gt;preAllocatedVUs&lt;/code&gt; 配够&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Gatling&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;开环（injection profile）&lt;/td&gt;
					&lt;td&gt;Scala DSL&lt;/td&gt;
					&lt;td&gt;报告漂亮、表达力强&lt;/td&gt;
					&lt;td&gt;JVM 自身需要预热与调优&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;wrk2&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;开环（恒定速率 + HdrHistogram）&lt;/td&gt;
					&lt;td&gt;Lua（弱）&lt;/td&gt;
					&lt;td&gt;验证尾延迟、轻量高并发&lt;/td&gt;
					&lt;td&gt;脚本能力弱，适合单一接口&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JMeter&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;闭环为主&lt;/td&gt;
					&lt;td&gt;GUI/XML&lt;/td&gt;
					&lt;td&gt;协议覆盖广、插件生态&lt;/td&gt;
					&lt;td&gt;资源占用高，GUI 模式不适合正式压测&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Vegeta&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;开环&lt;/td&gt;
					&lt;td&gt;CLI&lt;/td&gt;
					&lt;td&gt;简单场景、快速验证&lt;/td&gt;
					&lt;td&gt;报告与生态弱&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Locust&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;开环/闭环&lt;/td&gt;
					&lt;td&gt;Python&lt;/td&gt;
					&lt;td&gt;分布式压测&lt;/td&gt;
					&lt;td&gt;单机性能一般&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;选择建议&lt;/strong&gt;：&lt;/p&gt;</description>
    </item>
    <item>
      <title>两类现象，两条路径</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/02-two-paths/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/02-two-paths/</guid>
      <description>&lt;h1 id=&#34;42-两类现象两条路径&#34;&gt;4.2 两类现象，两条路径&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/01-load-generators/&#34;&gt;4.1 负载生成器&lt;/a&gt;　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/03-async-profiler/&#34;&gt;4.3 async-profiler&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一句话结论&#34;&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;剖析工具选错的代价，是得到「没有瓶颈」这个错误结论。&lt;/strong&gt; 记住一条分叉：&lt;strong&gt;CPU 高 → 用 on-CPU 采样；CPU 不高但慢 → 用 wall-clock 采样。&lt;/strong&gt; 这两条路径的差别，比工具之间的差别重要得多。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一用厨房理解两种慢&#34;&gt;一、用厨房理解两种「慢」&lt;/h2&gt;
&lt;p&gt;一家餐厅出菜慢，有两种完全不同的原因：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;现象&lt;/th&gt;
					&lt;th&gt;厨房状态&lt;/th&gt;
					&lt;th&gt;类比后端&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;灶台全开着，厨师忙不过来&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;CPU 时间被占满&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;CPU 高&lt;/strong&gt;：真在算&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;厨师都闲着，在等食材送到&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;CPU 空闲，时间花在等待&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;CPU 不高&lt;/strong&gt;：在等 IO / 锁 / 下游&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键洞察&lt;/strong&gt;：这两种情况的&lt;strong&gt;排查手段完全不同&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一种：看「谁在占用灶台」→ &lt;strong&gt;on-CPU 采样&lt;/strong&gt;，找最宽的函数。&lt;/li&gt;
&lt;li&gt;第二种：看「厨师在等什么」→ &lt;strong&gt;wall-clock 采样&lt;/strong&gt;，找阻塞点。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;如果对第二种情况用第一种工具&lt;/strong&gt;：你会看到一张&lt;strong&gt;几乎空白&lt;/strong&gt;的火焰图（因为 CPU 没在干活），然后得出「没有瓶颈」的错误结论。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;这是新手最常见的分析错误，也是最浪费时间的一种&lt;/strong&gt;——因为你会反复采集、反复看空图，怀疑是工具坏了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二分叉决策表&#34;&gt;二、分叉决策表&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;现象&lt;/th&gt;
					&lt;th&gt;首选工具&lt;/th&gt;
					&lt;th&gt;事件类型&lt;/th&gt;
					&lt;th&gt;你会看到&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;CPU 接近饱和（&amp;gt; 70%）&lt;/td&gt;
					&lt;td&gt;async-profiler / JFR&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;cpu&lt;/code&gt; / &lt;code&gt;jdk.ExecutionSample&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;火焰图顶部有明确的宽块&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CPU 低（&amp;lt; 40%）但延迟高&lt;/td&gt;
					&lt;td&gt;async-profiler&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;wall&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;线程大面积停在等待栈上&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CPU 的 &lt;code&gt;sys&lt;/code&gt; 占比高&lt;/td&gt;
					&lt;td&gt;系统工具 + 火焰图&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;cpu&lt;/code&gt;（看内核栈）&lt;/td&gt;
					&lt;td&gt;系统调用、锁、页错误&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GC 停顿与延迟尖刺对齐&lt;/td&gt;
					&lt;td&gt;GC 日志 / JFR&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;jdk.GCPhasePause&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;周期性停顿&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;分配速率高&lt;/td&gt;
					&lt;td&gt;async-profiler&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;alloc&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;谁在制造垃圾&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;吞吐上不去但 CPU 不高&lt;/td&gt;
					&lt;td&gt;async-profiler&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;lock&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;锁争用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;所有指标都正常但用户说慢&lt;/td&gt;
					&lt;td&gt;看&lt;strong&gt;测量点&lt;/strong&gt;（第 1 章 1.3）&lt;/td&gt;
					&lt;td&gt;客户端/网关/tracing&lt;/td&gt;
					&lt;td&gt;问题可能在网络或上游&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三四种事件的完整分工&#34;&gt;三、四种事件的完整分工&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;事件&lt;/th&gt;
					&lt;th&gt;采样依据&lt;/th&gt;
					&lt;th&gt;回答&lt;/th&gt;
					&lt;th&gt;典型发现&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;cpu&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;CPU 时间&lt;/td&gt;
					&lt;td&gt;谁在消耗 CPU？&lt;/td&gt;
					&lt;td&gt;热点函数、算法问题、序列化开销&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;wall&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;墙上时间&lt;/td&gt;
					&lt;td&gt;时间都花在哪（含等待）？&lt;/td&gt;
					&lt;td&gt;阻塞 IO、锁等待、下游慢&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;alloc&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;分配的对象&lt;/td&gt;
					&lt;td&gt;谁在制造 GC 压力？&lt;/td&gt;
					&lt;td&gt;装箱、字符串拼接、正则编译&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;lock&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;锁等待时间&lt;/td&gt;
					&lt;td&gt;谁在抢锁？&lt;/td&gt;
					&lt;td&gt;锁竞争、临界区过大&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;记忆方法&lt;/strong&gt;：&lt;/p&gt;</description>
    </item>
    <item>
      <title>async-profiler：四类火焰图</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/03-async-profiler/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/03-async-profiler/</guid>
      <description>&lt;h1 id=&#34;43-async-profiler四类火焰图&#34;&gt;4.3 async-profiler：四类火焰图&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/02-two-paths/&#34;&gt;4.2 两类现象，两条路径&lt;/a&gt;　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/04-jfr-and-jcmd/&#34;&gt;4.4 JFR 与 jcmd&lt;/a&gt;
配套代码：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/code/04-toolchain/03-async-profiler/&#34;&gt;04-toolchain/03-async-profiler&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一句话结论&#34;&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;async-profiler 是目前 JVM 上最好用的采样剖析器&lt;/strong&gt;，它最大的价值是&lt;strong&gt;四种事件类型&lt;/strong&gt;（cpu / alloc / lock / wall）——分别回答「谁在忙、谁在造垃圾、谁在抢锁、谁在干等」。&lt;strong&gt;只采 CPU 火焰图，等于只用了一个功能的四分之一。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一用x-光造影理解四种事件&#34;&gt;一、用「X 光造影」理解四种事件&lt;/h2&gt;
&lt;p&gt;给病人做检查，不同的造影剂能看到不同的东西：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;造影剂&lt;/th&gt;
					&lt;th&gt;看到什么&lt;/th&gt;
					&lt;th&gt;对应事件&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;看骨骼结构&lt;/td&gt;
					&lt;td&gt;硬组织的形态&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;cpu&lt;/code&gt;&lt;/strong&gt;：谁在消耗 CPU&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;看血流&lt;/td&gt;
					&lt;td&gt;哪里堵住了&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;wall&lt;/code&gt;&lt;/strong&gt;：谁在等待&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;看代谢活跃区&lt;/td&gt;
					&lt;td&gt;哪里在异常增生&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;alloc&lt;/code&gt;&lt;/strong&gt;：谁在制造垃圾&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;看血管交叉点&lt;/td&gt;
					&lt;td&gt;哪里互相压迫&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;lock&lt;/code&gt;&lt;/strong&gt;：谁在抢锁&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键&lt;/strong&gt;：&lt;strong&gt;不同的病要用不同的造影剂&lt;/strong&gt;。用看骨骼的 X 光去查血管堵塞，只会得到「没问题」。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二四类事件的命令与用途&#34;&gt;二、四类事件的命令与用途&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;jcmd | grep app.jar | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ① CPU：谁在消耗 CPU（现象：CPU 高）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;asprof -d &lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; -e cpu -f cpu.html &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ② 墙上时间：时间都花在哪（现象：CPU 不高但慢）⭐ 最容易被忽略&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;asprof -d &lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; -e wall -f wall.html &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ③ 分配：谁在制造垃圾（现象：GC 频繁、分配速率高）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;asprof -d &lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; -e alloc -f alloc.html &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ④ 锁：谁在抢锁（现象：吞吐上不去、sys CPU 高）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;asprof -d &lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; -e lock -f lock.html &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;asprof&lt;/code&gt; 是 async-profiler 3.x 的启动器名&lt;/strong&gt;（旧版本叫 &lt;code&gt;profiler.sh&lt;/code&gt;，2.x 也支持 &lt;code&gt;asprof&lt;/code&gt; 别名）。如果你的版本较老，把 &lt;code&gt;asprof&lt;/code&gt; 换成 &lt;code&gt;./profiler.sh&lt;/code&gt;。&lt;/p&gt;</description>
    </item>
    <item>
      <title>JFR 与 jcmd：能常开的剖析与无依赖应急</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/04-jfr-and-jcmd/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/04-jfr-and-jcmd/</guid>
      <description>&lt;h1 id=&#34;44-jfr-与-jcmd能常开的剖析与无依赖应急&#34;&gt;4.4 JFR 与 jcmd：能常开的剖析与无依赖应急&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/03-async-profiler/&#34;&gt;4.3 async-profiler&lt;/a&gt;　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/05-system-observability/&#34;&gt;4.5 系统级观测&lt;/a&gt;
配套代码：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/code/04-toolchain/04-jfr-and-jcmd/&#34;&gt;04-toolchain/04-jfr-and-jcmd&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一句话结论&#34;&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;JFR（JDK Flight Recorder）是唯一适合在生产环境长期开着的剖析工具&lt;/strong&gt;（开销约 1%），它记录的是「系统发生了什么」的完整事件流。&lt;strong&gt;jcmd 则是零依赖的应急手段&lt;/strong&gt;——什么都不用装，出问题时随手可用。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一用24-小时动态心电图理解-jfr&#34;&gt;一、用「24 小时动态心电图」理解 JFR&lt;/h2&gt;
&lt;p&gt;普通心电图只在医院做几分钟。但有些心脏问题只在特定时刻发作——所以医生给病人戴一个&lt;strong&gt;24 小时动态心电图记录仪&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;动态心电图&lt;/th&gt;
					&lt;th&gt;JFR&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;长期佩戴，开销极小&lt;/td&gt;
					&lt;td&gt;生产环境常开，约 1% 开销&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;持续记录，出事时回放&lt;/td&gt;
					&lt;td&gt;滚动录制，事后 dump&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;记录多种信号（心率、心律、ST 段）&lt;/td&gt;
					&lt;td&gt;记录几十类事件（GC、锁、IO、异常…）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;不能当场看结果，要事后分析&lt;/td&gt;
					&lt;td&gt;用 JDK Mission Control 分析&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键价值&lt;/strong&gt;：性能问题往往&lt;strong&gt;偶发且不可复现&lt;/strong&gt;。JFR 让你能在问题发生后&lt;strong&gt;回到现场&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二jfr-的三种用法&#34;&gt;二、JFR 的三种用法&lt;/h2&gt;
&lt;h3 id=&#34;用法一出问题时临时录一段&#34;&gt;用法一：出问题时临时录一段&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;jcmd | grep app.jar | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 录制 120 秒，输出到文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jcmd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; JFR.start name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;perf settings&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;profile duration&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;120s filename&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/tmp/perf.jfr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 结束后自动停止；也可以手动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jcmd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; JFR.stop name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;perf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;用法二滚动录制推荐用于生产&#34;&gt;用法二：滚动录制（推荐用于生产）⭐&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 保持最多 256MB / 1 小时的事件，超出后自动丢弃最旧的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jcmd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; JFR.start name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;rolling settings&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;profile maxsize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m maxage&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1h
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 出问题时立刻 dump（不用等录制结束）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jcmd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; JFR.dump name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;rolling filename&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/tmp/incident-&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;date +%s&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;.jfr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 不再需要时停止&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jcmd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$PID&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; JFR.stop name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;rolling
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;这是最实用的模式&lt;/strong&gt;：平时默默记录，出事时 dump 出「过去 1 小时」的事件。&lt;/p&gt;</description>
    </item>
    <item>
      <title>系统级观测：sys、steal 与上下文切换</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/05-system-observability/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/05-system-observability/</guid>
      <description>&lt;h1 id=&#34;45-系统级观测syssteal-与上下文切换&#34;&gt;4.5 系统级观测：sys、steal 与上下文切换&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/04-jfr-and-jcmd/&#34;&gt;4.4 JFR 与 jcmd&lt;/a&gt;　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/06-app-observability/&#34;&gt;4.6 应用可观测性&lt;/a&gt;
配套代码：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/code/04-toolchain/05-system-observability/&#34;&gt;04-toolchain/05-system-observability&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一句话结论&#34;&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;JVM 指标告诉你「应用怎么了」，系统指标告诉你「环境怎么了」。&lt;/strong&gt; 三个最容易被忽略、信息量最大的系统指标是：&lt;strong&gt;&lt;code&gt;sys&lt;/code&gt; CPU（内核在忙什么）、&lt;code&gt;steal&lt;/code&gt;（被虚拟机邻居抢走多少）、上下文切换次数（锁竞争与线程过多的信号）。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一用体检的血检理解系统观测&#34;&gt;一、用「体检的血检」理解系统观测&lt;/h2&gt;
&lt;p&gt;去医院看病，医生不会只看你说「哪不舒服」（应用指标），还会让你做血检、尿检（系统指标）——因为&lt;strong&gt;身体大环境的问题会表现为各种局部症状&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;血检项&lt;/th&gt;
					&lt;th&gt;对应系统指标&lt;/th&gt;
					&lt;th&gt;提示&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;白细胞&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sys&lt;/code&gt; CPU&lt;/td&gt;
					&lt;td&gt;有&amp;quot;炎症&amp;quot;（系统调用/锁/页错误）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;血糖&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;steal&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;被外部因素影响（虚拟机邻居）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;心率&lt;/td&gt;
					&lt;td&gt;上下文切换&lt;/td&gt;
					&lt;td&gt;系统在频繁&amp;quot;换人&amp;quot;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;肾功能&lt;/td&gt;
					&lt;td&gt;磁盘 &lt;code&gt;await&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;排毒能力（IO 能力）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键&lt;/strong&gt;：应用层的所有指标都建立在系统资源之上。&lt;strong&gt;系统层的瓶颈会伪装成应用层的问题。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二cpu-的五个组成部分不要只看总数&#34;&gt;二、CPU 的五个组成部分（不要只看总数）&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 最常用的三个命令&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;top -b -n &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; | head -5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pidstat -u -p &amp;lt;pid&amp;gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mpstat -P ALL &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;top&lt;/code&gt; 那一行 &lt;code&gt;%Cpu(s)&lt;/code&gt; 的解读&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;%Cpu(s): 12.3 us, 34.5 sy,  0.0 ni, 51.2 id,  1.2 wa,  0.0 hi,  0.8 si,  0.0 st
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │        │          │        │        │        │        │        └─ steal（被邻居抢走）
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │        │          │        │        │        │        └─ 软中断
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │        │          │        │        │        └─ 硬中断
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │        │          │        │        └─ IO 等待
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │        │          │        └─ 空闲
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │        │          └─ nice（低优先级）
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          │        └─ sys（内核态）
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          └─ user（用户态）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;指标&lt;/th&gt;
					&lt;th&gt;高意味着&lt;/th&gt;
					&lt;th&gt;常见原因&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;us&lt;/code&gt;（user）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;应用代码在算&lt;/td&gt;
					&lt;td&gt;正常；如果过高说明 CPU 是瓶颈&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;sy&lt;/code&gt;（sys）&lt;/strong&gt; ⭐&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内核在忙&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;频繁系统调用、&lt;strong&gt;锁竞争&lt;/strong&gt;、页错误、网络栈处理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;wa&lt;/code&gt;（iowait）&lt;/td&gt;
					&lt;td&gt;等磁盘&lt;/td&gt;
					&lt;td&gt;磁盘慢或 IO 密集&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;si&lt;/code&gt;/&lt;code&gt;hi&lt;/code&gt;（中断）&lt;/td&gt;
					&lt;td&gt;网络/设备中断&lt;/td&gt;
					&lt;td&gt;高流量网络、中断没做多队列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;&lt;code&gt;st&lt;/code&gt;（steal）&lt;/strong&gt; ⭐&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;被虚拟机邻居抢走 CPU&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;云主机超卖；&lt;strong&gt;你的优化再多也没用&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;两个最容易被忽略的指标&#34;&gt;两个最容易被忽略的指标&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sy&lt;/code&gt; 高（比如 35%）&lt;/strong&gt; 是一个强烈信号：&lt;/p&gt;</description>
    </item>
    <item>
      <title>应用可观测性：指标、追踪、日志</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/06-app-observability/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/06-app-observability/</guid>
      <description>&lt;h1 id=&#34;46-应用可观测性指标追踪日志&#34;&gt;4.6 应用可观测性：指标、追踪、日志&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/05-system-observability/&#34;&gt;4.5 系统级观测&lt;/a&gt;　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/07-data-and-middleware/&#34;&gt;4.7 数据与中间件观测&lt;/a&gt;
配套代码：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/code/04-toolchain/06-app-observability/&#34;&gt;04-toolchain/06-app-observability&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一句话结论&#34;&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;应用可观测性由三根柱子支撑：指标（发现问题）、追踪（定位环节）、日志（看清细节）。&lt;/strong&gt; 三者各有致命陷阱：指标的分位数算法、追踪的采样策略、日志的同步刷盘——任何一个搞错，都会让你在关键时刻拿不到数据。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一用生命体征监护仪理解三根柱子&#34;&gt;一、用「生命体征监护仪」理解三根柱子&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;监护手段&lt;/th&gt;
					&lt;th&gt;对应&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;监护仪（心率、血压、血氧）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;指标&lt;/td&gt;
					&lt;td&gt;连续、便宜、能告警；但只有数字，不知道原因&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;CT/造影（看具体位置）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;追踪&lt;/td&gt;
					&lt;td&gt;能定位到具体环节；但有采样成本&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;病历（详细记录）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;日志&lt;/td&gt;
					&lt;td&gt;信息最全；但成本高，不能全记&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键&lt;/strong&gt;：三者&lt;strong&gt;互相验证&lt;/strong&gt;。监护仪报警（指标异常）→ 做 CT（追踪定位）→ 查病历（日志细节）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二指标三个必须避开的陷阱&#34;&gt;二、指标：三个必须避开的陷阱&lt;/h2&gt;
&lt;h3 id=&#34;陷阱一用平均值或客户端算好的分位数&#34;&gt;陷阱一：用平均值或客户端算好的分位数&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;已在第 1 章 1.2 节讲过&lt;/strong&gt;：百分位不可平均，必须用&lt;strong&gt;直方图&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-promql&#34; data-lang=&#34;promql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;--&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;✅&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;正确：先按&lt;/span&gt; le &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;聚合，再算分位数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;histogram_quantile&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0.99&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;le&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;rate&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;http_server_requests_seconds_bucket[&lt;span style=&#34;color:#e6db74&#34;&gt;5m&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;--&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;❌&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;错误：对实例的&lt;/span&gt; P99 &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;求平均&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;avg&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;http_server_requests_seconds{quantile&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;#34;&lt;span style=&#34;color:#e6db74&#34;&gt;0.99&lt;/span&gt;&amp;#34;}&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;实践检查&lt;/strong&gt;：如果你的 Prometheus 里出现了 &lt;code&gt;quantile=&amp;quot;0.99&amp;quot;&lt;/code&gt; 这样的标签，说明你（或某个库）在客户端算了分位数——&lt;strong&gt;这在多实例场景下是错的&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;陷阱二桶边界不合适&#34;&gt;陷阱二：桶边界不合适&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;已在第 1 章 1.2 节讲过&lt;/strong&gt;。这里补充一个快速检查方法：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-promql&#34; data-lang=&#34;promql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 如果 P99 长期等于某个固定值（比如正好 100ms），说明桶在那一带太稀疏&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;histogram_quantile&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0.99&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;le&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;rate&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;http_server_requests_seconds_bucket[&lt;span style=&#34;color:#e6db74&#34;&gt;5m&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;自检&lt;/strong&gt;：把桶边界画出来，看 SLO 附近是否加密。&lt;/p&gt;
&lt;h3 id=&#34;陷阱三标签基数爆炸-&#34;&gt;陷阱三：标签基数爆炸 ⭐&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-kotlin&#34; data-lang=&#34;kotlin&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// ❌ 灾难：每个用户/订单/URL 一个时间序列
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;registry.counter(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;userId&amp;#34;&lt;/span&gt;, userId)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;registry.counter(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/orders/12345&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// ✅ 正确：只用可枚举维度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;registry.counter(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/orders/{id}&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;200&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;基数的量化影响&lt;/strong&gt;：&lt;/p&gt;</description>
    </item>
    <item>
      <title>数据与中间件观测：是数据库慢，还是等连接慢？</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/07-data-and-middleware/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/07-data-and-middleware/</guid>
      <description>&lt;h1 id=&#34;47-数据与中间件观测是数据库慢还是等连接慢&#34;&gt;4.7 数据与中间件观测：是数据库慢，还是等连接慢？&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/06-app-observability/&#34;&gt;4.6 应用可观测性&lt;/a&gt;　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/08-container-interference/&#34;&gt;4.8 容器与编排的干扰&lt;/a&gt;
配套代码：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/code/04-toolchain/07-data-and-middleware/&#34;&gt;04-toolchain/07-data-and-middleware&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一句话结论&#34;&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;「数据库慢」和「等连接慢」是两件完全不同的事，修法也完全相反。&lt;/strong&gt; 前者要优化 SQL 或加索引，后者要调连接池——&lt;strong&gt;搞错了会把问题放大&lt;/strong&gt;（盲目加连接池 = 把压力转移到数据库）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一用食堂打饭理解两个不同的瓶颈&#34;&gt;一、用「食堂打饭」理解两个不同的瓶颈&lt;/h2&gt;
&lt;p&gt;食堂里你等了 20 分钟才吃上饭。原因是哪个？&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;可能原因&lt;/th&gt;
					&lt;th&gt;类比&lt;/th&gt;
					&lt;th&gt;修法&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;打饭窗口只有一个，大家在排队&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;连接池太小&lt;/td&gt;
					&lt;td&gt;增加窗口（加连接）——但要小心&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;厨师做菜很慢，每个人都要等很久&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;查询慢&lt;/td&gt;
					&lt;td&gt;让厨师做快点（优化 SQL/加索引）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;窗口很多，但厨师只有 2 个&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;连接够了，但数据库处理能力不足&lt;/td&gt;
					&lt;td&gt;优化查询，减少并发&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;关键区别&lt;/strong&gt;：&lt;strong&gt;排队（等窗口）vs 服务慢（厨师慢）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;判断方法&lt;/strong&gt;：看两个不同的指标——&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;连接池 pending &amp;gt; 0  →  在排队（等窗口）
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;连接池 pending = 0 但查询耗时长  →  服务慢（厨师慢）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;这两个指标必须同时看&lt;/strong&gt;，只看一个必然误判。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二postgresql四个必看的视图与命令&#34;&gt;二、PostgreSQL：四个必看的视图与命令&lt;/h2&gt;
&lt;h3 id=&#34;21-pg_stat_statements最贵语句排行榜&#34;&gt;2.1 &lt;code&gt;pg_stat_statements&lt;/code&gt;：最贵语句排行榜&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 前提：在 postgresql.conf 里加 shared_preload_libraries = &amp;#39;pg_stat_statements&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; EXTENSION &lt;span style=&#34;color:#66d9ef&#34;&gt;IF&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;EXISTS&lt;/span&gt; pg_stat_statements;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 按总耗时排序（谁最消耗数据库时间）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    calls,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    round(total_exec_time::numeric, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)  &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; total_ms,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    round(mean_exec_time::numeric, &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)   &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; mean_ms,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    round((&lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; total_exec_time &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;sum&lt;/span&gt;(total_exec_time) OVER ())::numeric, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; pct,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;left&lt;/span&gt;(query, &lt;span style=&#34;color:#ae81ff&#34;&gt;70&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; query
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; pg_stat_statements
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;ORDER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; total_exec_time &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;LIMIT&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;读法（关键）&lt;/strong&gt;：&lt;/p&gt;</description>
    </item>
    <item>
      <title>容器与编排的干扰：「本地好、上线慢」的头号原因</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/08-container-interference/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/08-container-interference/</guid>
      <description>&lt;h1 id=&#34;48-容器与编排的干扰本地好上线慢的头号原因&#34;&gt;4.8 容器与编排的干扰：「本地好、上线慢」的头号原因&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/07-data-and-middleware/&#34;&gt;4.7 数据与中间件观测&lt;/a&gt;　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/09-lab4/&#34;&gt;4.9 Lab 4&lt;/a&gt;
配套代码：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/code/04-toolchain/08-container-interference/&#34;&gt;04-toolchain/08-container-interference&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一句话结论&#34;&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;容器 CPU limit 会让你的进程被周期性「掐停」&lt;/strong&gt;——平均 CPU 利用率看起来不高，但延迟会间隔性抖动，P99 明显变差。&lt;strong&gt;这是「本地压测很好、上线就慢」的头号原因&lt;/strong&gt;，而且不看 cgroup 指标几乎不可能发现。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一用限速器理解-cpu-节流&#34;&gt;一、用「限速器」理解 CPU 节流&lt;/h2&gt;
&lt;p&gt;想象你开车，但车上装了一个限速器：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;规则：&lt;strong&gt;每 100 毫秒的窗口内，最多只能开 10 毫秒的&amp;quot;油门时间&amp;quot;&lt;/strong&gt;（相当于 CPU limit = 0.1 核）。&lt;/li&gt;
&lt;li&gt;你正常行驶时看不出问题（因为大部分时间不需要那么多油门）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;但当你要加速时&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;第 1 个 100ms 窗口：你猛踩油门，10ms 用完 → 被强制&amp;#34;断油&amp;#34;剩余 90ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;第 2 个 100ms 窗口：又是一样
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;结果：你的&amp;#34;平均速度&amp;#34;看起来不高（因为大部分时间在滑行），
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      但每次踩油门都被强行打断 → 车一顿一顿的。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;这就是 CPU 节流&lt;/strong&gt;：不是「不给你 CPU」，而是「&lt;strong&gt;周期性掐断你的 CPU&lt;/strong&gt;」。&lt;/p&gt;
&lt;h3 id=&#34;对应到后端&#34;&gt;对应到后端&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;现象&lt;/th&gt;
					&lt;th&gt;解释&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;平均 CPU 利用率只有 40%&lt;/td&gt;
					&lt;td&gt;因为大部分时间被掐停了&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;P99 间隔性抖动&lt;/td&gt;
					&lt;td&gt;请求恰好落在被掐停的窗口里&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;火焰图上看到「什么都没做」的时间&lt;/td&gt;
					&lt;td&gt;线程被强制暂停&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GC 停顿时间变长&lt;/td&gt;
					&lt;td&gt;GC 线程也被节流&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;本地无限制 CPU 时完全正常&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;本地没有 cgroup 配额&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二怎么确认看-cgroup-的四个值&#34;&gt;二、怎么确认：看 cgroup 的四个值&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# cgroup v2（现代 Linux）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat /sys/fs/cgroup/cpu.max           &lt;span style=&#34;color:#75715e&#34;&gt;# 格式：&amp;lt;quota&amp;gt; &amp;lt;period&amp;gt;，例如 &amp;#34;100000 100000&amp;#34; = 1 核&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat /sys/fs/cgroup/cpu.stat          &lt;span style=&#34;color:#75715e&#34;&gt;# 关键指标在这里&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# cgroup v1（较老）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat /sys/fs/cgroup/cpu/cpu.cfs_period_us
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat /sys/fs/cgroup/cpu/cpu.stat
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;cpu.stat&lt;/code&gt; 的关键字段&lt;/strong&gt;：&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lab 4：搭起最小观测回路</title>
      <link>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/09-lab4/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/09-lab4/</guid>
      <description>&lt;h1 id=&#34;49-lab-4搭起最小观测回路&#34;&gt;4.9 Lab 4：搭起最小观测回路&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;上一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/04-toolchain/08-container-interference/&#34;&gt;4.8 容器与编排的干扰&lt;/a&gt;　|　下一节：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/05-experiment-design/&#34;&gt;第 5 章 实验设计与方法论&lt;/a&gt;
配套代码：&lt;a href=&#34;https://www.dorkytiger.top/kotlin/kotlin-benchmark/code/04-toolchain/09-lab4/&#34;&gt;04-toolchain/09-lab4&lt;/a&gt;
预计时长：&lt;strong&gt;120 分钟&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一这个-lab-的目标&#34;&gt;一、这个 Lab 的目标&lt;/h2&gt;
&lt;p&gt;把本章的工具&lt;strong&gt;串成一条回路&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;k6 压测 → 服务 → Prometheus/Grafana → 火焰图
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ↑                                      │
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   └──────── 现象 → 假设 → 验证 ←──────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;关键不是「每个工具都会用」，而是「它们能互相验证」&lt;/strong&gt;：指标告诉你哪里有异常，火焰图告诉你是哪行代码，两者对得上，结论才可信。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二任务清单&#34;&gt;二、任务清单&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;#&lt;/th&gt;
					&lt;th&gt;任务&lt;/th&gt;
					&lt;th&gt;产出&lt;/th&gt;
					&lt;th&gt;时长&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;搭观测栈（Prometheus + Grafana）&lt;/td&gt;
					&lt;td&gt;Docker Compose 一键启动&lt;/td&gt;
					&lt;td&gt;25 min&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;2&lt;/td&gt;
					&lt;td&gt;埋四层指标并验证&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/metrics&lt;/code&gt; 输出含四层&lt;/td&gt;
					&lt;td&gt;20 min&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;3&lt;/td&gt;
					&lt;td&gt;跑通 k6 回路&lt;/td&gt;
					&lt;td&gt;三条曲线同屏（到达率/QPS/P99）&lt;/td&gt;
					&lt;td&gt;20 min&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;4&lt;/td&gt;
					&lt;td&gt;采四类火焰图并对比&lt;/td&gt;
					&lt;td&gt;cpu/wall/alloc/lock 各一份&lt;/td&gt;
					&lt;td&gt;30 min&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;5&lt;/td&gt;
					&lt;td&gt;JFR 录制并分析&lt;/td&gt;
					&lt;td&gt;至少找到一条线索&lt;/td&gt;
					&lt;td&gt;15 min&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;6&lt;/td&gt;
					&lt;td&gt;容器节流检查&lt;/td&gt;
					&lt;td&gt;确认有无节流&lt;/td&gt;
					&lt;td&gt;10 min&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三任务-1观测栈&#34;&gt;三、任务 1：观测栈&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker compose -f docker-compose.observability.yml up -d
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Prometheus → http://localhost:9090&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Grafana    → http://localhost:3000 (admin/admin)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;验收&lt;/strong&gt;：Prometheus 的 &lt;code&gt;/targets&lt;/code&gt; 页面显示你的应用是 &lt;code&gt;UP&lt;/code&gt;。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
