Linux系统网络性能检测和调优

Linux网络性能调优

网络监控命令
netstat

用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,核心是显示套接字状态

参数:-a 显示所有套接字 -n 不解析DNS名字(解析DNS会比较慢) -t 过滤出TCP相关的网络套接字 -p 显示进程/程序名 -s显示出协议栈中相关的一些统计信息
tips:现在常用ss替代
Linux系统网络性能检测和调优_第1张图片
在这里插入图片描述

ifconfig

用于显示或配置网络设备(网络接口卡)信息 (现用ip相关命令替代,包括 ip link ip address 等)
Linux系统网络性能检测和调优_第2张图片
Linux系统网络性能检测和调优_第3张图片
一些配置操作:

#启动或者关闭指定网卡
ifconfig eth0 down   
ifconfig eth0 up
#修改MAC地址
ifconfig eth0 down //关闭网卡
ifconfig eth0 hw ether MACaddress //修改MAC地址
ifconfig eth0 up //启动网卡
#配置IP地址
ifconfig eth0 $ipaddress netmask 255.255.255.0  // 给eth0网卡配置IP地址,并加上子掩码
#启用和关闭ARP协议
ifconfig eth0 arp  //开启
ifconfig eth0 -arp  //关闭
#设置最大传输单元
ifconfig eth0 mtu 1460 //设置能通过的最大数据包大小为 1460 bytes
route

用于显示和操作IP路由表,通过目标地址ip和子网掩码可以分析出发包路径 (现常用ip route替代) (补充:ip rule show显示路由策略表,调整路由策略表可以设置路由转发策略)
在这里插入图片描述
用ip命令查看和操作IP路由的一些信息:
Linux系统网络性能检测和调优_第4张图片
可以通过route去配置路由表:

route add -net 224.0.0.0 netmask 240.0.0.0 reject  #屏蔽一条路由
route del -net 224.0.0.0 netmask 240.0.0.0   #删除路由记录
route add default gw 192.168.120.240 #添加设置默认网关
sar

sar是一个优秀的一般性能监视工具,它可以输出Linux所完成的几乎所有工作的数据。sar命令在sysetat rpm中提供。 sar可以显示CPU、运行队列、磁盘I/O、分页(交换区)、内存、CPU中断、网络等性能数据 (详细介绍:sar详解)

sar -n DEV显示网络信息
Linux系统网络性能检测和调优_第5张图片

字段 说明
IFACE LAN接口
rxpck/s 每秒钟接收到的数据包
txpck/s 每秒钟发送出去的数据包
rxkB/s 每秒钟接收到的字节数
txkB/s 每秒钟发送出去的字节数
rxcmp/s 每秒钟接收到的压缩数据包
txcmp/s 每秒钟发送出去的压缩数据包
rxmcst/s 每秒钟接收到的多播数据包

用sar分析网络更多的是用于流量和包量的检测和异常发现。详细分析还是tcpdump+wireshark方便。

nmap

一个用于网络探测和安全审核的工具,需要自行安装(yum install nmap)

常用来:

  • 检测某个网段存活的主机
  • 网络故障时,快速探测 ping 不通的主机
  • 测试安全策略是否正常
    Linux系统网络性能检测和调优_第6张图片
nmap <target ip1 address> <target ip2 address> #快速扫描多个ip地址
nmap -p(range) <target IP>    #指定端口和范围
Socket的性能调优

性能相关socket options: SO_LINGER SO_RCVBUF SO_SNDBUF SO_REUSEPORT

SO_LINGER

SO_LINGER :指定函数close对面向连接的协议如何操作,内核缺省close操作是立即返回,如果有数据残留在套接口缓冲区中则系统将试着将这些数据发送给对方。

struct linger {
     int l_onoff; /* 0 = off, nozero = on */
     int l_linger; /* linger time */
};
  • 设置l_onoff为0,则关闭linger,close直接返回,未发送数据将由内核完成传输
  • 设置l_onoff为非0,l_linger为0,则打开linger,则立即关闭该连接,通过发送RST分组(而不是用正常的FIN|ACK|FIN|ACK四个分组)来关闭该连接。如果发送缓冲区中如果有未发送完的数据,则丢弃。主动关闭一方的TCP状态则跳过TIMEWAIT,直接进入CLOSED
  • 设置l_onoff为非0,l_linger为非0,将连接的关闭设置一个超时。如果socket发送缓冲区中仍残留数据,进程进入睡眠,内核进入定时状态去尽量去发送这些数据。在超时之前,如果所有数据都发送完且被对方确认,内核用正常的FIN|ACK|FIN|ACK四个分组来关闭该连接,close()成功返回。如果超时之时,数据仍然未能成功发送及被确认,用上述a方式来关闭此连接。close()返回EWOULDBLOCK

四次挥手断开连接主动关闭方会进入TIME_WAIT状态,TIME_WAIT状态非常多的话会导致系统负载较大(TIME_WAIT本身不占用资源,但是处理TIME_WAIT需要耗费资源),故可以通过设置打开linger则直接发送RST分组,这种情况不会产生TIME_WAIT。

(TIPS:TIME_WAIT状态太多,系统会进行回收和利用,因此,回收的是等待的时间最长的,故如果TIME_WAIT状态太多的话,就需要维护一个非常大的数据结构用来找等待时间最长的,会占据一定的系统计算资源)

对于TIME_WAIT过多也可以直接设置系统的最大TIME_WAIT数,将该数字调小一些。(会导致一些不太可靠的断开,不过对于减少服务器压力来说还是比较不错的方式,只是会令客户端断开连接更慢一些,客户端通常是一个主机,维持连接较少,一个较长的断开影响不大)

缓存大小

SO_RCVBUF 和 SO_SNDBUF:设置的是Socket缓存大小,缓存大小会影响套接字的的性能

SO_REUSEPORT 让多个进程使用一个端口,内核需要维护端口和进程的负载均衡

proc目录下的SOCKET缓存参数路径为:

/proc/sys/net/core/rmem_default
/proc/sys/net/core/rmem_max
/proc/sys/net/core/wmem_default
/proc/sys/net/core/wmem_max

调大缓存理论上是会提升Socket传输速率的,但是,并不是总是这样。缓存是一个只有在发送方和接收方的性能差异比较大时缓存会产生影响。还要补充的是,对于TCP连接而言,真正的传输过程是依赖于发送方和接收方两方的窗口大小的,因此单单调大发送方缓存并不会对整体产生明显影响。

在大延时网络上的带宽利用率低,主要原因是延时变大之后,发送方发的数据不能及时到达接收方。导致发送缓存满之后,不能再持续发送数据。接收方则因为TCP通告窗口受到接收方剩余缓存大小的影响。接收缓存小的话,则会通告对方发送窗口变小。进而影响发送方不能以大窗口发送数据。所以,这里的调优思路应该是,发送方调大tcp_wmem,接收方调大tcp_rmem。

如果网络的环境比较差,即丢包率比较高,那么会发现哪怕调高发送和接收双方的缓存大小,也无法提升整体的传输速率,主要原因是由于丢包比较高,因此网络比较拥塞,会频繁引发慢启动,使得真正的窗口瓶颈并不在于缓存的大小,甚至一直难以到达一个较大的值。这种情况下,可以考虑采用不同的拥塞控制算法,bbr算法对丢包不敏感,因此在这种情况下如果采用bbr拥塞控制算法将使得整个网络性能较高。如果网络的丢包很少延时很大,那么调整拥塞控制算法也不会由明显提升,此时主要瓶颈就是缓存。

为了提高网络的吞吐量,通常需要调整这些缓冲区的大小:

  • 增大每个套接字的缓冲区大小 net.core.optmem_max;
  • 增大套接字接收缓冲区大小 net.core.rmem_max 和发送缓冲区大小net.core.wmem_max;
  • 增大 TCP 接收缓冲区大小 net.ipv4.tcp_rmem 和发送缓冲区大小net.ipv4.tcp_wmem
backlog

TCP socket 服务的4个步骤 socket->bind->listen->accept

在调用listen函数时,有一个backlog参数.在Linux中backlog表示已完成(ESTABLISHED)且未accept的队列大小.

int listen(int sockfd, int backlog);

TCP建立连接过程:服务器收到客户端SYN包,发送SYN+ACK包后,在内存创建一个状态为SYN_RCVD 的连接,放入未完成队列,这个队列的大小可通过/proc/sys/net/ipv4/tcp_max_syn_backlog设置. 服务器收到客户端的ACK包后,该连接的状态由SYN_RCVD改为ESTABLISHED,并移到已完成队列.

服务器程序调用accept后,该连接移除已完成队列, 由内核交给程序控制.

(需要注意的是,在第二次握手完成后服务器已经将该连接放入了半连接队列,当第三次握手成功后放入了全连接队列,当accept进程被调用后,该连接被调走由内核管理)

backlog就是指定全连接队列的大小,如果全连接队列队列满了并且tcp_abort_on_overflow是0的话,server过一段时间再次发送syn+ack给client,如果client超时等待比较短,就会很容易导致异常。(tcp_abort_on_overflow 为0表示如果三次握手第三步的时候全连接队列满了那么server扔掉client 发过来的ack),因此如果backlog太小的话会导致全连接队列容易满,从而TCP连接建立失败。
Linux系统网络性能检测和调优_第7张图片
设置backlog后,系统会和/proc/sys/net/core/somaxconn比较,取较小值作为真正的backlog

当已连接队列满后,如果设置tcp_abort_on_overflow 为0表示如果三次握手第三步的时候全连接队列满了那么server扔掉client发过来的ack

当半连接队列满后,如果启用syncookies (net.ipv4.tcp_syncookies = 1),新的连接不进入未完成队列,不受影响.否则,服务器不在接受新的连接.

SYN 洪水攻击(syn flood attack)
通过伪造IP向服务器发送SYN包,塞满服务器的未完成队列,服务器发送SYN+ACK包 没回复,反复SYN+ACK包,使服务器不可用.启用syncookies 是简单有效的抵御措施.仅未完成队列满后才生效.
SYN 洪水攻击导致被攻击服务器保持大量SYN_RECV状态的“半连接”,并且会重试默认5次回应第二个握手包,塞满TCP等待连接队列,资源耗尽(CPU满负荷或内存不足),让正常的业务请求连接不进来

others

套接字接口还提供了一些配置选项,用来修改网络连接的行为。

  • 为 TCP 连接设置 TCP_NODELAY 后,就可以禁用 Nagle 算法;
  • 为 TCP 连接开启 TCP_CORK 后,可以让小包聚合成大包后再发送(注意会阻塞小包的发送);
  • 使用 SO_SNDBUF 和 SO_RCVBUF ,可以分别调整套接字发送缓冲区和接收缓冲区的大小。
应用程序优化

从网络 I/O 的角度来说,有如下思路:

  • I/O 多路复用技术 epoll,主要用来取代 select 和 poll,是目前很多网络应用默认使用的机制。
  • 异步 I/O技术。异步IO允许应用程序同时发起很多I/O 操作,而不用等待这些操作完成。等到 I/O 完成后,系统会用事件通知的方式,告诉应用程序结果。

从进程的工作模型来说,有如下思路:

  • 主进程 + 多个 worker 子进程。其中,主进程负责管理网络连接,而子进程负责实际的业务处理。
  • 监听到相同端口的多进程模型(负载均衡)。在这种模型下,所有进程都会监听相同接口,并且开启 SO_REUSEPORT 选项,由内核负责,把请求负载均衡到这些监听进程中去。

应用层的网络协议优化思路:

  • 使用长连接取代短连接,可以显著降低 TCP 建立连接的成本。在每秒请求次数较多时,这样做的效果非常明显。
  • 使用内存等方式,来缓存不常变化的数据,可以降低网络 I/O 次数,同时加快应用程序的响应速度。
  • 使用 Protocol Buffer 等序列化的方式,压缩网络 I/O 的数据量,可以提高应用程序的吞吐。
    负载均衡到这些监听进程中去。

应用层的网络协议优化思路:

  • 使用长连接取代短连接,可以显著降低 TCP 建立连接的成本。在每秒请求次数较多时,这样做的效果非常明显。
  • 使用内存等方式,来缓存不常变化的数据,可以降低网络 I/O 次数,同时加快应用程序的响应速度。
  • 使用 Protocol Buffer 等序列化的方式,压缩网络 I/O 的数据量,可以提高应用程序的吞吐。
  • 使用 DNS 缓存、预取、HTTPDNS 等方式,减少 DNS 解析的延迟,也可以提升网络I/O 的整体速度。

你可能感兴趣的:(Linux,计算机网络)