当前内核是否支持tcp fast open需先检查/proc/sys/net/ipv4/tcp_fastopen是否存在,存在则查看其值(0-3),不存在则内核未编译config_tcp_fastopen;再确认应用层是否调用setsockopt启用tfo。

如何确认当前内核是否支持TCP Fast Open
Linux 4.1+ 内核原生支持 TCP Fast Open(TFO),但需确认实际启用状态。直接查 /proc/sys/net/ipv4/tcp_fastopen 的值最可靠:
-
0:完全禁用(默认值,即使内核支持也不生效) -
1:仅作为客户端启用 TFO(可发 TFO Cookie,但不接受 TFO 请求) -
2:仅作为服务端启用(可响应 TFO 请求,但不发 Cookie) -
3:客户端和服务端均启用(推荐生产环境使用)
运行 cat /proc/sys/net/ipv4/tcp_fastopen 即可查看。若报错 “No such file”,说明内核编译时未开启 CONFIG_TCP_FASTOPEN —— 这种情况只能升级内核或重编译。
怎样临时启用 TCP Fast Open(无需重启)
修改 /proc/sys/net/ipv4/tcp_fastopen 是最直接的临时方案:
- 启用客户端 + 服务端:
echo 3 > /proc/sys/net/ipv4/tcp_fastopen - 需要 root 权限,普通用户会提示
Permission denied - 该设置在重启后失效,适合测试或调试场景
- 注意:仅修改此值还不够 —— 应用层必须显式调用
setsockopt(..., IPPROTO_TCP, TCP_FASTOPEN, ...)才能真正触发 TFO 流程
例如 Nginx 1.11.5+ 默认在 listen 指令中加 fastopen=256 才会启用服务端 TFO;curl 7.49.0+ 需加 --tcp-fastopen 参数才启用客户端行为。
如何永久启用并避免常见配置错误
写入 /etc/sysctl.conf 是持久化方式,但容易漏掉关键点:
- 添加行:
net.ipv4.tcp_fastopen = 3,然后运行sysctl -p - 错误做法:只改
sysctl.conf却没执行sysctl -p,或执行后未验证cat /proc/sys/net/ipv4/tcp_fastopen是否真为 3 - 某些发行版(如 CentOS 7)的 systemd-sysctl 服务可能延迟加载,建议加
systemctl restart systemd-sysctl确保生效 - TFO 依赖 TCP Cookie,首次连接仍走三次握手;只有重复连接且 Cookie 有效时才跳过 SYN-ACK 往返 —— 所以压测前务必用同一 client IP 多连几次,否则看不出效果
为什么开了 TFO 却没看到性能提升
常见原因不是配置失败,而是应用或网络条件不满足 TFO 触发前提:
- 服务端未在 socket 上调用
setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen))(如旧版 Nginx、OpenSSL 应用未适配) - 客户端未在 connect 前设置
TCP_FASTOPEN或未用sendto(..., MSG_FASTOPEN)(glibc 2.23+ 才支持 MSG_FASTOPEN) - 中间存在不识别 TFO 的防火墙/NAT 设备,会丢弃带 TFO Cookie 的 SYN 包(现象是连接超时或回退到普通握手)
- 抓包看
tcpdump -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0',若 SYN 包里没有TFO字样或options [exp 34],说明根本没发出 TFO 请求
TFO 不是“开个开关就提速”的魔法,它只对短连接高频复用场景(如 HTTP/1.1 多请求、移动端 API 调用)有明显收益;长连接或 TLS 握手耗时远大于 TCP 握手时,优化感知很弱。










