推荐视频: 剖析Linux内核网络协议栈大全 linux后台开发岗面试中tcpip,哪些容易被问到的 cclinux服务器开发学习地址:CCLinux服务器开发后台架构师【零声教育】学习视频教程腾讯课堂 同CPU、内存以及IO一样,网络也是Linux系统最核心的功能。网络是一种把不同计算机或网络设备连接到一起的技术,它本质上是一种进程间通信方式,特别是跨系统的进程间通信,必须要通过网络才能进行。随着高并发、分布式、云计算、微服务等技术的普及,网络的性能也变得越来越重要。 那么,Linux网络又是怎么工作的呢?又有哪些指标衡量网络的性能呢?接下来,我们一起学习Linux网络的工作原理和性能指标。网络模型 说到网络,我们肯定经常提起七层负载均衡、四层负载均衡,或者三层设备、二层设备等等。那么,这里说的二层、三层、四层、七层又都是什么意思呢? 实际上,这些层都来自国际标准化组织制定的开放式系统互联通信参考模型(OpenSystemInterconnectionReferenceModel),简称为OSI网络模型。 为了解决网络互联中异构设备的兼容性问题,并解耦复杂的网络包处理流程,OSI模型把网络互联的框架分为应用层、表示层、会话层、传输层、网络层、数据链路层以及物理层等七层,每个层负责不同的功能。其中:应用层,负责为应用程序提供统一的接口。表示层,负责把数据转换成兼容接收系统的格式。会话层,负责维护计算机之间的通信连接。传输层,负责为数据加上传输表头,形成数据包。网络层,负责数据的路由和转发。数据链路层,负责MAC寻址、错误侦测和改错。物理层,负责在物理网络中传输数据帧。 但是OSI模型还是太复杂了,也没能提供一个可实现的方法。所以,在Linux中,我们实际上使用的是另一个更实用的四层模型,即TCPIP网络模型。 TCPIP模型,把网络互联的框架分为应用层、传输层、网络层、网络接口层等四层,其中:应用层,负责向用户提供一组应用程序,比如HTTP、FTP、DNS等。传输层,负责端到端的通信,比如TCP、UDP等。网络层,负责网络包的封装、寻址和路由,比如IP、ICMP等。网络接口层,负责网络包在物理网络中的传输,比如MAC寻址、错误侦测以及通过网卡传输网络帧等。 为了帮你更形象理解TCPIP与OSI模型的关系,画了一张图,如下所示: 当然了,虽说Linux实际按照TCPIP模型,实现了网络协议栈,但在平时的学习交流中,我们习惯上还是用OSI七层模型来描述。比如,说到七层和四层负载均衡,对应的分别是OSI模型中的应用层和传输层(而它们对应到TCPIP模型中,实际上是四层和三层)。Linux网络栈 有了TCPIP模型后,在进行网络传输时,数据包就会按照协议栈,对上一层发来的数据进行逐层处理;然后封装上该层的协议头,再发送给下一层。 当然,网络包在每一层的处理逻辑,都取决于各层采用的网络协议。比如在应用层,一个提供RESTAPI的应用,可以使用HTTP协议,把它需要传输的JSON数据封装到HTTP协议中,然后向下传递给TCP层。 而封装做的事情就很简单了,只是在原来的负载前后,增加固定格式的元数据,原始的负载数据并不会被修改。 比如,以通过TCP协议通信的网络包为例,通过下面这张图,我们可以看到,应用程序数据在每个层的封装格式。 其中:传输层在应用程序数据前面增加了TCP头;网络层在TCP数据包前增加了IP头;而网络接口层,又在IP数据包前后分别增加了帧头和帧尾。 这些新增的头部和尾部,都按照特定的协议格式填充,想了解具体格式,你可以查看协议的文档。比如,你可以查看这里,了解TCP头的格式。 这些新增的头部和尾部,增加了网络包的大小,但我们都知道,物理链路中并不能传输任意大小的数据包。网络接口配置的最大传输单元(MTU),就规定了最大的IP包大小。在我们最常用的以太网中,MTU默认值是1500(这也是Linux的默认值)。 一旦网络包超过MTU的大小,就会在网络层分片,以保证分片后的IP包不大于MTU值。显然,MTU越大,需要的分包也就越少,自然,网络吞吐能力就越好。 理解了TCPIP网络模型和网络包的封装原理后,我们很容易能想到,Linux内核中的网络栈,其实也类似于TCPIP的四层结构。如下图所示,就是Linux通用IP网络栈的示意图: 我们从上到下来看这个网络栈,可以发现:最上层的应用程序,需要通过系统调用,来跟套接字接口进行交互;套接字的下面,就是我们前面提到的传输层、网络层和网络接口层;最底层,则是网卡驱动程序以及物理网卡设备。 网卡是发送和接收网络包的基本设备。在系统启动过程中,网卡通过内核中的网卡驱动程序注册到系统中。而在网络收发过程中,内核通过中断跟网卡进行交互。 再结合Linux网络栈,可以看出,网络包的处理非常复杂。所以,网卡硬中断只处理最核心的网卡数据读取或发送,而协议栈中的大部分逻辑,都会放到软中断中处理。 【文章福利】需要CCLinux服务器架构师学习资料加群812855908(资料包括CC,Linux,golang技术,内核,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCPIP,协程,DPDK,ffmpeg等) Linux网络收发流程 了解了Linux网络栈后,我们再来看看,Linux到底是怎么收发网络包的。网络包的接收流程 我们先来看网络包的接收流程。 当一个网络帧到达网卡后,网卡会通过DMA方式,把这个网络包放到收包队列中;然后通过硬中断,告诉中断处理程序已经收到了网络包。 接着,网卡中断处理程序会为网络帧分配内核数据结构(skbuff),并将其拷贝到skbuff缓冲区中;然后再通过软中断,通知内核收到了新的网络帧。 接下来,内核协议栈从缓冲区中取出网络帧,并通过网络协议栈,从下到上逐层处理这个网络帧。比如:在链路层检查报文的合法性,找出上层协议的类型(比如IPv4还是IPv6),再去掉帧头、帧尾,然后交给网络层。网络层取出IP头,判断网络包下一步的走向,比如是交给上层处理还是转发。当网络层确认这个包是要发送到本机后,就会取出上层协议的类型(比如CP还是UDP),去掉IP头,再交给传输层处理。传输层取出TCP头或者UDP头后,根据