压测到三千并发开始丢请求,nstat 里 TcpExtListenOverflows 和 ListenDrops 持续上涨,netstat -s 报 listen queue overflow,加机器也没有明显改善,问题在单机的队列长度,直觉都会指向带宽。乍看像缓存或者权限的锅,追下去往往不是。
nstat -az | grep -i listen ss -lnt | head sysctl net.core.somaxconn sudo sysctl -w net.core.somaxconn=4096
追下去是这么回事:应用传入的 backlog 和内核 somaxconn 取较小值生效,accept 速度跟不上握手速度,队列满了内核直接丢包,客户端只看到超时重试,看着像网络问题。
碰到「somaxconn 队列溢出」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
具体做法是,用 nstat 看 ListenOverflows 是否随并发持续增长 先确认是队列丢的 不是后端慢;ss 的 Send-Q 列就是该 socket 当前的队列上限值 和 somaxconn 对照着看 一眼能看出来;应用 backlog 与 somaxconn 一起调大再重新压测 只调一侧常常没有效果。
验收就看一点,再压一轮 ListenOverflows 不再增长 超时率降到千分之一以内 P99 也跟着下来 观察一天。
