网络分析
一、OSI和TCP/IP模型
应用层:http,https,mqtt,ftp
表示层:数据转换成兼容接收系统的格式
会话层:建立维护通信连接
传输层:为数据加上表头,形成数据包。建立端到端的通信
网络层:负责数据的路由和转发,通过 IP 寻址来建立两个节点之间的连接
数据链路层:mac 寻址
物理层:中继器,路由器,交换机等等
二、三次握手和四次挥手
一次握手: 客户端向服务器 发送 syn 序列号 ,然后 进入 SYN--SENT 状态。此时服务端维护了一个半连接队列: tcp_max_syn_backlog
当积压的半连接个数超过了 tcp_max_syn_backlog值,新的SYN数据包会被drop
二次握手: 服务端 接收到 syn , 会 给客户端返回 synack 确认, , 状态变更为RCVD
客户端发出 SYN 后如果一直没有收到服务端的 synack,会重传 tcp_syn_retries (默认6)次(重传间隔时间1,2,4,8,16,32,64秒)。之后还没有收到数据包,返回 connection timeout
三次握手: 客户端接收到服务端的 k synack 之后,向服务端发送最终的 ack确认。此时 客户端进入 ESTABLISHED ( 就绪)
此时服务端维护的是全连接队列。全连接队列在(backlog, net.core.somaxconn)之间取最小值
backlog 在每个层级下配置
如果服务端没有接收到客户端的最终 ack,服务端也会重传 synack。重传次数由tcp_synack_retries 控制
全连接个数如果超出队列长度,新的全连接就会被 drop。服务端在执行 drop 的时候,可以选择发送 reset 来通知客户端,让客户端不再重发
net.ipv4.tcp_abort_on_overflow = 0 表示不发送 reset
一次挥手:TCP 发送一个 FIN(结束),用来关闭客户到服务端的连接。客户端进入 FIN- WAIT- 1
二次挥手:服务端收到 FIN,返回一个 ack 之后进入了 CLOSE- WAIT 状态。客户端收到服务器的 ack 后进入 FIN- WAIT- 2
这个状态后,如果收不到对端的 FIN 包,就会一直处于这个状态,持续消耗资源。可以设置超时时间 tcp_fin_timeout,默认为 60s,超过这个时间自动销毁连接
三次挥手:服务端发送一个 FIN 到客户端,接着关闭客户端的连接。服务器就进入了 LAST -K ACK 状态,等待客户端的确认
四次挥手:客户端确认关闭之后进入 TIME- -T WAIT 状态,服务器收到了客户端发出的确认,进入 D CLOSED 状态
Timewait 时间过长或者总数过多,会导致大量的端口被占用,新的连接无法建立。处理方法
设置 net.ipv4.tcp_max_tw_buckets,控制 timewait 总数
设置 net.ipv4.tcp_tw_reuse = 1,开启端口复用
设置 net.ipv4.ip_local_port_range,扩大端口范围
三、linux的TCP核心配置
四、常用的TCP分析命令
1.windows
分析客户端的 tcp 状态,如果 time_wait 很高,ES 很低。说明 TCP 连接在不停的中断
netstat -an |find /c ":port" 统计 tcp 总量
netstat -nap tcp| findstr port | find /C "ESTABLISH"
netstat -nap tcp| findstr port| find /C "TIME"
netstat -nap tcp| findstr port| find /C "SYN"
2.linux
ss -t -a |grep {prot} 查全连接队列
Recv-Q:全连接队列当前长度
Recv-Q:全连接队列当前长度
tcp 的连接数超出应用的最大连接数,在 新的请求将会被存在 back_log 中等待连过 接释放。如果等待连接的数量超过 back_log ,连接将彻底阻塞
netstat - - s | grep overflow 查看 t accept
tc qdisc add dev eth0 root netem loss 10% 模拟丢包
tc qdisc add dev eth0 root netem delay 100ms 模拟网络延迟
3.网络优化
ethtool -l eth0 查看网卡数
上面的是Combined是最大能支持几个网卡,下面的Combined是当前开启的几个网卡
ethtool -L eth0 combined {index}激活网卡队列
ethtool -s eth0 speed 1000 设置网卡流速(如果设置的500,就算是办理的1000MB/s的宽带也只是500MB/s的速率)
ethtool -s eth0 duplex full autoneg off 设置网口半/全双工(全双工:客户端向服务端发送数据包的同时,服务端可以向客户端发送数据包,服务器默认是不开的 开启命令:ethtool -s eth0 speed 1000 duplex full)
cat /sys/class/net/eth0/mtu 查看或者修改 mtu
五、宽带
网卡速率 b=bit【比特】 网络传速 B=Byte【字节】 1Byte=8bit ,下行速度大概是上行速度的 2-3倍 , 千兆网卡的传速速度就是 千兆/8=1235Mb/s,加上网络消耗差不多 100MB/s【下行速度】,下行速度就是4MB/s左右。
六、网络数据包收发过程
收包:
1.网络包到达网卡
2.DMA缓冲区
a.内核分配的一个主存地址段(DMA缓冲区)
b.网卡设备在DMA缓冲区中读写数据
3.网卡把网络收包队列写入DMA缓冲区队列
4.DMA通知CPU产生硬中断(net.core.netdev_budget = 60000【cpu轮询数据包】)
5.中断处理器锁定DMA缓冲区
6.中断处理器为网络包分配内存缓冲区(sk_buff) (net.ipv4.tcp_moderate_rcvbuf=1【sk_buff自适应】 net.core.netdev_max_backlog 【sk_buff队列优化】)
7.中断处理器将网络包拷贝到sk_buff缓冲区
8.中断处理器清空并解锁当前DMA缓冲区
9.通过软中断通知内核协议栈处理数据包
10.内核协议栈从sk_buff缓冲区取出网络包,开始处理问题
11.链路层 检查报文的合法性。找出上层协议的类型(IPv4还是ipv6),去掉帧头、帧尾后交给网络层
12网络层 取出 IP 头,判断下一步的走向,比如是交给上层处理还是转发.。判断上层协议的类型( TCP 还是 UDP),去掉 IP 头,交给传输层处理
13.传输层 取出 TCP 或者 UDP 头,根据 < 源 IP、源端口、目的 IP、目的端口 >作为标识,找出对应的 Socket 。数据拷贝到 Socket 接收缓冲区。内核用缓冲区队列来保存这些数据【netdev_max_backlog】 net.ipv4.tcp_moderate_rcvbuf = 1【接收缓冲区动态调整】
2.发包:
1.应用程序陷入内核态套接字层,调用 Socket API 【系统调用】
2.套接字把发包队列放到socket发送缓冲区
a.net.ipv4.tcp_wmem 【发送缓冲区】
b.net.ipv4.tcp_mem 【tcp连接消耗的总内存】
c.net.core.wmem_max【应当大于发送缓冲区】
d.echo 1 > /sys/kernel/debug/tracing/events/sock/sock_exceed_buf_limit/enable【打开tracing观察内存事件】
e.cat /sys/kernel/debug/tracing/trace_pipe
3.网络协议栈从 Socket 发送缓冲区取出数据包,开始处理
4.传输层添加TCP头
5.网络层添加IP头,判断数据长度是否超出链路层的MTU
a.超出MTU,切片发送,导致cpu中断 cat /sys/class/net/eth0/mtu【MTU查询】 echo "{mtu值默认1500}" > /sys/class/net/eth0/mtu【mtu调整】
b.没有超出MTU,向下走链路层(网络接口层)
6.链路层物理寻址,找到MAC地址,添加帧头帧尾
7.将发包队列写入DMA缓冲区
8.软中断通知驱动程序处理
9.驱动程序从DMA读取发包队列的数据包,通知网卡发送
七、网络IO分析:
iptraf-ng
iptraf-ng -s eth0【网卡各端口流量】
iptraf-ng -d eth0【网卡流量】
iptraf-ng -i eth0【远程主机端口】
sar -n TCP,ETCP【重传】
sar -n DEV,EDEV【丢包】
nicstat -t 【Tcp信息】
InKB : 表示每秒接收到的千字节.
OutKB : 表示每秒传输的千字节.
InSeg : 表示每秒接收到的TCP数据段(TCP Segments).
OutSeg : 表示每秒传输的TCP数据段(TCP Segments).
Reset : 表示TCP连接从ESTABLISHED或CLOSE-WAIT状态直接转变为CLOSED状态的次数.
AttF : 表示TCP连接从SYN-SENT或SYN-RCVD状态直接转变为CLOSED状态的次数,再加上TCP连接从SYN-RCVD状态直接转变为LISTEN状态的次数
%ReTX : 表示TCP数据段(TCP Segments)重传的百分比.即传输的TCP数据段包含有一个或多个之前传输的八位字节.
InConn : 表示TCP连接从LISTEN状态直接转变为SYN-RCVD状态的次数.
OutCon : 表示TCP连接从CLOSED状态直接转变为SYN-SENT状态的次数.
Drops : 表示从完成连接(completed connection)的队列和未完成连接(incomplete connection)的队列中丢弃的连接次数.
nicstat -l【网卡速率】
nicstat -x –n 1 10
iftop -i eth0【】
nload -u M【】
ifstat -i eth0
RX:发送流量
TX:接收流量
PEAK:流量峰值
rates:过去 2s 10s 40s 的平均流量
八、关注点:
硬件关注点:网络速度、网卡速率、网卡数、双工开启。分析错误率,重传率;看实际的带宽利用率,收发包的次数
先从内存着手,查看缓冲区空间,查看TCP连接池,端口数
瓶颈:网卡中断过多,频繁打断cpu 数据包在队列积压太多,队列阻塞