<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Tcp_tw_reuse on Zero Day Notes</title>
        <link>https://blog.5772447.xyz/tags/tcp_tw_reuse/</link>
        <description>Recent content in Tcp_tw_reuse on Zero Day Notes</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <lastBuildDate>Sun, 30 Aug 2026 07:00:00 +0800</lastBuildDate><atom:link href="https://blog.5772447.xyz/tags/tcp_tw_reuse/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>一次 Linux 内核参数调优误配导致 TCP 性能断崖的排查记录</title>
            <link>https://blog.5772447.xyz/posts/8d0234d5/</link>
            <pubDate>Sun, 30 Aug 2026 07:00:00 +0800</pubDate>
            <guid>https://blog.5772447.xyz/posts/8d0234d5/</guid>
            <description>&lt;h2 id=&#34;问题背景&#34;&gt;&lt;a href=&#34;#%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;生产环境一台对外提供大文件下载与 API 聚合的服务器，在高峰期偶发吞吐量断崖式下跌（从 1.2 Gbps 跌到 40 Mbps），但 &lt;code&gt;iostat&lt;/code&gt;、&lt;code&gt;sar&lt;/code&gt;、&lt;code&gt;top&lt;/code&gt; 均未见磁盘/CPU/内存瓶颈。早期通过粗暴调优 &lt;code&gt;tcp_tw_reuse=1&lt;/code&gt; 与 &lt;code&gt;netdev_max_backlog=30000&lt;/code&gt; 试图缓解 TIME_WAIT 与软中断队列压力，调优后两天内性能反而更差。最终决定系统性回溯内核参数变更，定位到 PAWS 时间戳误判与 qdisc 队列积压两个隐藏冲突。&lt;/p&gt;&#xA;&lt;h2 id=&#34;故障现象&#34;&gt;&lt;a href=&#34;#%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;ul&gt;&#xA;&lt;li&gt;晚高峰 20:00-22:00 对外下载速度从 120 MB/s 跌至不足 5 MB/s，P99 延迟从 80 ms 飙到 8 s。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;ss -s&lt;/code&gt; 显示 &lt;code&gt;TimeWait&lt;/code&gt; 仍维持在 3 万左右，但 &lt;code&gt;Recv-Q&lt;/code&gt; 与 &lt;code&gt;Send-Q&lt;/code&gt; 几乎为 0，连接看似空闲却无法推进。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;tcpdump -i any port 80&lt;/code&gt; 抓包发现大量 &lt;code&gt;TCP ACK&lt;/code&gt; 被静默丢弃，远端不断重传；同时发现部分 SYN 报文携带时间戳，但服务端回复 RST。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;tc -s qdisc show dev eth0&lt;/code&gt; 显示 &lt;code&gt;backlog 28765p&lt;/code&gt; 持续堆积，&lt;code&gt;dropped&lt;/code&gt; 计数每秒递增数百。&lt;/li&gt;&#xA;&lt;li&gt;重启 nginx / 重载配置无效，必须重启整机才能短暂恢复。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;排查过程&#34;&gt;&lt;a href=&#34;#%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;h3 id=&#34;1-排除应用层&#34;&gt;&lt;a href=&#34;#1-%e6%8e%92%e9%99%a4%e5%ba%94%e7%94%a8%e5%b1%82&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;1. 排除应用层&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;先用 &lt;code&gt;strace -p &amp;lt;nginx worker&amp;gt;&lt;/code&gt; 确认 worker 线程并未阻塞在 &lt;code&gt;sendfile&lt;/code&gt;/&lt;code&gt;writev&lt;/code&gt;，排除了业务代码 bug。接着用 &lt;code&gt;perf top -e cpu-clock&lt;/code&gt; 采样 30 秒，热点落在 &lt;code&gt;tcp_write_xmit&lt;/code&gt; 与 &lt;code&gt;__qdisc_run&lt;/code&gt;，指向内核网络栈。&lt;/p&gt;&#xA;&lt;h3 id=&#34;2-内核参数回溯&#34;&gt;&lt;a href=&#34;#2-%e5%86%85%e6%a0%b8%e5%8f%82%e6%95%b0%e5%9b%9e%e6%ba%af&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;2. 内核参数回溯&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;对比 &lt;code&gt;/etc/sysctl.d/*.conf&lt;/code&gt; 与 &lt;code&gt;sysctl -a&lt;/code&gt; 差异，发现最近三周内修改过 17 个 TCP 相关参数，其中 &lt;code&gt;tcp_tw_reuse=1&lt;/code&gt;、&lt;code&gt;netdev_max_backlog=30000&lt;/code&gt;、&lt;code&gt;tcp_timestamps=1&lt;/code&gt; 三者同时存在。&lt;/p&gt;&#xA;&lt;h3 id=&#34;3-paws-时间戳误判&#34;&gt;&lt;a href=&#34;#3-paws-%e6%97%b6%e9%97%b4%e6%88%b3%e8%af%af%e5%88%a4&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;3. PAWS 时间戳误判&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;tcpdump&lt;/code&gt; 抓到远端 SYN 携带时间戳 &lt;code&gt;TSval=0x12ab&lt;/code&gt;，服务端回复 RST。查阅内核源码 &lt;code&gt;tcp_v4_conn_request&lt;/code&gt; 中的 &lt;code&gt;tcp_paws_check&lt;/code&gt;，当 &lt;code&gt;tcp_tw_reuse=1&lt;/code&gt; 且 TIME_WAIT 桶被快速复用时，旧连接残留的时间戳可能触发 PAWS（Protect Against Wrapped Sequence numbers）误判，导致新 SYN 被丢弃。&lt;/p&gt;&#xA;&lt;h3 id=&#34;4-qdisc-队列暴涨&#34;&gt;&lt;a href=&#34;#4-qdisc-%e9%98%9f%e5%88%97%e6%9a%b4%e6%b6%a8&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;4. qdisc 队列暴涨&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;netdev_max_backlog=30000&lt;/code&gt; 配合 &lt;code&gt;fq&lt;/code&gt; qdisc 默认 &lt;code&gt;limit 10000&lt;/code&gt; 不匹配，导致软中断上下文把报文塞进 qdisc 队列，队列满后直接 &lt;code&gt;drop&lt;/code&gt;。用 &lt;code&gt;tc qdisc replace dev eth0 root fq limit 40000 flow_limit 2000&lt;/code&gt; 临时验证，&lt;code&gt;dropped&lt;/code&gt; 计数立即归零，吞吐量回升至 800 Mbps。&lt;/p&gt;&#xA;&lt;h3 id=&#34;5-复现与确认&#34;&gt;&lt;a href=&#34;#5-%e5%a4%8d%e7%8e%b0%e4%b8%8e%e7%a1%ae%e8%ae%a4&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;5. 复现与确认&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;在测试环境用 &lt;code&gt;tc qdisc add dev eth0 root netem delay 50ms&lt;/code&gt; 模拟广域网 + 大流量压测，确认 &lt;code&gt;tcp_tw_reuse + tcp_timestamps + fq limit 不匹配&lt;/code&gt; 三者叠加即可稳定复现 PAWS 丢包 + qdisc drop。&lt;/p&gt;&#xA;&lt;h2 id=&#34;解决方案&#34;&gt;&lt;a href=&#34;#%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;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;紧急止血&lt;/strong&gt;：临时把 &lt;code&gt;netdev_max_backlog&lt;/code&gt; 回退到 5000，并把 fq limit 调大到 40000，5 分钟内恢复 90% 吞吐量。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;根治参数模板&lt;/strong&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;&lt;span style=&#34;color:#75715e&#34;&gt;# /etc/sysctl.d/99-tcp-performance.conf&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.core.netdev_max_backlog &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16384&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.core.somaxconn &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;65535&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.ipv4.tcp_tw_reuse &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.ipv4.tcp_timestamps &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.ipv4.tcp_rmem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4096&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;87380&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;6291456&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.ipv4.tcp_wmem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4096&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16384&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4194304&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.ipv4.tcp_congestion_control &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; bbr&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.core.default_qdisc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; fq&#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;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;qdisc 持久化&lt;/strong&gt;：用 systemd-networkd 的 &lt;code&gt;.network&lt;/code&gt; 文件或 NetworkManager dispatcher 脚本在 &lt;code&gt;post-up&lt;/code&gt; 阶段执行 &lt;code&gt;tc qdisc replace&lt;/code&gt;，避免重启后配置丢失。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;监控增强&lt;/strong&gt;：在 Prometheus node_exporter 添加 &lt;code&gt;node_netstat_Tcp_RetransSegs&lt;/code&gt;、&lt;code&gt;tc -j qdisc show&lt;/code&gt; 解析脚本，每分钟告警 backlog &amp;gt; 10000 或 drop rate &amp;gt; 10 pps。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;根因分析&#34;&gt;&lt;a href=&#34;#%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;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;tcp_tw_reuse=1&lt;/code&gt; 必须搭配 &lt;code&gt;tcp_timestamps=1&lt;/code&gt; 使用，但 PAWS 检查在高并发短连接场景下会误判旧时间戳，导致 SYN 被 RST。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;netdev_max_backlog&lt;/code&gt; 只控制软中断入队上限，不控制 qdisc 队列长度，两者不匹配造成入队即丢包的「静默黑洞」。&lt;/li&gt;&#xA;&lt;li&gt;调优时缺少「变更后 48 小时全链路压测 + 关键指标基线对比」，把局部优化误判为全局最优。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;预防措施&#34;&gt;&lt;a href=&#34;#%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;&lt;strong&gt;参数变更 Checklist&lt;/strong&gt;：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;变更前必须用 &lt;code&gt;sysctl -a | grep &amp;lt;key&amp;gt;&lt;/code&gt; 记录基线。&lt;/li&gt;&#xA;&lt;li&gt;变更后 30 分钟内跑 &lt;code&gt;wrk&lt;/code&gt;/&lt;code&gt;iperf3&lt;/code&gt; 压测 5 分钟，采集 &lt;code&gt;ss -s&lt;/code&gt;、&lt;code&gt;tc -s qdisc&lt;/code&gt;、&lt;code&gt;netstat -s&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;任何涉及 &lt;code&gt;tcp_tw_reuse&lt;/code&gt; / &lt;code&gt;timestamps&lt;/code&gt; / &lt;code&gt;backlog&lt;/code&gt; 的变更，必须附上「PAWS 风险评估」。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;模板化&lt;/strong&gt;：把经过验证的参数集合做成 Ansible role 或 Salt state，所有新服务器必须套用。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;自动化巡检&lt;/strong&gt;：每周跑一次 &lt;code&gt;ss -tan state time-wait | wc -l&lt;/code&gt; + &lt;code&gt;tc -s qdisc&lt;/code&gt; 对比历史基线，偏差 &amp;gt; 30% 即告警。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;文档闭环&lt;/strong&gt;：在运维 Wiki 新增「Linux TCP 调优避坑指南」，把本次 PAWS + qdisc 案例写入「已踩过的坑」章节。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;总结&#34;&gt;&lt;a href=&#34;#%e6%80%bb%e7%bb%93&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;总结&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;一次看似「常规」的内核参数调优，因为缺少对 PAWS 时间戳语义与 qdisc 队列长度匹配的理解，反而引入了更严重的性能黑洞。通过系统性回溯、抓包定位、参数模板收口，最终把故障转化为可复用的 Checklist。本次事件再次印证：内核参数没有银弹，任何调优都必须经过「基线 → 变更 → 压测 → 监控」四步闭环。后续将把该 Checklist 固化进服务器上线流程，避免同类问题再次发生。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
