
ssl_buffer_size 控制的是 TLS 记录层中单个明文 record 的最大长度,它不改变握手流程,也不直接决定 TCP 包大小,但深刻影响“握手完成→首字节发出”这一关键窗口。调对了,TTFB 可降 30–50ms;调错了,小响应被卡在缓冲区,反而增加 record 数量、TLS 加解密开销,甚至触发延迟 ACK。
它真正控制什么
这个参数设定的是加密前的应用数据块上限,不是最终网络包尺寸。一个 TLS record 包含:5 字节记录头 + 明文数据(≤ ssl_buffer_size)+ MAC 和填充。Nginx 在生成 HTTP 响应时,会按此大小切分明文,再逐段加密封装。
- 设为 1400:800 字节的 JSON 响应可立即封装发送,首 record 很快抵达客户端
- 设为 4096:同样响应可能等待缓冲填满或响应结束才发,首字节多等几十甚至上百毫秒
- 它不绕过 tcp_nopush 或 tcp_nodelay —— 若启用了 tcp_nopush,Nginx 仍会尝试凑够 MSS 再发包,此时单独调小 ssl_buffer_size 效果受限
怎么选值:看首响应体大小和路径 MSS
别套通用数字,先确认你服务最常返回的“首个有效载荷”有多大(比如 HTML head、API 状态响应、HTTP/2 首帧),再匹配链路实际能承载的 TCP 数据长度。
- 轻量 API / 移动端接口(首响应 ≤ 1KB):用 1024 或 1400。1400 兼容多数以太网路径(MSS=1460),留出 TLS 头与填充余量
- 常规网页(首 HTML 含内联资源,约 1.5–2.5KB):2048 是较稳选择,避免 record 过多又不让首包明显延迟
- 大文件下载 / 视频流:保持 4096 或更高(如 8K、16K),吞吐优先,首包不敏感
- 不确定链路 MTU(如经运营商 NAT、IPv6 隧道):先用 ping -M do -s 1472 example.com 测可达 MTU,再减去 28 得到可用 MSS,ssl_buffer_size 设为该值 − 40 左右
必须同步开启的三项配置
ssl_buffer_size 单独调整几乎无效。它的收益依赖传输层与协议栈协同:
- tcp_nodelay on;:禁用 Nagle 算法,确保小 TLS record 到达 TCP 层后立即发出,不等待合并
- ssl_protocols TLSv1.3;:TLS 1.3 默认 1-RTT 握手,首包逻辑更干净;若需兼容旧客户端,至少禁用 TLSv1 和 TLSv1.1
- ssl_stapling on; ssl_stapling_verify on;:启用 OCSP Stapling,避免客户端因证书状态查询而阻塞首包
验证是否真的生效
别只信 curl -w "%{time_starttransfer}",那只是端到端结果。要确认行为是否改变,得看真实链路:
- 用 Wireshark 抓 Nginx 出口流量,过滤 tls.record.content_type == 23 && frame.number == N(N 为握手完成后第一个 Application Data 包),检查 Length 字段是否稳定落在你设定值 ±50 字节内
- 重点观察 TLS Finished 后的下一个 TCP 包是否就携带了 HTTP/1.1 200 OK 或 HTTP/2 HEADERS 帧
- 在真实弱网环境(如用 tc 模拟 200ms RTT + 2% 丢包)下跑 10 轮 curl 测试,对比中位数变化;下降 ≥30ms 才算有效











