一、背景
同事反馈浏览器访问线上服务会出现端口不通的问题,且很容易复现。
刚开始以为是nginx配置的问题,也对nginx做了配置回滚,发现并没有解决;而且其他服务的端口也会出现这个问题,非常奇怪。
二、排查过程
先检查nginx的配置,检查后发现无异常,程序无报错信息。通过 telnet 此代理的其他端口,也会出现端口访问不通的问题。所以先排除nginx配置问题,怀疑此机器系统是否有问题。但是通过其他客户端(centos7,windows 10)访问又是正常的。怀疑macOS客户端和nginx机器的内核参数有什么关联。通过排查发现,此机器的内核参数配置了以下参数:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
当把net.ipv4.tcp_tw_recycle 的值改为0之后,macOS访问正常了。排查下来服务端开启了timestamp和recycle之后,SYN包走到内核层之后会被校验SYN包的timestamp,在60s内,SYN包的timestamp如果不是递增,就会直接被丢弃。从抓包看,SYN包的timestamp一会大一会小,触发了drop的逻辑,跟客户端的net.inet.tcp.randomize_timestamps(随机生成时间戳)参数有关。 mac客户端关闭随机时间戳和sack之后,访问就正常了
sudo sysctl -w net.inet.tcp.randomize_timestamps=0
sudo sysctl -w net.inet.tcp.sack=0
当然了,办公室一堆mac用户让他们改内核参数有点难度,直接改掉net.ipv4.tcp_tw_recycle = 0,代价是time_wait数量会增加不少。