<?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>Sysctl · XB 现场笔记</title><link>https://hk.xbcatm.com/zh/tags/sysctl/</link><description>基于 HTTP、DNS、TLS、Caddy、SSH、发布与恢复的可复现运维现场笔记。</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://hk.xbcatm.com/zh/tags/sysctl/index.xml" rel="self" type="application/rss+xml"/><item><title>SYN backlog 保存未完成握手的请求</title><link>https://hk.xbcatm.com/zh/posts/sysctl-tcp-max-sync-backlog/</link><pubDate>Fri, 24 Mar 2028 00:00:00 +0000</pubDate><guid>https://hk.xbcatm.com/zh/posts/sysctl-tcp-max-sync-backlog/</guid><description>Linux 区分记住的 SYN 请求和等待 accept 的已建立连接；cookies 是兜底机制，并非容量保证。</description><content:encoded>&lt;p&gt;监听中的 TCP 套接字会区分未完成握手的请求，以及已经建立、等待应用 &lt;code&gt;accept()&lt;/code&gt; 的连接。真正的参数名是 &lt;code&gt;tcp_max_syn_backlog&lt;/code&gt;；本文保留历史 URL 中的拼写。它约束的是内核记住的半开请求，而传给 &lt;code&gt;listen()&lt;/code&gt; 的 backlog 约束 accept 队列。先弄清压力发生在哪个阶段，再考虑处理办法，否则调大一个数字很可能没有解决真正的问题。&lt;/p&gt;
&lt;p&gt;SYN cookies 是无法继续保存普通握手状态时的兜底机制。它不代表服务器不会过载、不保证报文送达，也不意味着 SYN 队列从此无需关注。即使启用了 cookies，丢包、过滤、资源分配失败和 accept 侧压力仍然可能让连接失败。判断时必须把握手状态、应用接收速度与最终业务响应分开。&lt;/p&gt;
&lt;figure class="technical-diagram"&gt;&lt;img loading="lazy" src="https://hk.xbcatm.com/visuals/posts-sysctl-tcp-max-sync-backlog.detail.zh.svg" alt="SYN 队列保存未完成握手的请求，accept 队列保存已建立、等待 accept() 的连接。仅当 listen backlog 配置为 8192、somaxconn 为 4096 时，accept 侧上限为 4096。增加等待容量本身不会提高处理速率；原文全文仍暂缓、待审。" width="720" height="2230"&gt;&lt;figcaption&gt;SYN 队列保存未完成握手的请求，accept 队列保存已建立、等待 accept() 的连接。仅当 listen backlog 配置为 8192、somaxconn 为 4096 时，accept 侧上限为 4096。增加等待容量本身不会提高处理速率；原文全文仍暂缓、待审。 全文仍暂缓、待审；本图不为文中存疑论断背书。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id="backlog-参数管的是-accept-队列"&gt;backlog 参数管的是 accept 队列&lt;/h2&gt;
&lt;p&gt;Linux 从 2.2 起改变了 &lt;code&gt;listen()&lt;/code&gt; backlog 的含义。配置值会受到 &lt;code&gt;somaxconn&lt;/code&gt; 限制；只有当两者分别是 8192 和 4096 时，配置上限才是 4096。这是条件明确的配置例子，不是一次测量得到的精确接纳数量。应查看实际监听套接字与其网络命名空间，不能假定默认值，也不能根据短促突发中恰好成功的连接数反推严格容量。&lt;/p&gt;
&lt;p&gt;内核文档将 &lt;code&gt;tcp_max_syn_backlog&lt;/code&gt; 定义为每个监听套接字记住的 SYN_RECV 请求数限制，初始值与内存及内核实现有关。旧手册中的内存分档不能当作当前机器的实际配置。任何一个队列的长度，都不能单独说明应用每秒能完成多少请求；排队等待和处理能力是不同的观测维度。&lt;/p&gt;
&lt;h2 id="syncookies-开着的时候syn-队列就不再是瓶颈"&gt;SYN cookies 仍然只是兜底&lt;/h2&gt;
&lt;p&gt;在内核支持该功能的前提下，&lt;code&gt;tcp_syncookies=1&lt;/code&gt; 启用溢出兜底；值 2 是无条件发送 cookies 的测试模式。listen 手册所说的取消逻辑长度限制，描述的是不为每个请求保存状态的接纳路径，并不是无限内存、CPU、带宽或已建立套接字。面对合法流量造成的压力，内核文档仍建议结合应用消化工作的能力，考虑 SYN backlog 等相关配置，而不是宣布这个参数已经过时。&lt;/p&gt;
&lt;p&gt;也不能保证每条 cookie 连接都会失去 SACK 和窗口缩放。固定到 Linux v6.12 的实现，在协商时间戳时可以把这些选项编码进时间戳位；具体能保留什么，取决于实现和协商结果。这个限定结论既不等于保留所有 TCP 扩展，也不意味着紧急兜底可以代替容量规划。直接关闭 cookies 同样不是普遍适用的修复方案。&lt;/p&gt;
&lt;h2 id="压力真正落在-accept-队列上"&gt;压力真正落在 accept 队列上&lt;/h2&gt;
&lt;p&gt;accept 侧与 SYN 侧的压力可以同时存在。在 Linux v6.12 的普通握手路径里，创建子套接字失败可能进入溢出分支；当 &lt;code&gt;tcp_abort_on_overflow&lt;/code&gt; 关闭时，服务端可以保留请求，而不是立即复位。此时客户端可能已经认为连接建立，后续应用通信却停滞。这是一种可能出现的状态不一致，不能推导为每次 &lt;code&gt;connect()&lt;/code&gt; 都必定成功。&lt;/p&gt;
&lt;p&gt;更大的队列可以容纳有限突发，也可能增加等待时间，但它本身不能证明稳态处理能力提高。应一起测量到达速率、accept 等待时间和应用完成情况。本文没有实测每秒 20,000 次连接的数据，也不把未提供的模型结果当作吞吐证据。&lt;/p&gt;
&lt;h2 id="坏掉的样子"&gt;坏掉的样子&lt;/h2&gt;
&lt;p&gt;溢出计数器增长值得调查，但不能唯一归因于某个处理线程。accept 循环的调度、资源耗尽、同一网络命名空间中的其他监听套接字，以及两次采样之间的突发，都会影响解释。历史累计值非零，不等于当前正在发生故障；仅凭一次截图也无法还原事件顺序或受影响的请求。&lt;/p&gt;
&lt;p&gt;启用 cookies 时仍然可能丢失 SYN。客户端重试时间取决于内核版本、重试配置、套接字行为与应用截止时间，67 秒或 131 秒都不是通用超时承诺。TCP 连接成功也不等于应用请求完成，排查时需要保留两者各自的结果，而不能把连接阶段的成功当作业务层恢复。&lt;/p&gt;
&lt;h2 id="快速验证"&gt;快速验证&lt;/h2&gt;
&lt;p&gt;下面是网络状态观察练习，仅适用于已获授权的 Linux 系统：8443 端口已有监听者，且当前处于它所在的网络命名空间，&lt;code&gt;ss&lt;/code&gt;、&lt;code&gt;nstat&lt;/code&gt; 和 &lt;code&gt;sysctl&lt;/code&gt; 已经安装。不要为了练习启动监听者、制造过载、修改参数或提升权限。本轮审查没有运行这些命令，也没有取得新的内核行为证据。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ss -lnt &amp;#39;sport = :8443&amp;#39;
nstat -az TcpExtListenOverflows TcpExtListenDrops TcpExtTCPReqQFullDrop TcpExtTCPReqQFullDoCookies
sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_syncookies net.ipv4.tcp_abort_on_overflow
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在已经获准的普通工作负载前后各取一次快照。对监听中的 TCP 套接字，&lt;code&gt;Recv-Q&lt;/code&gt; 表示排队等待接收的已建立连接，&lt;code&gt;Send-Q&lt;/code&gt; 表示实际 backlog 限制。输出为空表示没有可见的匹配监听者，不表示队列长度为零。当前 sysctl 值也不能倒推已有监听者创建时的配置；应记录监听上下文，避免把别的命名空间当成目标。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;nstat -az&lt;/code&gt; 显示包含零值的绝对计数，并可能更新本地历史；应比较同一观察区间的增量。这几个计数器提供溢出、请求丢弃和 cookie 兜底的不同线索，但它们属于整个网络命名空间，也不是彼此互斥的单监听者判决。提出调优方案前，记录内核版本、监听上下文和应用请求结果。缺少工具、访问权限或隔离测试环境时，运行时结论继续保持未决，不为补齐证据放宽安全边界。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.kernel.org/doc/html/latest/networking/ip-sysctl.html"&gt;内核 ip-sysctl 文档&lt;/a&gt;，SYN 请求限制、cookie 模式与过载处理建议；保留早期核验日期 2026-09-16，已核验 2026-10-19。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man7.org/linux/man-pages/man2/listen.2.html"&gt;Linux listen(2)&lt;/a&gt;，accept backlog 的含义及 somaxconn 配置上限；保留早期核验日期 2026-09-16，已核验 2026-10-19。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man7.org/linux/man-pages/man7/tcp.7.html"&gt;Linux tcp(7)&lt;/a&gt;，与版本相关的配置及重试行为；保留早期核验日期 2026-09-16，已核验 2026-10-19。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/torvalds/linux/v6.12/net/ipv4/syncookies.c"&gt;Linux v6.12 cookie 实现&lt;/a&gt;，利用时间戳编码 SACK 和窗口缩放，已核验 2026-10-19。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/torvalds/linux/blob/v6.12/net/ipv4/tcp_minisocks.c"&gt;Linux v6.12 握手实现&lt;/a&gt;，有条件进入的 listen_overflow 分支，已核验 2026-10-19。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man7.org/linux/man-pages/man8/nstat.8.html"&gt;iproute2 nstat 手册&lt;/a&gt;，绝对计数与零值显示选项，已核验 2026-10-19。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>