我们简单说一下Linux的网络子系统

CPU 内存 以及IO 都是Linux的核心功能

网络是一种将不同的计算机连接到一起的技术,本质上是一种进程间通信的方式,特别是跨系统的进程间通信,必须要通过网络

传统上来说,网络模型分为了7层架构,或者说4层架构

七层中分为了

应用层 表示层 会话层 传输层 网络层 数据链路层 物理层

在4层架构中,是Linux的常见表示网路架构

分为了应用层,传输层,网络层,网路接口层四层

应用层负责 进行提供网络接口给应用程序,比如HTTP FTP DNS

传输层负责 端到端的传输 TCP及UDP等

网络层 网络包的封装 寻址 以及路由 提供IP以及ICMP等

网络接口层 网络包在物理网络中的传输,比如MAC寻址 错误侦测 网卡传输

七层和四层架构的区别,基本可以总结为下图

图片

在有了对应的TCP/IP的模型之后,进行网络传输的时候,数据包就会按照协议栈,对上层的数据进行逐层封装,发给下一层

基本上的封装如下

图片

传输层在应用程序前面加了TCP头

网络层在TCP之前加了IP头

网络接口,则加了帧头及帧尾

在三层中,限制了MTU的大小,在网络层中分片,保证分片后的IP不超过MTU的大小

MTU的默认值是1500

一旦网络包超过了MTU的大小,就会在网络层中分片

然后,我们说一下最下层的网卡,即物理层,网卡在启动的时候,通过内核的网卡驱动注册到系统中,然后在网络收发过程中,内核通过中断和网卡进行交互

结合之前提到的Linux网络栈来看,网络包的处理分为硬中断和软中断

硬中断只处理最核心的网卡数据读取和发送,协议栈中的大部分逻辑,放在软中断中处理

Linux网络收发流程

首先是接收的流程,当一个网络帧到了网卡之后,网卡通过DMA的方式放入到收包队列中,然后通过硬中断,告诉中断处理程序收到了网络包

接着,网卡处理程序会为网络帧分配数据结构,让其拷贝到sk_buff缓冲区中,通过软中断通知内核收到了新的网络帧

接下来,内核协议栈从缓冲区中取出网络帧,通过网络协议栈,从上到下的处理这个网络帧

整体的流程如下

图片

对应的发送流程,基本如下

网络包的接受流程对应的就是发送流程

其实就是利用Socket  API发送网络包

这样触发了一个系统调用,陷入了内核态的套接字层中,套接字层会将数据包放入到Socket发送缓冲区中

然后网络协议栈从Socket发送缓冲区中,获取到数据包,按照TCP/IP栈,从上到下的处理

处理完成之后,有软中断通知驱动程序,告诉内核发包队列中有新的网络帧需要发送

最后驱动程序通过DMA,从发包队列中读出了网络帧,通过物理网卡发出去

最后整理下网卡发送和接受报文的过程,

内核分配了一个主内存地址段 DMA缓冲区,网卡设备可以通过DMA缓冲区读写数据

当来了一个网络包,网卡将网络包写入DMA缓冲区,写完通知CPU产生硬中断

硬中断处理程序锁定当前的DMA缓冲区,然后将网络包拷贝到另一个内存区,清空并解锁当前DMA缓冲区,通知软中断去处理网络包

我们说完了整体的Linux网络架构和原理,应用程序通过套接字接口发送数据包的时候,通过网络协议栈从上到下进行逐层处理,最终通过网卡发送出去,接收网络包则是一套相反的流程,了解了这些,下一步们则是需要知道哪些的指标可以衡量Linux的网络协议

常见的指标,包含

带宽 链路的最大传输速率,单位为b/s

吞吐量,单位时间传输成功的数据量,单位为b/s或者B/s  -> 吞吐量/带宽,就是网络的使用率

延时,网络包从发出到对应的响应的时间,一般指的是RTT 数据包往返的时间

PPS 网络包为单位的传输效率,PPS通常用于评估网络转发能力

除此外,网络性能还有 网络可用性 并发连接数 丢包率 重传率也是常用的性能指标

对于网络问题分析的第一步,就是查看网络接口的配置和状态,可以使用ifconfig ip命令

ifconfig和ip分别属于软件包 net-tools 和 iproute2 , iproute2是nettools的下一代,通常情况下会在发行版中默认安装

以网络接口eth0为例,可以运行如下的命令,获取对应的配置和状态

$ ifconfig eth0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

inet 10.240.0.30 netmask 255.240.0.0 broadcast 10.255.255.255

inet6 fe80::20d:3aff:fe07:cf2a prefixlen 64 scopeid 0x20<link>

ether 78:0d:3a:07:cf:3a txqueuelen 1000 (Ethernet)

RX packets 40809142 bytes 9542369803 (9.5 GB)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 32637401 bytes 4815573306 (4.8 GB)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

$ ip -s addr show dev eth0

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000

link/ether 78:0d:3a:07:cf:3a brd ff:ff:ff:ff:ff:ff

inet 10.240.0.30/12 brd 10.255.255.255 scope global eth0

valid_lft forever preferred_lft forever

inet6 fe80::20d:3aff:fe07:cf2a/64 scope link

valid_lft forever preferred_lft forever

RX: bytes packets errors dropped overrun mcast

9542432350 40809397 0       0       0       193

TX: bytes packets errors dropped carrier collsns

4815625265 32637658 0       0       0       0

两者输出类似,只是格式不同,他们都包括了网络接口的状态标志 MTU大小 IP 子网 MAC地址和网络包的收发统计信息

里面包含几个和网络密切相关的指标,包括如下

第一,网络接口的标志状态,ifconfig中的RUNNING ip输出汇总的LOWER_UP,说明物理网络是连通的,网卡已经介入了交换机或者路由器中,如果看不到,说明网线被拔掉了

MTU的大小,MTU默认是1500,根据网络架构,可能需要调大或调小MTU的数值

网络接口的IP地址 子网和MAC地址

网络收发的字节数,包数,错误数以及丢包的请求,包括 errors dropped overruns carrier

collisions 不为0,表示出现了网络IO问题

errors 包括错误的包数

dropped表示丢弃的包数

overruns 超限数据包,即网络IO速度过快,导致RingBuffer来不及处理而丢包

carrier 表示carrier错误的包数,比如物理电缆问题等

collsions 碰撞包数

套接字信息

ifconfig和ip只显示了网络接口收发数据的统计信息

实际性能之中,netstat或者ss,都可以用来查看套接字,网络栈 网络接口以及路由表信息

ss来查看网路连接

# head -n 3 表示只显示前面3行

# -l 表示只显示监听套接字

# -n 表示显示数字地址和端口(而不是名字)

# -p 表示显示进程信息

$ netstat -nlp | head -n 3

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name

tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      840/systemd-resolve

# -l 表示只显示监听套接字

# -t 表示只显示 TCP 套接字

# -n 表示显示数字地址和端口(而不是名字)

# -p 表示显示进程信息

$ ss -ltnp | head -n 3

State    Recv-Q    Send-Q        Local Address:Port        Peer Address:Port

LISTEN   0         128           127.0.0.53%lo:53               0.0.0.0:*        users:((“systemd-resolve”,pid=840,fd=13))

LISTEN   0         128                 0.0.0.0:22               0.0.0.0:*        users:((“sshd”,pid=1459,fd=3))

netstat和ss的输出都是类似的

其中的重要指标是 接受队列Recv-Q和发送队列 Send-Q,通常是0,如果不是0,说明有网络包的堆积

在链接的不同状态,会有不同的含义

Established的时候,Recv-Q会表示套接字缓冲还没有被应用程序取走的字节数

Send-Q表示还没有被远端主机确认的字节数

而Listening的时候,

Recv-Q表示全连接队列的长度

Send-Q表示全连接队列的最大长度

然后查看协议栈相关统计信息

使用netstat和ss,可以查看协议栈信息

$ netstat -s

Tcp:

3244906 active connection openings

23143 passive connection openings

115732 failed connection attempts

2964 connection resets received

1 connections established

13025010 segments received

17606946 segments sent out

44438 segments retransmitted

42 bad segments received

5315 resets sent

InCsumErrors: 42

$ ss -s

Total: 186 (kernel 1446)

TCP:   4 (estab 1, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0

Transport Total     IP        IPv6

*    1446      –         –

RAW    2         1         1

UDP    2         2         0

TCP    4         3         1

ss显示了连接 关闭 孤儿套接字等信息统计,netstat则提供更加详细的网络协议栈的信息

netstat输出还包括TCP的主动连接 被动连接 失败重试 发送和接收的分段数量等信息

网络吞吐和PPS

sar则可以直接查看.只需要加上-n的参数节课

获取对应的信息,输出的指标比较多,比如下面的信息

# 数字1表示每隔1秒输出一组数据

$ sar -n DEV 1

Linux 4.15.0-1035-azure (ubuntu)   01/06/19   _x86_64_  (2 CPU)

13:21:40        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil

13:21:41         eth0     18.00     20.00      5.79      4.25      0.00      0.00      0.00      0.00

13:21:41      docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

13:21:41           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

rxpck/s 和 txpck/s 接收和发送的PPS,单位为包/秒

rxkB/s 和 txkB/s 接收和发送的吞吐量 单位是KB/秒

rxcmp/s 和 txcmp/s 接收和发送的压缩数据包数,单位是包/秒

%ifutil 网络接口的使用率, 半双工为 (rxkB/s + txkB/s) / Bandwidth

双工为 max(rxkB/s , txkB/s) / Bandwidth

Bandwidth 可以使用ethtool查询,单位是Gb/s 或者是Mb/s 都是比特而不是字节

最后就是ping

ping 一个地址,可以获得两部分信息

可以获取对应的ICMP 的 ping的信息

本次,我们说了,如何使用带宽 吞吐量 延时等指标,获得衡量网络的性能

可以使用ifconfig netstat ss sar ping等工具,进行查看网路性能

发表评论

邮箱地址不会被公开。 必填项已用*标注