使用ip命令查看网状态。ifconfig命令已多年不再更新,从CentOS7开始,发行版的mini系统已不再自带ifconfig工具,取而代之的是ip命令。

其实质是iproute2套件取代了net-tools套件,ifconfig便是后者中一个工具。两者的简单对比,从网上找到张图:

iproute2 vs net-tools

查看网卡统计数据

使用ip -s link查看link的统计数据:

网卡状态

以上各个统计指标的含义为:

指标 含义
errors 网线损坏或者网卡协商模式错误或者速率不匹配导致的错误。
dropped iptables或者其他规则或者内核读取网卡数据的buffer满导致的丢包。
overrun 网卡的驱动buffer满导致的overruns。
carrier 网线接触不良或者网线损坏或者交换机故障。
collsns 一般而言是0。若非零,代表双工模式的协商问题。若数值很小且不再增长,代表只是刚接入的时候故障,现已正常。

网卡buffer

网卡buffer设置

上篇已提到,在网卡统计中出现overruns时,需要确定是否是由于网卡buffer设置不当导致的。使用ethtool -g eth0查看当前设置,具体查看上篇

网卡buffer查看

值得说明的是,此处的数值大小并不是代表可以缓冲多大的数据,而是指可以缓冲的数据帧(frame)的数量。

网卡buffer工作原理

网卡buffer会采用环形缓冲(ring buffer)的形式,其也是FIFO的一种实现方式,设计非常简单,也比较稳定,在较为底层的数据传输中使用广泛。其工作原理大致如下图所示,具体可以查看wiki

ring buffer工作原理

其他注意事项

有两个需要注意的地方:

buffer设置

使用ethtool -G eth0 rx 256设置接收buffer后,NIC会有个down/up的操作,会出现瞬时的断网,在网卡吞吐量较大时,副作用明显。

另外每次系统重启之后,该设置会失效,需要将该设置命令写入开机启动脚本/etc/rc.local中。

延迟

网卡的buffer并不是越多越好,在接入带宽较低的情况下,设置很大的带宽导致数据包传输的延迟。

如在1Mbps接入带宽,MTU=1500字节的情况下,设置tx buffer=256帧。假设每个包刚好都是1500字节,则填充满buffer需要1500*256=384,000字节,也就是3,072,000比特。1Mbps每秒最多传输1024*1024=1,048,000比特的数据,当最新的一个包进入到buffer的时候,需要3s才能发送出去,会造成3s的数据延迟。

在有巨型帧(Jumbo Frame)时,每个帧长度更长,导致需要更多的时间充满buffer,延迟更久。

内核参数

以上所说的buffer均指的是网卡及其驱动程序所使用的buffer,另外还有个内核使用的buffer,用以从网卡读取数据帧所用,在内核参数中设置。

BQL

此处有个概念叫starvation,中文有翻译成饿死,即网卡从ring buffer读取数据的时候,buffer中没有数据,次时设备空转一次,造成浪费,称为starvation。避免starvation是个十分复杂的问题,一个有效的办法便是增大ring buffer的长度,使得内核可以存放跟多的数据到队列中,减少starvation产生的概率。

但是增大ring buffer长度可能会导致上节中描述的发包延迟现象,因此出现了BQL

3.3.0内核之后,linux 内核自身会通过字节队列限制(Byte Queue Limits,BQL)自动调整数据包排队的数量,以避免在ring buffer中排队的数据包太多导致的发送延迟。实质上是在IP栈和drive queue之间加了一层,对进入drive queue的数据进行调度,避免队列满而导致延迟,同时也减少buffer长度。

这边有些相关资料,留作备份,暂时看不懂,也没需求,先不看了。

https://www.linuxplumbersconf.org/2012/wp-content/uploads/2012/08/bql_slide.pdf

http://www.linuxplumbersconf.org/2011/ocw/sessions/171

/proc/sys/net

IP栈允许到ring buffer排队的数据包数量可以在proc/sys/net/core/netdev_max_backlog中设置。另外在/proc/sys/net/etc/sysctl.conf中有很多网络相关的内核参数,具体可以参考这篇博文

参数(路径+文件) 描述 默认值 优化值
/proc/sys/net/core/rmem_default 默认的TCP数据接收窗口大小(字节)。 229376 256960
/proc/sys/net/core/rmem_max 最大的TCP数据接收窗口(字节)。 131071 513920
/proc/sys/net/core/wmem_default 默认的TCP数据发送窗口大小(字节)。 229376 256960
/proc/sys/net/core/wmem_max 最大的TCP数据发送窗口(字节)。 131071 513920
/proc/sys/net/core/netdev_max_backlog 在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。 1000 2000
/proc/sys/net/core/somaxconn 定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数。 128 2048
/proc/sys/net/core/optmem_max 表示每个套接字所允许的最大缓冲区的大小。 20480 81920
/proc/sys/net/ipv4/tcp_mem 确定TCP栈应该如何反映内存使用,每个值的单位都是内存页(通常是4KB)。第一个值是内存使用的下限;第二个值是内存压力模式开始对缓冲区使用应用压力的上限;第三个值是内存使用的上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的BDP可以增大这些值(注意,其单位是内存页而不是字节)。 94011 125351 188022 131072 262144 524288
/proc/sys/net/ipv4/tcp_rmem 为自动调优定义socket使用的内存。第一个值是为socket接收缓冲区分配的最少字节数;第二个值是默认值(该值会被rmem_default覆盖),缓冲区在系统负载不重的情况下可以增长到这个值;第三个值是接收缓冲区空间的最大字节数(该值会被rmem_max覆盖)。 4096 87380 4011232 8760 256960 4088000
/proc/sys/net/ipv4/tcp_wmem 为自动调优定义socket使用的内存。第一个值是为socket发送缓冲区分配的最少字节数;第二个值是默认值(该值会被wmem_default覆盖),缓冲区在系统负载不重的情况下可以增长到这个值;第三个值是发送缓冲区空间的最大字节数(该值会被wmem_max覆盖)。 4096 16384 4011232 8760 256960 4088000
/proc/sys/net/ipv4/tcp_keepalive_time TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。 7200 1800
/proc/sys/net/ipv4/tcp_keepalive_intvl 探测消息未获得响应时,重发该消息的间隔时间(秒)。 75 30
/proc/sys/net/ipv4/tcp_keepalive_probes 在认定TCP连接失效之前,最多发送多少个keepalive探测消息。 9 3
/proc/sys/net/ipv4/tcp_sack 启用有选择的应答(1表示启用),通过有选择地应答乱序接收到的报文来提高性能,让发送者只发送丢失的报文段,(对于广域网通信来说)这个选项应该启用,但是会增加对CPU的占用。 1 1
/proc/sys/net/ipv4/tcp_fack 启用转发应答,可以进行有选择应答(SACK)从而减少拥塞情况的发生,这个选项也应该启用。 1 1
/proc/sys/net/ipv4/tcp_timestamps TCP时间戳(会在TCP包头增加12个字节),以一种比重发超时更精确的方法(参考RFC 1323)来启用对RTT 的计算,为实现更好的性能应该启用这个选项。 1 1
/proc/sys/net/ipv4/tcp_window_scaling 启用RFC 1323定义的window scaling,要支持超过64KB的TCP窗口,必须启用该值(1表示启用),TCP窗口最大至1GB,TCP连接双方都启用时才生效。 1 1
/proc/sys/net/ipv4/tcp_syncookies 表示是否打开TCP同步标签(syncookie),内核必须打开了CONFIG_SYN_COOKIES项进行编译,同步标签可以防止一个套接字在有过多试图连接到达时引起过载。 1 1
/proc/sys/net/ipv4/tcp_tw_reuse 表示是否允许将处于TIME-WAIT状态的socket(TIME-WAIT的端口)用于新的TCP连接 。 0 1
/proc/sys/net/ipv4/tcp_tw_recycle 能够更快地回收TIME-WAIT套接字。 0 1
/proc/sys/net/ipv4/tcp_fin_timeout 对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间(秒)。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。 60 30
/proc/sys/net/ipv4/ip_local_port_range 表示TCP/UDP协议允许使用的本地端口号 32768 61000 1024 65000
/proc/sys/net/ipv4/tcp_max_syn_backlog 对于还未获得对方确认的连接请求,可保存在队列中的最大数目。如果服务器经常出现过载,可以尝试增加这个数字。 2048 2048
/proc/sys/net/ipv4/tcp_low_latency 允许TCP/IP栈适应在高吞吐量情况下低延时的情况,这个选项应该禁用。 0
/proc/sys/net/ipv4/tcp_westwood 启用发送者端的拥塞控制算法,它可以维护对吞吐量的评估,并试图对带宽的整体利用情况进行优化,对于WAN 通信来说应该启用这个选项。 0
/proc/sys/net/ipv4/tcp_bic 为快速长距离网络启用Binary Increase Congestion,这样可以更好地利用以GB速度进行操作的链接,对于WAN通信应该启用这个选项。 1 1

参考资料

QUEUEING IN THE LINUX NETWORK STACK

这边文章包罗了很多内容,非常值得细度。