<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>内存 on Zero Day Notes</title>
        <link>https://blog.5772447.xyz/tags/%E5%86%85%E5%AD%98/</link>
        <description>Recent content in 内存 on Zero Day Notes</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <lastBuildDate>Wed, 02 Jul 2025 09:08:48 +0000</lastBuildDate><atom:link href="https://blog.5772447.xyz/tags/%E5%86%85%E5%AD%98/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>记一次 K8s Pod OOMKilled 触发的服务雪崩</title>
            <link>https://blog.5772447.xyz/posts/2025-07-02-%E4%B8%80%E6%AC%A1kubernetes-pod-oomkilled%E8%A7%A6%E5%8F%91%E6%9C%8D%E5%8A%A1%E9%9B%AA%E5%B4%A9%E7%9A%84%E6%8E%92%E6%9F%A5%E8%AE%B0%E5%BD%95/</link>
            <pubDate>Wed, 02 Jul 2025 09:08:48 +0000</pubDate>
            <guid>https://blog.5772447.xyz/posts/2025-07-02-%E4%B8%80%E6%AC%A1kubernetes-pod-oomkilled%E8%A7%A6%E5%8F%91%E6%9C%8D%E5%8A%A1%E9%9B%AA%E5%B4%A9%E7%9A%84%E6%8E%92%E6%9F%A5%E8%AE%B0%E5%BD%95/</guid>
            <description>&lt;h2 id=&#34;一问题背景&#34;&gt;&lt;a href=&#34;#%e4%b8%80%e9%97%ae%e9%a2%98%e8%83%8c%e6%99%af&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;一、问题背景&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;我们的订单中心 &lt;code&gt;order-service&lt;/code&gt; 跑在 Kubernetes 集群（v1.27，containerd 运行时）上，Deployment 配置 6 个副本，平时负载稳定，内存常驻约 600MB。该服务是交易链路的核心，下游由支付、库存等服务调用，上游又被 API 网关和多个内部业务系统依赖。&lt;/p&gt;&#xA;&lt;p&gt;某天上午，运营临时做了一个营销活动，订单量较平日上涨约 3 倍。活动开始约 20 分钟后，订单成功率告警触发。此时我们并未发版，纯属流量驱动的突发故障。集群节点规格为 8C16G，节点本身剩余内存充足，看起来不像是节点级资源问题。&lt;/p&gt;&#xA;&lt;h2 id=&#34;二故障现象&#34;&gt;&lt;a href=&#34;#%e4%ba%8c%e6%95%85%e9%9a%9c%e7%8e%b0%e8%b1%a1&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;二、故障现象&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;监控面板在 09:05 左右集中飘红：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;order-service&lt;/code&gt; 的 &lt;code&gt;CrashLoopBackOff&lt;/code&gt; 副本数从 0 涨到 4，6 个副本里一度只剩 2 个在 &lt;code&gt;Running&lt;/code&gt;；&lt;/li&gt;&#xA;&lt;li&gt;上游 API 网关大量返回 504，&lt;code&gt;order-service&lt;/code&gt; 调用超时率从 0.2% 升到 35%；&lt;/li&gt;&#xA;&lt;li&gt;订单创建成功率从 99.6% 跌到 58%，部分用户出现重复下单；&lt;/li&gt;&#xA;&lt;li&gt;滚动更新状态卡在 &lt;code&gt;Progressing&lt;/code&gt;：新副本 &lt;code&gt;ready&lt;/code&gt; 数量始终达不到 &lt;code&gt;minAvailable&lt;/code&gt;，Deployment 既不成功也不回滚。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;最迷惑的是：节点 &lt;code&gt;kubectl top node&lt;/code&gt; 显示内存还有 6G+ 空闲，但 Pod 就是不断重启。这说明问题出在 &lt;strong&gt;Pod 级别内存限制（limit）&lt;/strong&gt;，而不是节点容量。&lt;/p&gt;&#xA;&lt;h2 id=&#34;三排查过程&#34;&gt;&lt;a href=&#34;#%e4%b8%89%e6%8e%92%e6%9f%a5%e8%bf%87%e7%a8%8b&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;三、排查过程&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;第一步，看 Pod 事件，直接命中关键字：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div 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;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&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&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&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;$ kubectl describe pod order-service-7d9c8b6f4-xyz12&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Last State:     Terminated&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Reason:       OOMKilled&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Exit Code:    &lt;span style=&#34;color:#ae81ff&#34;&gt;137&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Events:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Type     Reason     Age   From               Message&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Warning  Unhealthy  2m    kubelet            Readiness probe failed: HTTP probe failed with statuscode: &lt;span style=&#34;color:#ae81ff&#34;&gt;503&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Warning  BackOff    1m    kubelet            Back-off restarting failed container&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Reason: OOMKilled&lt;/code&gt; 和 &lt;code&gt;Exit Code: 137&lt;/code&gt; 明确说明容器是被 cgroup 杀了——进程实际用量超过了 &lt;code&gt;memory limit&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;第二步，看内存配置和真实用量：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div 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;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&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&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&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;$ kubectl get deploy order-service -o jsonpath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{.spec.template.spec.containers[0].resources}&amp;#39;&lt;/span&gt;&#xA;&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:#e6db74&#34;&gt;&amp;#34;limits&amp;#34;&lt;/span&gt;:&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;memory&amp;#34;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1Gi&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;requests&amp;#34;&lt;/span&gt;:&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cpu&amp;#34;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;500m&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;memory&amp;#34;&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;512Mi&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ kubectl top pod | grep order-service&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;order-service-7d9c8b6f4-abc 980Mi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;limit 设了 1Gi，但流量上涨后 RSS 已逼近 980Mi，剩余空间几乎为 0。一旦有请求峰值或 GC 不及时，立刻越线被杀。&lt;/p&gt;&#xA;&lt;p&gt;第三步，确认是不是内存泄漏。拉取一个还没被杀的 Pod 的堆信息：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div 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;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&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&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&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;$ kubectl exec order-service-xxx -- jmap -histo:live &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; | head -15&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; num     &lt;span style=&#34;color:#75715e&#34;&gt;#instances         #bytes  class name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   1:        &lt;span style=&#34;color:#ae81ff&#34;&gt;420183&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;71234560&lt;/span&gt;  java.util.concurrent.ConcurrentHashMap$Node&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   2:        &lt;span style=&#34;color:#ae81ff&#34;&gt;318902&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;25512160&lt;/span&gt;  com.xxx.OrderCacheEntry&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   3:        &lt;span style=&#34;color:#ae81ff&#34;&gt;120033&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;14403960&lt;/span&gt;  java.lang.String&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;code&gt;OrderCacheEntry&lt;/code&gt; 实例高达 31 万个且持续增长——这是一个本地订单缓存，使用 &lt;code&gt;ConcurrentHashMap&lt;/code&gt; 但&lt;strong&gt;没有设置容量上限和过期策略&lt;/strong&gt;，活动期间订单不断写入，缓存无限膨胀，导致内存只涨不落。&lt;/p&gt;&#xA;&lt;p&gt;第四步，解释&amp;quot;雪崩&amp;quot;链条。Pod 被 OOMKilled 后重启，重启期间 &lt;code&gt;readinessProbe&lt;/code&gt; 在应用冷启动 + 缓存重建完成前一直返回 503，于是 Endpoint 不把流量切给它；而剩余存活副本要承接全部流量，内存进一步上涨，再次 OOMKilled——形成&lt;strong&gt;重启→探活失败→流量集中→再 OOM&lt;/strong&gt;的死亡螺旋。滚动更新因为新副本始终 &lt;code&gt;ready&lt;/code&gt; 不过半，卡死在 Progressing，无法自愈。&lt;/p&gt;&#xA;&lt;h2 id=&#34;四解决方案&#34;&gt;&lt;a href=&#34;#%e5%9b%9b%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;四、解决方案&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;应急（先止血）：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;立即调大 &lt;code&gt;memory limit&lt;/code&gt; 到 2Gi、request 提到 1Gi，并临时把副本数扩到 12，分散单 Pod 压力，打破越线被杀的循环：&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div 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;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&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&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&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;$ kubectl scale deploy order-service --replicas&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;给 &lt;code&gt;readinessProbe&lt;/code&gt; 增加 &lt;code&gt;initialDelaySeconds: 30&lt;/code&gt; 与更宽容的 &lt;code&gt;failureThreshold&lt;/code&gt;，避免冷启动期被误判摘流（临时缓解，非根治）。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;紧急重启有泄漏风险的缓存：对 &lt;code&gt;OrderCacheEntry&lt;/code&gt; 增加容量上限（LRU，最大 5 万条）+ TTL（10 分钟），重新发版。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;给 Deployment 配置 &lt;code&gt;minReadySeconds&lt;/code&gt; 与 &lt;code&gt;progressDeadlineSeconds: 300&lt;/code&gt;，并在探针上加 &lt;code&gt;startupProbe&lt;/code&gt;，让冷启动阶段不被 readiness 误杀：&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div 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;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&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&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;startupProbe&lt;/span&gt;:&#xA;&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;httpGet&lt;/span&gt;:&#xA;&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;path&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;/health&lt;/span&gt;&#xA;&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;port&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;&#xA;&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;failureThreshold&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;&#xA;&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;periodSeconds&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;发版后副本稳定 &lt;code&gt;Running&lt;/code&gt;，上游超时率 5 分钟内回落到 0.3%，订单成功率恢复到 99.4%。&lt;/p&gt;&#xA;&lt;h2 id=&#34;五根因分析&#34;&gt;&lt;a href=&#34;#%e4%ba%94%e6%a0%b9%e5%9b%a0%e5%88%86%e6%9e%90&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;五、根因分析&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;根因是&lt;strong&gt;无界本地缓存导致的内存泄漏&lt;/strong&gt;，在流量上涨时触顶 &lt;code&gt;memory limit&lt;/code&gt; 被 cgroup OOMKilled。雪崩的放大器是两点：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;readiness 探针在冷启动期误摘流&lt;/strong&gt;：Pod 重启后缓存未预热完即被判定不健康，Endpoint 不接流量，存活副本承压更重。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;滚动更新卡死&lt;/strong&gt;：新副本始终达不到 ready 阈值，Deployment 既不能完成也不能自动回滚，故障窗口被人为拉长。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;节点有空余内存是假象——Kubernetes 的 OOM 是按 Pod cgroup 边界触发的，和节点总内存无关。&lt;/p&gt;&#xA;&lt;h2 id=&#34;六预防措施&#34;&gt;&lt;a href=&#34;#%e5%85%ad%e9%a2%84%e9%98%b2%e6%8e%aa%e6%96%bd&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;六、预防措施&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;所有本地缓存必须有界&lt;/strong&gt;：用 Caffeine/Guava Cache 显式设置 &lt;code&gt;maximumSize&lt;/code&gt; 与 &lt;code&gt;expireAfterWrite&lt;/code&gt;，禁止裸用 &lt;code&gt;ConcurrentHashMap&lt;/code&gt; 当缓存。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;内存 limit 留足 headroom&lt;/strong&gt;：limit 不应紧贴常驻用量，建议 limit ≥ 常驻峰值 × 1.5，并配置 &lt;code&gt;requests&lt;/code&gt; 与 &lt;code&gt;limits&lt;/code&gt; 一致以避免被调度到紧张节点。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;探针三件套合理配置&lt;/strong&gt;：&lt;code&gt;startupProbe&lt;/code&gt; 保护冷启动、&lt;code&gt;readinessProbe&lt;/code&gt; 控制接流、&lt;code&gt;livenessProbe&lt;/code&gt; 控制重启，三者职责分离，避免互相误伤。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;设置 PodDisruptionBudget + progressDeadlineSeconds&lt;/strong&gt;，配合告警，让滚动更新卡死能被及时发现并人工/自动干预。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;内存监控与压测&lt;/strong&gt;：对 &lt;code&gt;container_memory_working_set_bytes&lt;/code&gt; 设 80% 告警，大促前按 3 倍流量做容量压测，提前暴露泄漏。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;七总结&#34;&gt;&lt;a href=&#34;#%e4%b8%83%e6%80%bb%e7%bb%93&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;七、总结&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;这次故障的教训是：&lt;strong&gt;Kubernetes 的 OOM 是 Pod 级的，不是节点级的&lt;/strong&gt;。看到节点有内存就以为安全，是典型的认知陷阱。更深的坑在于 OOMKilled 与探针、滚动更新的耦合——单点重启会被链路放大成整服务雪崩。排查时 &lt;code&gt;kubectl describe pod&lt;/code&gt; 里的 &lt;code&gt;Reason: OOMKilled&lt;/code&gt; + &lt;code&gt;Exit Code 137&lt;/code&gt; 是第一线索，再用 &lt;code&gt;jmap -histo:live&lt;/code&gt; 定位泄漏对象。容器环境下，任何&amp;quot;无限增长&amp;quot;的本地状态都是隐患，给缓存设边界、给探针分职责、给更新加兜底，三者缺一不可。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
