最后更新:2022-06-19 17:18:28 手机定位技术交流文章
我们一般知道OSI的网络参考模型分为七层:应用层,即传输网络数据的表。表示层,会话层,传输层,网络层,数据链路层,物理层。实际的Linux网络层协议指的是OSI标准,但它被实现在四个层次上:应用层,传输层,网络层,网络接口层。多层OSI与实际实现的层相符.我们的主要关注是传输层和网络层。一般来说,网络层是IP层,负责IP路由地址和其他细节,传输层TCP/UDP负责可靠/快速的数据传输功能。

网络的实际运行过程是发送者,从高层向底层,根据协议,数据是层层填充的,每个层都附有层协议的头部;以及接收器,从底层向高层,不断的解封数据包,删除每个层的协议的标题,然后最高应用程序层获取应用程序层数据:

每个层的附加字符(TCP/UDP字符、IP字符、数据链接字符)是必须存在才能实现层的协议服务的协议相关数据。
2. Socket Buffer
发生方发送数据,接收方接受数据,因此,双方都必须有一个缓冲器来存储数据,它叫做索克缓冲器。TCP/IP实现都在内核中,因此插座缓冲器也位于内核中。插座缓冲器的大小配置对网络性能有很大影响,相关参数如下:
1)/proc/sys/net/ipv4/tcp_mem:这是全系统参数,显示所有TCP的缓冲配置。有三个值,单元是内存页(通常是4K),第一个值缓冲值的最低限度,第二值表示内存压力模式开始限制缓冲器应承受的压力量;第三值表示使用内存量,超过时,可能会丢弃报文。
2)/proc/sys/net/ipv4/tcp_rmen: r 表示接收,也有三个值,第一个值是TCP接收机接收的最小字节数;第二个值是默认值(这个值将被rmem_default覆盖);第三值是TCP接收机接收的最小字节数(这个值将被rmem_max覆盖);
3)/proc/sys/net/ipv4/tcp_wmem: w意思是写,也就是send。也有三个值,第一个值是TCP发送缓冲区的最小字节数;第二个值是默认值(这个值将被wmem_default覆盖);第三值是TCP发送缓冲区的最小字节数(这个值将被wmem_max覆盖);
4)/proc/sys/net/core/wmem_default:TCP数据发送窗口的默认字节数;
5)/proc/sys/net/core/wmem_max:TCP数据发送窗口的最大字节数;
6)/proc/sys/net/core/rmem_default:TCP数据接收窗口的默认字节数;
7)/proc/sys/net/core/rmem_max:TCP数据接收窗口的最大字节数;
注:除了tcp_mem单元作为存储页之外,其他几个单元是字节;而tcp_mem是一个全球配置,其他几个单元是每个TCP连接的配置参数。
3.网络API,较新的网络API
NAPI被引入以解决网络对CPU的影响。
Every time an Ethernet frame with a matching MAC address arrives at the interface, there will be a hard interrupt. Whenever a CPU has to handle a hard interrupt, it has to stop processing whatever it was working on and handle the interrupt, causing a context switch and the associated flush of the processor cache. While you might think that this is not a problem if only a few packets arrive at the interface, Gigabit Ethernet and modern applications can create thousands of packets per second, causing a large number of interrupts and context switches to occur.
Because of this, NAPI was introduced to counter the overhead associated with processing network traffic. For the first packet, NAPI works just like the traditional implementation as it issues an interrupt for the first packet. But after the first packet, the interface goes into a polling mode. As long as there are packets in the DMA ring buffer of the network interface, no new interrupts will be caused, effectively reducing context switching and the associated overhead.
可以看到,NAPI能够有效地减少因网络中断而导致的CPU上下文交换的数量,并减少由此产生的CPU性能损失。
4. Netfilter
Linux内核的防火墙实现模块,即我们使用呼叫iptables的功能。 提供数据包过滤和地址转换功能。
5.三个TCP/IP握手建立连接,四个握手终止连接

5.1建立联系的三个手:
1)第一次握手:当连接建立时,客户端A将SYN包(SYN=j)发送到服务器B,并输入SYN_SEND状态,等待服务器B确认。
2)第二次握手:服务器B接收了SYN包,而ACK包必须出现以确认客户端A的SYN(ACK=j+1),同时发送给自己SYN包(SYN=k),即SYN+ACK包,在该点服务器B输入SYN_RECV状态。
3)第三个握手:A客户端从B服务器接收SYN+ACK包,发送确认包ACK到服务器B(ACK=k+1),此包发送完毕,客户端A和服务器B输入“调用”状态,完成三个握手(注:主动打开器的最后的ACK包可能带有它想向服务端发送的数据。
摘要:三手实际上是主动开关,发送SYN,指示建立连接,然后被动开关确认,表示是,然后主动接收确认,然后确认确认;
5.2解开连接的四个波:
由于TCP连接是完全双向的,每个方向必须单独关闭,并且两个TCP必须互相发送一个FI包,并互相确认。 根据两个FI包的发送和确认,四个波可以分为两个阶段:
第一阶段: 主要是主动关闭侧发生 FIN, 被动侧确认;
1)第一波:在主动关闭方面,客户端在发送数据后向服务器发送 FIN(M)包并输入 FIN_WAIT1状态;
被动关闭服务器在接收 FIN(M)后进入CLOSE_WAIT状态;
2)第二波:Fin(M)确认包ACK(M+1)在服务端出现,关闭服务器读信频道,输入LAST_ACK状态;客户端接收ACK(M+1),关闭客户端写信频道,
输入 FIN_WATI2状态;客户端仍可通过读取通道读取服务器的数据,服务器仍可通过读取通道写入数据。
第二阶段: 主要发生被动关闭, 最后, 主动确认;
3)第三波:服务器向客户端发送数据并发送 FIN(N)包,状态保持不变或LAST_ACK;客户端接收 FIN(N)并输入 TIME_WAIT状态
4)第四波:客户端将ACK(N+1)确认返回 FIN(N)并关闭客户端读取通道(或 TIME_WAIT状态);
接收ACK(N+1)后,服务器关闭写信通道并输入CLOSED状态。
总结:
四波的本质是:
数据发生后主动关闭Fin出现,表示我们的数据发生,切断连接,并被动确认;
然后在数据发生完成后,会发生被动关闭。最后,意思是我们的数据发生完成,切断连接,而主动确认了这一点;
5.3CLOSE_WAIT状态的原因和处理:
通过振动上面的TCP将连接破裂四次的过程,众所周知,CLOSE_WAIT是在Fin发生之后的主动关闭。被动接收 FIN 并输入CLOSE_WAIT状态。此时,如果被动方不调用关闭()函数关闭TCP连接,然后被动服务器将留在CLOSE_WAIT状态(等待调用关闭函数);
所以有许多CLOSE_WAIT状态有两个原因:
1)代码没有写代码关闭连接,即程序有一个错误;
2)连接的业务代码处理时间太长,代码还在处理,另一方已开始调停请求;即,客户有某种原因先向服务端发送 FIN信号,导致服务终止被动关闭,如果服务端不主动关闭插座并向客户端发送 FIN,此时,服务端口将处于CLOSE_WAIT状态(而不是LAST_ACK状态)。
CLOSE_WAIT的特点:
CLOSE_WAIT由于某些原因将持续至少2小时(系统默认为7200秒,也就是2小时)。如果服务器程序导致系统由于某种原因消耗大量CLOSE_WAIT资源,所以通常你不会等到释放的时刻,系统就已崩溃。CLOSE_WAIT的危险包括TOMCAT响应损失等。
解决CLOSE_WAIT过载问题有两种方法:
1)在程序中找到错误并修复它;
2)修改TCP/IP的维护参数,缩短CLOSE_WAIT状态维护的时间;
TCP连接的维护参数:
1> /proc/sys/net/ipv4/tcp_keepalive_time 对应内核参数 net.ipv4.tcp_keepalive_time
如果在指定的数秒内,TCP连接仍处于闲置状态,则内核开始在客户端上启动探测器以查看它是否还活着;
2> /proc/sys/net/ipv4/tcp_keepalive_intvl 对应内核参数 net.ipv4.tcp_keepalive_intvl
意思是:该参数指定的秒数是时间间隔,客户端启动其检测;
3> /proc/sys/net/ipv4/tcp_keepalive_probes 对应内核参数 net.ipv4.tcp_keepalive_probes
内核启动客户端检测的次数,如果没有接收相应的客户端,则客户端要么不可用,要么关闭,内核关闭TCP连接并释放相应的资源;
因此,CLOSE_WAIT状态保持的秒数=tcp_keepalive_time + tcp_keepalive_intvl * tcp_keepalive_probes
因此,tcp_keepalive_time,tcp_keepalive_intvl,tcp_keepalive_probes的适当减少可以由三个值缩短:CLOSE_WAIT:
修改方法:
修改将暂时生效,在重新启动服务器后将恢复到默认值。 修改后,观察一段时间,如果CLOSE_WAIT减少,可以进行永久的修改:
在/etc/sysctl.Add或修改Conf的内容如下:
这里的数据比上面的数据大,因为上面的测试数据有点激进。 当然,如果数据太大,它就不会有效,但你仍然可以使用上面提到的数据。
修改执行后: sysctl -p 将修改立即生效。
5.4 TIME_WAIT状态和处理方法的原因:
与 TIME_WAIT和CLOSE_WAIT不同,默认 TIME_WAIT大,但默认CLOSE_WAIT应该更短。
TIME_WAIT发生在TCP的四个波的第二阶段:被动关闭触发 FIN(N),主动接收 FIN(N),输入 TIME_WAIT状态,然后ACK(N+1)。
输入 TIME_WAIT后,主动关闭器等待2MSL(最大分段寿命报告最大存储时间)才能释放资源,例如它拥有的端口。
这是因为,如果最后的ACK(N+1)没有被动方接收,被动面将重新创建 FIN(N2),然后在主动侧再次出现 ACK (N2+1) 的确认。因此, Active shutter 应该在 TIME_WAIT 状态下等待 2MSL 。
如果您的 TIME_WAIT状态的TCP负载过大,并且占用诸如端口的资源,您可以通过修改:
TCP连接的Time_WATI相关参数:
1)/proc/sys/net/ipv4/tcp_tw_reuse相应的内核参数:net.ipv4.tcp_tw_reuse
意思是:是否可以重新启用在 TIME_WAIT状态的TCP连接;在启用此重新设置时,必须同时启用以下快速循环!
2)/proc/sys/net/ipv4/tcp_tw_recycle相应的内核参数:net.ipv4.tcp_tw_recycle
意思:设置是否快速在 TIME_WAIT状态中检索TCP;
3)/proc/sys/net/ipv4/tcp_fin_timeout相应的内核参数:net.ipv4.tcp_fin_timeout
意思是:当它留在 FIN_WAIT_2中时,TCP会被关闭。 另一方可能仍不能终止连接,或者无法预料的进程会死去。
修改方法与 keepalive 参数相同:
永久修改方法也修改 /etc/sydctl.Conf:
sysctl -p是有效的修改。
如果它是Windows服务器,TcpTimedWaitDelay和MaxUserPort可以修改;参见 http://ww.cnblogs.com/digdeep/p/4779544.html
5.5检查不同状态的TCP连接的连接数目:
Windows平台实现类似的功能:
netstat -n | find /i "time_wait" /c
netstat -n | find /i "close_wait" /c
一个国家是一个统计数字.
6.TCP/IP传输窗口
Basically, the TCP transfer window is the maximum amount of data a given host can send or receive before requiring an acknowledgement from the other side of the connection. The window size is offered from the receiving host to the sending host by the window size field in the TCP header. Using the transfer window, the host can send packets more effectively because the sending host doesn't have to wait for acknowledgement for each sending packet. It enables the network to be utilized more. Delayed acknowledgement also improves efficiency. TCP windows start small and increase slowly with every successful acknowledgement from the other side of the connection.
传输窗口或滑动窗口,在收到接收方的确认包之前,指发送方,可以发送的数据总数。接收器通过TCP头的窗口大小字段,告诉发送器它自己的接受传输窗口有多大。然后发送者相应优化传输窗口的大小。
7. TCP/IP Offload
如果网络卡硬件支持checksum,tso等,则这些功能可以由网络卡实现,从而减少CPU负载。
1)检查sum offload:为了确保数据在传输过程中不会受到损伤,IP/TCP/UDP将检查数据并将其比较;此功能允许实现网络卡硬件;
2)TCP分段负载(TSO):如果传输的数据超过网络卡的MTU,则必须拆解,网络卡硬件也可以实现该功能;
8. 多网卡绑定
Linux内核支持将多个物理网络卡绑定到一个逻辑网络,从而实现网络卡负载平衡和网络卡容错。
9.检测网络瓶颈和故障
查看Linux网络情况的命令通常是: netstat, iptraf, tcpdump等,其中netstat是最常用的和使用最好的工具。
9.1使用netstat命令查看活动网络连接
netstat视图信息根据协议和连接状态分为两个类别:
1)根据协议tcp -t, udp -u显示: netstat -ntap, netstat -nuap
-t 表示 tcp 连接, -u 表示 udp 连接, 如下面所示
2)根据连接状态显示TCP协议: LISTEN -l; non- LISTEN, all state -a
添加-l以显示只在听状态中的TCP连接,-a以显示所有在状态中的TCP连接,和-a以显示仅在默认的ESTABLISHED状态中的TCP连接,如下面所示:
-n表示数值显示ip和终端数值,而不是文本;-p表示程序名称;
-c可以连续每秒一次显示。
字段含义:
recv-Q表示网络接收队列
该消息表明,接收数据是由缓冲器本地接收的,但其中一部分尚未被用户进程删除,如果接收队列Rev-Q被封锁,它可能遭受了拒绝服务攻击。
send-Q表示网络发送队列
被发送但没有收到对方的Ack, 也保留了本地缓冲区.
如果不能快速清除发送Q队列,则可能应用程序 sending out the packets too fast, or that the other party is not receiving the packets fast enough 。
两个值通常应该是0,如果不是0,那么可能有问题。 包不应该在两个队列中堆栈。
netstat-s显示所有协议连接的统计数据:
9.2使用iptraf命令实时查看网络
该命令显示在实时变化的网络信息,而iptraf的直接执行允许您进入交互界面。
一般使用方法: iptraf -i eth0, iptraf -g eth0, iptraf -d eth0, iptraf -l eth0
-i指示IP流量,-g指示通用信息,-d指示详细信息
Iptraf -d eth0, iptraf -d eth0
它显示: 接收的包数, 发送的包数; 网络包率: 输入的包数, 输出的包数.
9.3使用tcpdump命令查看网络
使用tcpdump可以筛选网络卡、主机、协议、端口等,并指定只查看指定的网络信息。
下面的结果来自一个访问网络包的浏览器,它是一个叫做Inginx的虚拟机:
以下 是 对 上述 结果 的 简要 分析 :

首先.52970的浏览器发送到.http服务器上,发送了一个已打开的SYN包(1845276991);
接下来.http服务器向.52970浏览器发送SYN+ACK包,注 ack=1845276992 = 1845276991 +1;
然后是.52970浏览器向.http服务器发送ACK(1),然后向服务器发送请求,seq 1:352从1到352只是351个字符,请求的长度:长度351相符;
服务器接受http请求后,返回ACK(352),确认浏览器收到请求,开始处理,然后返回内容:
seq: 1:244, seq: 244:856,响应请求,使用两个TCP连接发送内容,并发送855字节到浏览器;
52970浏览器在接收856字节后返回ACK(856)到服务器上。
因为浏览器发送一个字符串(第351:352)到服务器,然后服务器确认ACK(352)
您可以看到连接的每个头有一个胜利字段值(窗口大小),用于确定是否将传输窗口(滑行窗口)用于该字段;您也可以看到MSS值。
9.4使用sar-n命令查看网络
sar命令太强,所以CPU、内存、磁盘IO和网络都可以使用sar命令查看。 sar-n是专门用于网络的,使用下列方法:
sar -n { keyword [,...] | ALL }
Report network statistics.
Possible keywords are DEV, EDEV, NFS, NFSD, SOCK, IP, EIP, ICMP, EICMP, TCP, ETCP, UDP, SOCK6, IP6, EIP6,
ICMP6, EICMP6 and UDP6.
sar -n DEV: 查看每秒的网络卡,每秒的包数,每秒接收的KB数,发送的KB数:
英译汉 英译汉
sar -n EDEV: 查看网络错误,网络过载,网络故障
字段含义:
每秒收到的不良包的总数。每秒收到的损坏包
txerr/s:在传输数据包时每秒发生的错误总数。每秒发送受损数据包
Coll/s:传输数据包时每秒发生碰撞的数目。每秒发送网络冲突数据包的数目
rxdrop/s:由于Linux缓冲器缺乏空间,每秒丢失的接收包数减少。
txdrop/s:由于Linux缓冲器缺乏空间,每秒丢失的包数下降。
txcarr/s:在传输包时每秒发生的传输错误数目。传输错误意味着什么?
rxfram/s: Number of frame alignment errors that happened per second on received packets.
rxfifo/s:接收包每秒出现的FIFO过载错误数目。接收fifo队列中过载错误的频率(每秒)
txfifo/s:在传输包上每秒发生的FIFO过载错误的数目。发送者的fifo队列中过载错误的频率(每秒)
1)如果 coll/s网络冲突持续,可能存在网络设备的故障、瓶颈或配置错误;
2)FIFO队列超时发生,表明SOCKET BUFFER太小;
(三) persistent packet damage, frame damage, 可能表示网络设备部分故障,或配置错误;
sar -n SOCK:查看所有系统使用的SOCKKET端口和Time_WAIT状态连接
With the SOCK keyword, statistics on sockets in use are reported (IPv4). The following values are displayed:
totsck: Total number of sockets used by the system.
tcpsck: Number of TCP sockets currently in use.
udpsck: Number of UDP sockets currently in use.
rawsck: Number of RAW sockets currently in use.
ip-frag: Number of IP fragments currently in use.
tcp-tw: Number of TCP sockets in TIME_WAIT state.
9.5使用 ifconfig命令查看网络活动、错误和负载:
overruns:使用插座缓冲器的次数;帧:帧错误的次数
10.网络优化和调试
首先了解网络的基本原理:
1)查看各种状态数字: netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
查看网络错误,过时等待错误: ifconfig eth0, ifconfig all, sar -n EDEV, sar -n EDEV | grep eth0
3)检查网络流量: sar -n DEV, sar -n DEV | grep eth0
10.2确认网络双plex和速度是否正确:
结果,速度:100Mb/s Duplex:Full表明这是正确的。 在 Half 中,100Mb/s等将对性能产生巨大的影响。
10.3MTU尺寸调整
如果在TCP连接的两端的网络卡和网络接口层支持大的MTU,那么我们可以配置使用更大的MTU大小的网络,而不会导致切断重新组装和发送。
配置命令: ifconfig eth0 mtu 900 up
事实上,除了MTU之外,还有MSS(最大分区大小),MTU是网络接口层的限度,MSS是传输层的概念。事实上,这是TCP和IP分段。MSS值是在执行TCP协议(缩小标题)时从MTU转换中导出。当一个连接建立时,连接双方必须互相通知其MSS值。
基于MSS的TCP分段在传输层发生。TCP分段在传输层完成,并在传输层重新组织
基于MTU的IP区分在网络层中发生,由网络层完成IP区分,并重新组织网络层。
这里实际上是一个窗口大小,但它是一个完全不同的东西:
winsize is used for flow control. Each time the source can send out a number of segments without ACKs. You should check "sliding-
window" to understand this. The value ofwinis dynamic since it's related to theremaining buffer size.
(见:http://ww.Newsmth.Net/nForum/#!CompNetResearch/455
MTU,MSS,窗口大小
10.4升级网络缓存
较小的网络缓冲器,或频繁的ACK确认包,会导致较小的窗口大小和较小的传输窗口;过小的插座缓冲器对网络性能有严重的影响。
Small socket buffers could cause performance degradation when a server deals with a lot of concurrentlargefile transfers. A clear performance decline will hanppen when using small socket buffers. A low value ofrmem_maxandwmem_maxlimit available socket buffer sizes even if the peer has affordable socket buffers available. This causes small window sizes and creates a performance ceiling for large data transfers. Though not included in this chart, no clear performance difference is observed forsmall data(less than 4 KB) transfer.
1)/proc/sys/net/ipv4/tcp_mem TCP全球缓存,单元是内存页(4k);
相应的内核参数是 net.ipv4.tcp_mem 在 /etc/sysctl.modify 中找到;
2)/proc/sys/net/ipv4/tcp_rmem 接收缓冲器,字节单位
相应的内核参数是 net.ipv4.tcp_rmem,可以在 /etc/sysctl.modify 中找到;
3)/proc/sys/net/ipv4/tcp_wmem 接收缓冲器,字节单位
相应的内核参数是 net.ipv4.tcp_wmem,可以在 /etc/sysctl.modify 中找到;
-----------------------
4)/proc/sys/net/core/rmem_default 接收缓冲器默认大小,单位字节
相应的内核参数: net.core.rmem_default,可以在/etc/sysctl.modify中找到;
5)/proc/sys/net/core/rmem_max最大接收缓冲大小,单位字节
相应的内核参数: net.core.rmem_max,可以在/etc/sysctl.modify中找到;
6)/proc/sys/net/core/wmem_default
相应的内核参数: net.core.rmem_default,可以在/etc/sysctl.modify中找到;
7)/proc/sys/net/core/wmem_max 发送缓冲区最大大小,单位字节
相应的内核参数: net.core.rmem_max,可以在/etc/sysctl.modify中找到;
注意:修改/etc/sysctl。 conf 之后, sysctl -p 命令必须执行,才能生效。
10.5卸载配置
有些网络操作可以被卸载到网络硬件上.
ethtool -k eth0可以查看当前的卸载配置:
ethtool -K eth0 rx on|off, ethtool -K eth0 tx on|off, ethtool -K eth0 tso on|off
10.6 最大化 接收 和 发送 队列 的 大小 :
1)接收队列:/ proc/sys/net/core/netdev_max_backlog 相应的内核参数: net.core.netdev_max_backlog
2)发送队列:
修改: ifconfig eth0 txqueuelen 200
10.7减少SYN半连接tcp_max_syn_backlog的数目
TCP三手建立连接,被动开端,一个状态是SYN,
When the server is heavily loaded or has many clients with bad connections with high latency, it can result in an increase in half-open connections. This is common for Web servers, especially when there are a lot of dial-up users. These half-open connections are stored in the backlog connections queue. You should set this value to at least 4096. (The default is 1024.)
Setting this value is useful even if your server does not receive this kind of connection, because it can still be protected from a DoS (syn-flood) attack.
cat /proc/sys/net/ipv4/tcp_max_syn_backlog 相应的内核参数: net.ipv4.tcp_max_syn_backlog,它可以在/etc/sysctl.Configuration中找到。
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
当服务器很重的时候,这导致许多客户端连接,服务器尚未确认,所以它处于SYN状态,这是所谓的半开连接.半连接的数目由tcp_max_syn_backlog参数控制,增加它可以避免客户连接被拒绝,它还能够保护SYN免受洪灾攻击。也就是说, 等待的连接数可以容纳.
10.8 / proc/sys/net/core/somaxconn 和 net.core.Somaxconn
这个参数用于完成三个握手,并且连接已经建立,等待握手的数目被接受,然后处理。 莫尔认为128,我们可以调整到65535,甚至更大。
本文由 在线网速测试 整理编辑,转载请注明出处。