【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟、丢包优化

【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟优化

【1】网络延迟优化

网络时延的测试方法

hping3 命令

安装
sudo apt-get install hping3

hping3 命令,测试与百度的延迟
# -c表示发送3次请求,-S表示设置TCP SYN,-p表示端口号为80
$ hping3 -c 3 -S -p 80 baidu.com

【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟、丢包优化

traceroute 命令

安装
sudo apt-get install traceroute

traceroute 命令,测试与百度的延迟
# --tcp表示使用TCP协议,-p表示端口号,-n表示不对结果中的IP地址执行反向域名解析
$ traceroute --tcp -p 80 -n baidu.com

【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟、丢包优化

traceroute 会在路由的每一跳发送三个包,并在收到响应后,输出往返延时;如果无响应或者响应超时(默认 5s),就会输出一个星号;

【2】网络丢包优化

丢包指在网络数据的收发过程中,数据包还没传输到应用程序中,就被丢弃的现象;被丢弃包的数量,除以总的传输包数,即丢包率,丢包率是网络性能中最核心的指标之一;

丢包通常会带来严重的性能下降,对于 TCP 丢包通常意味着网络拥塞和重传,进而还会导致网络延迟增大、吞吐降低;

丢包在网络传输中出现的位置

【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟、丢包优化

  • 在两台计算机连接之间,可能会发生传输失败的错误,比如网络拥塞、线路错误等;
  • 在网卡收包后,环形缓冲区可能会因为溢出而丢包;
  • 在链路层,可能会因为网络帧校验失败、QoS 等而丢包;
  • 在 IP 层,可能会因为路由失败、组包大小超过 MTU 等而丢包;
  • 在传输层,可能会因为端口未监听、资源占用超过内核限制等而丢包;
  • 在套接字层,可能会因为套接字缓冲区溢出而丢包;
  • 在应用层,可能会因为应用程序异常而丢包;
  • 若配置了 iptables 规则,网络包可能因为 iptables 过滤规则而丢包;

【2.1】链路层丢包排查

netstat 命令 -- 检查网卡丢包

命令
netstat -i

【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟、丢包优化

  • RX-OK、RX-ERR、RX-DRP、RX-OVR,分别表示接收时的总包数、总错误数、进入 Ring Buffer 后因其他原因导致的丢包数、Ring Buffer 溢出导致的丢包数;
  • TX-OK、TX-ERR、TX-DRP、TX-OVR,分别表示发送时的总包数、总错误数、进入 Ring Buffer 后因其他原因导致的丢包数、Ring Buffer 溢出导致的丢包数;
  • Flg 标志
    • B  已经设置了一个广播地址
    • L 该接口是一个回送设备
    • M 接收所有的数据包(混乱模式)
    • N 避免跟踪
    • O 在该接口上,禁用ARP
    • P 这是一个点到点连接
    • R 接口正在运行
    • U 接口处于"活动"状态

tc 命令 -- 检查网卡是否配置 tc 规则

命令
tc -s qdisc show dev eno1

结果
qdisc netem 800d: root refcnt 2 limit 1000 loss 30%
 Sent 432 bytes 8 pkt (dropped 4, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0

说明
eno1 上面配置了一个网络模拟排队规则 (qdisc netem),并且配置了丢包率为 30% (loss 30%)

解决
删除 netem 模块
tc qdisc del dev eth0 root netem loss 30%

【2.2】网络层和传输层丢包排查

netstat 命令 -- 协议收发汇总

命令
netstat -s

Ip:
    Forwarding: 1
    214542146 total packets received
    18 with invalid addresses
    48 forwarded
    0 incoming packets discarded
    212587679 incoming packets delivered
    36781261 requests sent out
    2 outgoing packets dropped
    1225 fragments dropped after timeout
    1998956 reassemblies required
    47570 packets reassembled ok
    1711123 packet reassemblies failed
Icmp:
    2514 ICMP messages received
    37 input ICMP message failed
    InCsumErrors: 10
    ICMP input histogram:
        destination unreachable: 2450
        timeout in transit: 21
        echo requests: 2
        echo replies: 31
    5708 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 5661
        time exceeded: 14
        echo requests: 31
        echo replies: 2
IcmpMsg:
        InType0: 31
        InType3: 2450
        InType8: 2
        InType11: 21
        OutType0: 2
        OutType3: 5661
        OutType8: 31
        OutType11: 14
Tcp:
    31920 active connection openings
    429 passive connection openings
    523 failed connection attempts
    1142 connection resets received
    12 connections established
    39259016 segments received
    37353339 segments sent out
    58952 segments retransmitted
    1219 bad segments received
    4328 resets sent
Udp:
    173996859 packets received
    3395 packets to unknown port received
    331 packet receive errors
    3861501 packets sent
    331 receive buffer errors
    0 send buffer errors
    IgnoredMulti: 330293
UdpLite:
TcpExt:
    6 resets received for embryonic SYN_RECV sockets
    2 packets pruned from receive queue because of socket buffer overrun
    12 ICMP packets dropped because they were out-of-window
    1513 TCP sockets finished time wait in fast timer
    18192 delayed acks sent
    37 delayed acks further delayed because of locked socket
    Quick ack mode was activated 8112 times
    15792151 packet headers predicted
    371218 acknowledgments not containing data payload received
    10607302 predicted acknowledgments
    TCPSackRecovery: 698
    Detected reordering 63 times using SACK
    4 congestion windows fully recovered without slow start
    TCPDSACKUndo: 13
    1 congestion windows recovered without slow start after partial ack
    TCPLostRetransmit: 41764
    TCPSackFailures: 1
    1034 fast retransmits
    TCPTimeouts: 55061
    TCPLossProbes: 3347
    TCPLossProbeRecovery: 1104
    TCPBacklogCoalesce: 26750
    TCPDSACKOldSent: 8113
    TCPDSACKRecv: 168
    361 connections reset due to unexpected data
    1017 connections reset due to early user close
    448 connections aborted due to timeout
    TCPDSACKIgnoredOld: 11
    TCPDSACKIgnoredNoUndo: 73
    TCPSackShifted: 43
    TCPSackMerged: 23
    TCPSackShiftFallback: 789
    IPReversePathFilter: 14
    TCPRcvCoalesce: 8922712
    TCPOFOQueue: 18762
    TCPChallengeACK: 1222
    TCPSYNChallenge: 1222
    TCPSpuriousRtxHostQueues: 5
    TCPAutoCorking: 151958
    TCPFromZeroWindowAdv: 109
    TCPToZeroWindowAdv: 109
    TCPWantZeroWindowAdv: 276
    TCPSynRetrans: 51463
    TCPOrigDataSent: 20657582
    TCPHystartTrainDetect: 11
    TCPHystartTrainCwnd: 234
    TCPACKSkippedSeq: 7
    TCPKeepAlive: 5876
    TCPDelivered: 20677380
    TCPAckCompressed: 2975
IpExt:
    InMcastPkts: 230863
    OutMcastPkts: 20820
    InBcastPkts: 515761
    OutBcastPkts: 8857
    InOctets: 275473275063
    OutOctets: 13751580722
    InMcastOctets: 53599231
    OutMcastOctets: 3798519
    InBcastOctets: 139501761
    OutBcastOctets: 1488411
    InNoECTPkts: 287914633

iptables

连接跟踪数查询

# 主机终端中查询内核配置
$ sysctl net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_max = 262144
$ sysctl net.netfilter.nf_conntrack_count
net.netfilter.nf_conntrack_count = 41

查看 iptable 的过滤规则

命令
sudo iptables -t filter -nvL

结果
Chain INPUT (policy ACCEPT 213M packets, 274G bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
    0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:67
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:67

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   48  3972 DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
   48  3972 DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
   24  2460 ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
   24  1512 ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  *      virbr0  0.0.0.0/0            192.168.122.0/24     ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  virbr0 *       192.168.122.0/24     0.0.0.0/0           
    0     0 ACCEPT     all  --  virbr0 virbr0  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT 37M packets, 14G bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  *      virbr0  0.0.0.0/0            0.0.0.0/0            udp dpt:68

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
   24  1512 DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
   48  3972 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
   24  1512 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
   48  3972 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

解决方案
删除 iptables 的 DROP 规则
iptables -t filter -D INPUT -m statistic --mode random --probability 0.30 -j DROP
iptables -t filter -D OUTPUT -m statistic --mode random --probability 0.30 -j DROP

附录

【1】iptables 知识点补充

【1.1】iptables 概念简介

netfilter/iptables 为 Linux 平台下的包过滤防火墙,可以完成封包过滤、封包重定向、网络地址转换 (NAT) 等功能;
iptables 和 netfilter 的关系

  • iptables 是 Linux 防火墙的管理工具,位于 /sbin/iptables;
  • netfilter 是 Linux 内核中实现包过滤的内部结构;

iptables 传输数据包的过程

【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟、丢包优化

iptables 的规则表和链

  • 表 (tables) 提供特定的功能,iptables 内置了 4 个表,即 filter 表、nat 表、mangle 表和 raw 表,分别用于实现包过滤、网络地址转换、包重构 (修改) 和数据跟踪处理;
  • 链 (chains) 是数据包传播的路径,每一条链是众多规则中的一个检查清单,每一条链中可以有一 条或数条规则;当一个数据包到达一个链时,iptables 就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件;如果满足,系统就会根据 该条规则所定义的方法处理该数据包;否则 iptables 将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables 就会根据该链预先定义的默认策略来处理数据包;
    • 规则表
      • 1. filter 表 —— 三个链,INPUT、FORWARD、OUTPUT
        • 作用 : 过滤数据包
        • 内核模块 : iptables_filter
      • 2. Nat 表 —— 三个链,PREROUTING、POSTROUTING、OUTPUT
        • 作用 : 用于网络地址转换 (IP、端口)
        • 内核模块 : iptable_nat
      • 3. Mangle 表 —— 五个链,PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
        • 作用 : 修改数据包的服务类型、TTL、并且可以配置路由实现 QoS 
        • 内核模块 : iptable_mangle
      • 4. Raw 表 —— 两个链,OUTPUT、PREROUTING
        • 作用 : 决定数据包是否被状态跟踪机制处理
        • 内核模块 : iptable_raw
      • 规则表之间的优先顺序 : Raw —— mangle —— nat —— filter
    • 规则链
      • 1. INPUT —— 进来的数据包应用此规则链中的策略
      • 2. OUTPUT —— 外出的数据包应用此规则链中的策略
      • 3. FORWARD —— 转发数据包时应用此规则链中的策略
      • 4. PREROUTING —— 对数据包作路由选择前应用此链中的规则
      • 5. POSTROUTING —— 对数据包作路由选择后应用此链中的规则

【1.2】iptables 命令

命令格式

iptables [-t 表名] 命令选项[链名][条件匹配][-j 目标动作或跳转]

【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟、丢包优化

【Linux 性能优化系列】Linux 性能优化 -- 网络性能篇(四) 网络延迟、丢包优化

命令选项

  • -A 在指定链的末尾添加 (append) 一条新的规则
  • -D 删除 (delete) 指定链中的某一条规则,可以按规则序号和内容删除
  • -I 在指定链中插入 (insert) 一条新的规则,默认在第一行添加
  • -R 修改、替换 (replace) 指定链中的某一条规则,可以按规则序号和内容替换
  • -L 列出 (list) 指定链中所有的规则进行查看
  • -E 重命名用户定义的链,不改变链本身
  • -F 清空 (flush)
  • -N 新建 (new-chain) 一条用户自己定义的规则链
  • -X 删除指定表中用户自定义的规则链 (delete-chain)
  • -P 设置指定链的默认策略 (policy)
  • -Z 将所有表的所有链的字节和数据包计数器清零
  • -n 使用数字形式 (numeric) 显示输出结果
  • -v 查看规则表详细信息 (verbose) 的信息
  • -V 查看版本 (version)
  • -h 获取帮助 (help)

参考致谢

本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。

【1】极客时间 -- Linux 性能优化实战

【2】netstat -i和-s

【3】iptables详解(图文)

上一篇:el-upload上传组件accept属性限制文件类型(案例详解)


下一篇:Phpmyadmin 2.X 反序列化漏洞(WooYun-2016-199433)