TCP_MEM小导致下载慢或无法下载

事件起因

上周同事反馈测服本地cdn的文件很多加载失败,使用chrome浏览器查看发现有些文件加载正常,有些加载一半就提示“err content length mismatch”错误,不论使用浏览器、curl单独访问该文件都无法全部加载。
而nginx反向代理的错误日志显示后端服务器主动断开了连接。

1
2018/05/08 08:56:29 [error] 27#27: *225448 readv() failed (104: Connection reset by peer) while reading upstream, client: 47.xx.xx.43, server: cdn.xxx.com, request: "GET /home/css/img/area-214f1779.png HTTP/1.1", upstream: "http://xx.xx.xx.xx:80/home/css/img/area-214f1779.png", host: "cdn.xxx.com", referrer: "http://cdn.xxx.com/home/css/index-1.0.9.css"

由于没找到问题,就直接把cdn迁移到其它服务器暂时解决。
而后有一个新静态站点要上线,使用jenkins去github拉取代码的时候无法pull下来,直接在服务器git clone也是很慢,curl下载docker-compose直接没速度,而在其它服务器操作都正常。

排查过程使用工具

  • 使用ethstatus实时监控eth0网卡的流量,发现没动静。
    ethstatus -i eth0
    ethstatus
  • iptraf 实时查看端口流量
  • sar 查看倒是有流量信息
    sar -n DEV 1
    sar
  • speedtest_cli 测试网速,发现下载很慢,上传正常。
    speedtest
  • 使用tcpdump抓包给Azure工程师帮忙处理
    tcpdump -i eth0 -w server.pcap
  • netstat -i 查看丢包率
  • dropwatch 定位系统内核丢包
  • dmesg 发现是 TCP连接的内存不够
    TCP: out of memory -- consider tuning tcp_mem
    查看tcp_mem大小
    1
    2
    cat /proc/sys/net/ipv4/tcp_mem
    39513 5268 79026

查看目前服务器使用了多少内存页,发现 mem 超出了tcp_mem最大值79026

1
2
3
4
5
6
7
cat /proc/net/sockstat
sockets: used 8089
TCP: inuse 27 orphan 0 tw 94 alloc 1092 mem 79562
UDP: inuse 1 mem 2
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

修改tcp_mem最大值

1
2
echo "net.ipv4.tcp_mem = 39513 5268 88000" >> /etc/sysctl.conf
sysctl -p

调大tcp_mem的值后下载速度恢复正常。

一分、两分都是爱!