1 物理层
物理层工作会将收到的每一个字节,都复制到其他端口上去。这就是第一层物理层联通方案。
物理层主要是最原始的数据比特流传输。
2 第二层(数据链路层)
数据链路层(约定俗成说的是MAC层,Medium Access Control媒体访问控制)要解决以下三个问题:
1、 这个包是发给谁的?谁应该接收?(ARP寻址协议)
2、大家都在发包,谁先发、谁后发?会不会发生混乱?(多路访问规则,以太网使用的是随机接入协议)
3、 发送时出现了错误,怎么办?(CRC循环冗余检测或者XOR异或算法)
数据链路层发送的数据叫帧,网络层叫包,传输层叫段
2.1 ARP
在一个局域网里面,当知道了 IP 地址,不知道 MAC 怎么。广而告之,发送一个广播包,谁是这个 IP 谁来回答。
为了避免每次都用 ARP 请求,机器本地也会进行 ARP 缓存,当然机器会不断地上线下线,IP 也可能会变,所以 ARP 的 MAC 地址缓存过一段时间就会过期。
2.2 冲突域、广播域
- 冲突域
冲突域就是连接在同一导线上的所有工作站的集合,或者说是同一物理网段上所有节点的集合,或以太网上竞争同一带宽的节点集合。 - 广播域
广播是一种信息的传播方式,指网络中的某一设备同时向网络中所有的其它设备发送数据,这个数据所能广播到的范围即为广播域(Broadcast Domain)。即网络中能接收任一设备发出的广播帧的所有设备的集合。
2.3 集线器、二层交换机
- 集线器
1.一个广播域,一个冲突域。
2.传输数据的过程中易产生冲突,带宽利用率不高。 - 交换机
1.在划分vlan的前提下可以实现多个广播域,每个接口都是一个单独的冲突域
2.通过自我学习的方法可以构建出CAM表,并基于CAM进行转发数据。
3.支持生成树算法。可以构建出物理有环,逻辑无环的网络,网络冗余和数据传输效率都甩Hub好几条街。SW是目前组网的基本设备之一。 - CAM表
所谓“cam表”就是指二层交换机上运行的Cisco IOS在内存中维护的一张表,CAM表是交换机在二层转发数据要查找的表,表中有MAC地址,对应的端口号,端口所属的VLAN。交换机的每一个二层端口都有MAC地址自动学习的功能,当交换机收到PC发来的一个帧,就会查看帧中的源MAC地址,并查找CAM表,如果有就什么也不做,开始转发数据。如果没有就存入CAM表,以便当其他人向这个MAC地址上发送数据时,可以决定向哪个端口转发数据。
3 第三层(网络层)
IP、ICMP
3.1 IP
按照传统的将IP地址分为5类,每个类别下网络号和主机号如下表所示。此时我们会发现A类、B类一个网段下主机数太多了,而C类又太少了。
IP地址分为5类.png
image.png
3.1.1 无类型域间选路(CIDR)
于是有了一个折中的方式叫做无类型域间选路(classless Inter-Domain Routing)。它将32位IP地址一分为2,前面是网络号,后面是主机号。比如10.100.122.2/24,表示前24位表示网络号,后8位表示主机号。
IP地址除了分类,还有几个常用的概念需要理解:
- 广播地址:广播地址(Broadcast Address)是专门用于同时向网络中所有工作站进行发送的一个地址。在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址,广播的分组传送给host ID段所涉及的所有计算机。
- 子网掩码:用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。将子网掩码和 IP 地址按位计算 AND,就可得到网络号。
3.2 ICMP(互联网控制报文协议)
当网络不通时,有哪些办法来调试?(ping、traceroute)
ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议簇的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
ICMP是IP协议的一个附属协议,一般认为属于网络层协议。ICMP报文是封装在IP包里面的,因为它起着侦查的作用,传输指令的时候肯定也得有源地址和目标地址等信息。但它只是侦查兵,所以不能携带大量信息,只能轻装上阵。
- ICMP报文类型
ICMP报文类型有很多种,最常用的主动请求类型为8,主动请求的应答为0,具体如下表所示:
类型代码 | 类型描述 |
---|---|
0 | 响应应答(ECHO-REPLY) |
3 | 不可到达 |
4 | 源抑制 |
5 | 重定向 |
8 | 响应请求(ECHO-REQUEST) |
11 | 超时 |
12 | 参数失灵 |
13 | 时间戳请求 |
14 | 时间戳应答 |
一般分两个大类,查询报文类型和差错报文类型。
3.2.1 查询报文
常用的ping就是查询报文,是一种主动请求并且获得主动应答的ICMP协议。ping发的包也是符合ICMP协议格式的,只不过在后面又增加了自己的格式。
对于ping的主动请求,进行网络抓包,称为ICMP ECHO REQUEST。同理主动请求的回复,称为ICMP ECHO REPLY。比起原生的ICMP,多了两个字段:
- 标识符
不同的侦查兵派出去作用不同,需要有标识符才能区分 - 序号
派出去的侦查兵,都需要编号,看能回来几个
ping还会存储发送请求的时间值来计算往返时间。
ping协议的工作过程.png
3.2.2 差错报文
常用的侦查兵除了出去探路的(查询),还有回来报错的。常用的几个差错报文类型有:终点不可达3,源抑制4,超时11,重定向为5。
终点不可达分为:
- 0 网络不可达
- 1 主机不可达
- 2 协议不可达
- 3 端口不可达
- 4需要分片但设置了不分片位
traceroute可以使用ICMP规则,故意制造一些产生错误的场景。traceroute常用的两招是:
- 设置TTL(time to live),来追踪去往目的地时沿途经过的路由器。如果设置成1,如果去往目的地的中间路由器不止一个,那么碰到第一个路由器就会牺牲返回一个ICMP包,内容是时间超时。接下来设置成2,那么就知道第二个路由器有多远,如此反复直到到达目的主机。(怎么知道UDP有没有到达目的主机呢,traceroute会故意发送一份UDP数据报给目的主机,但会选择一个不可能的UDP端口号比如大于30000,当数据报到达时,目的主机的UDP模块会产生一份端口不可达错误的ICMP报文返回,如果数据报没有到达,则可能还是超时)
- 确定MTU(最大传输单元),故意设置不分片,当每次收到ICMP不能分片差错时就减小分组的长度,直到到达目的主机。
3.3 NAT(网络地址转换)
NAT(Network Address Translation),当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但现在又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。
这种方法需要在专用网连接到Internet的路由器上安装NAT软件。装有NAT软件的路由器叫做NAT路由器,它至少有一个有效的外部全球IP地址。这样,所有使用本地地址的主机在和外界通信时,都要在NAT路由器上将其本地地址转换成全球IP地址,才能和Internet连接。
NAT时不光会替换ip地址,也会替换端口号;每个网关应该都维护了一张端口主机映射表,这样便能准确寻址私网主机。
4 传输层
TCP、UDP首先不同的特异性就是前者面向连接,后者无连接。所谓的建立连接,是为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态,用这样的数据结构来保证所谓的面向连接特性。
4.1 UDP
UDP头格式.png三大使用场景:
- 需要资源少,网络情况好的内网,对于丢包不敏感
- 不需要一对一沟通,建立连接,而是可以广播的应用。 比如DHCP就是基于UDP协议的,DHCP就是一种广播的形式。
- 需要处理速度快,时延低,可以容忍少数丢包,但是要求即便网络拥塞,也必须毫不退缩一往无前的发送。比如流媒体协议、实时游戏等。一般采用自定义的可靠的UDP协议。
4.2 TCP
TCP头格式.png- TCP提供可靠交付。通过TCP连接传输的数据,无差错】不丢失、不重复、按序到达。
- TCP是面向字节流。发送的时候是发一个流,没头没尾。IP包则是一个个的IP包,之所以变成流是TCP状态维护做的事情。UDP则继承IP的特性,基于数据报,一个一个的发,一个一个的收。
- TCP拥有拥塞控制。通过滑动窗口来控制自己的行为。而UDP则是应用让发就发。
- TCP是有状态的服务。精确记着发送了没有,接收到没有,发送到哪个了,应该接收哪个了。
5 应用层
5.1 HTTP
HTTP1.1请求构建.pngAccept-Charset:客户端可以接受的字符集
Content-Type:正文格式
If-Modified-Since:只有当所请求的内容在指定的日期之后又经过修改才返回 HTTP1.1返回构建.png
Retry-After:客户端应该多久后再次尝试
Content-Type:返回格式 HTTP请求架构图.png
5.2 HTTP协议的演变
HTTP1.1在应用层以纯文本的形式进行通信。每次通信都要带完整的HTTP头,而且不考虑pipeline模式的话,每次的过程总是一去一回。因此实时性、并发性都存在问题。具体描述如下:
http1.0的队首阻塞
对于同一个tcp连接,所有的HTTP1.0请求放入队列中,只有前一个请求的响应收到了,才能处理发送下一个请求。http1.0队首阻塞主要发生在客户端。
http1.1的队首阻塞
对于同一个tcp连接,http1.1允许一次发送多个http1.1请求,也就是说,不必等前一个响应收到,就可以发送下一个请求。但http1.1规定,服务器端的响应的发送要根据请求被接收的顺序排队。也就是说先收到的请求的响应也要先发送。这样造成的问题是,如果最先收到的请求处理时间长的话,响应生成也慢,就会阻塞已经生成的响应的发送。也会造成队首阻塞。http1.1的队首阻塞发生在服务器端。
为解决队首阻塞问题,HTTP2.0会对HTTP的头进行一定的压缩,将原来每次都要携带的大量key value在两端建立一个索引表,对相同的头只发送索引表中的索引。
另外,HTTP2.0协议将一个TCP连接中,切分为多个流,每个流都有自己的ID,而且流可以是客户端发送往服务端,也可以是服务端发往客户端。它其实只是一个虚拟的通道。流还可以赋予不同的优先级。
HTTP2.0协议还将所有的传输信息分割为更小的消息和帧,并对它们采用二进制格式编码。常见的帧有Header帧,用于传输Header内容并开启一个新的流。再就是Data帧,用来传输正文实体。多个Data帧属于同一个流。
通过这两种机制,HTTP2.0的客户端可以将多个请求分到不同的流中,然后将请求内容拆成帧,进行二进制传输。这些帧可以打散乱序发送,然后根据每个帧首部的流标识符重新组装,并且可以根据优先级,决定优先处理哪个流的数据。
总结:http2解决队首阻塞
http2无论客户端还是服务器端都不需要排队,在同一个tcp连接上,有多个stream,由各个stream发送和接收http请求,各个stream相互独立,互不阻塞。
只要tcp没有人在用,那么就可以发送已经生成的request或者response的数据,在两端都不用等,从而彻底解决了http协议层面的队首阻塞问题。
5.3 QUIC(Quick UDP Internet Connection)
HTTP2.0大大增加了并发性,但因为是基于TCP协议,TCP协议在处理包时时有严格顺序的。当其中一个数据包遇到问题,TCP连接需要等待这个包完成重传之后才能继续进行。虽通过多个stream,使得逻辑上一个TCP连接上的并行内容,进行多路数据的传输,然而这中间并没有关联的数据。一前一后,前面stream2的帧没有到,那么stream1的帧也会因此阻塞。
Google提出的QUIC协议很好的解决了这个问题。
5.3.1 自定义连接机制
一条TCP连接是四元组标识的,分别是源IP、源端口、目的IP、目的端口。一旦某个元素发生变化,就需要断开重连。当手机信号不稳定、wifi信号发生改变、移动网络发生切换,都会导致再次的三次握手的重连。
但基于UDP,QUIC在自己的逻辑里面维护连接的机制,不再以四元组标识,而是以一个64位的随机数作为ID来标识,而且UDP是无连接的,所以当IP或者端口变化时,只要ID不变则无需重连
5.3.2 自定义重传机制
TCP为了保证可靠性,通过使用序号和应答机制,来解决顺序问题和丢包问题。任何一个包发送出去,都得在一定的时间得到应答否则视为超时。TCP的超时是通过采样往返时间RTT(round-trip time)不断调整的。
其实在TCP里面超时的采样存在不准确的问题,比如发送一个序号为100的包,无返回。过一阵再发一个100,返回得到ACK101.往返时间就是ACK到达减去一个序号100的包的发送时间,减去第一个100序号的包,超时时间算长了,减去后一个100序号的包,时间就算短了。
QUIC里也有序列号但是是递增的,一个序列号的包只发一次,比如发一个包,序号为100,无返回再发送时序号就是101.如果返回的ACK是100,就是对第一个包的响应。ACK101就是对第二个包的响应。RTT计算相对准确。
但QUIC里怎么知道序号包100和包101是同样的内容呢,QUIC定义了一个offset的概念,QUIC既然也是面向连接的,那也就像TCP一样,是个数据流。发送的数据在这个数据流里面有个偏移量offset,可以通过offset查看数据发送到了哪里。这样只要这个offset宝没有来就得重发。如果来了就进行拼接,还是能拼成一个流。
image.png
5.3.3 无阻塞的多路复用
一个QUIC连接可以创建多个stream,因为QUIC是 基于UDP的,一个连接的多个stream之间没有依赖。假如stream2丢失了一个UDP包,后面跟着stream3的一个udp包,虽然stream2的包需要重传,但stream3的包无需等待。
5.3.4 自定义流量控制
TCP流量控制是通过滑动窗口协议。在TCP协议中,接收端的窗口起始点是下一个要接收并且ACK的包,即便后来的包都到了,放在缓存里,窗口也不能右移,因为TCP的ACK机制是基于序列号的累计应答,一旦ACK了一个序列号,就说明前面的都到了,所以只要前面的没到,后面到了的也不能ACK。因此导致后面的到了,也可能超时重传浪费带宽。
QUIC的ACK是基于offset的,每个offset的包来了,进了缓存,就可以应答,应答后不会重发。中间的空档会等待到来或者重发,窗口的起始位置为当前收到的最大offset,从这个offset到当前stream所能容纳的最大缓存,是真正的窗口大小。因此这样更加准确。
5.4 HTTPS
其中SSL/TLS是一种介与于传输层(比如TCP/IP)和应用层(比如HTTP)的协议。它通过"握手协议(Handshake Protocol)"和"传输协议(Record Protocol)"来解决传输安全的问题。SSL/TLS是一个可选层,没有它,使用HTTP也可以通信,它存在的目的就是为了解决安全问题,这也就是HTTPS相对于HTTP的精髓所在。
5.4.1 对称加密和非对称加密优缺点
对称加密,秘钥相同,那么秘钥传输时风险比较大。非对称加密各自拥有对方的公钥,然后用自己的私钥解密,但性能存在问题。
5.4.2 CA
每个人都可以创建自己的私钥,然后根据私钥创建公钥。但怎么才能证明这个公钥是有效的呢?此时需要权威机构CA的介入。CA的做法是将公钥进行哈希摘要算法,然后用CA私钥对其进行加密伴随公钥一起发出去(统称为证书)。客户端收到后,用CA公钥(各大CA机构的公钥是默认安装在操作系统里的)进行解密,然后对公钥进行哈希,比对哈希值是否一致。
CA的公钥则需要更牛的CA签名,层层往上递推,直到全球皆知的著名root CA。通过层层授信背书的方式,保证非对称加密模式的正常运转。
5.4.3 HTTPS工作模式
由于非对称性能不如对称加密,那么可以考虑将两者结合起来。比如公钥私钥用于传输对称加密的秘钥,而真正双方大量数据通信都是通过对称加密进行的。
HTTPS协议总体思路.png
5.5 DNS
DNS(Domain Name System)将域名和IP地址相互映射的一个分布式数据库。DNS服务器必须设置成高可用、高并发和分布式。
- 根DNS:返回顶级域DNS服务器的IP地址
- 顶级域DNS服务器:返回权威DNS服务器的IP地址
- 权威DNS服务器:返回相应主机的IP地址
5.5.1 DNS解析流程
注意每次都会先读缓存DNS,一般为etc/hosts文件
image.png
5.5.2 负载均衡
DNS除了映射为IP地址,还可以做另外一件事就是负载均衡。
- 内部负载均衡:域名解析时,通过配置策略,这次返回第一个IP,下次返回第二个IP
- 全局负载均衡: 为保证应用高可用,服务器会部署在多个机房有多个IP,当某个服务器挂掉,那么从DNS地址簿里删掉这个IP,就可以实现高可用。然后DNS还可以控制每次返回离用户最近的服务器IP,这样访问速度就会超快。
5.5.3 GSLB全局负载均衡器(Global Server Load Balance)
对于复杂的应用,尤其是跨运营商、跨地域的大型应用,则需要更复杂的全局负载均衡机制,因此需要专门的设备或者服务器来做这件事,这就是全局负载均衡器。
在yourcompany.com的DNS服务器中,一般是通过配置CNAME的方式,给object.yourcompany.com起一个别名,例如object.vip.yourcompany.com,然后告诉本地DNS服务器,让其请求GSLB来解析域名,然后GSLB再解析域名的过程中,通过自己的策略实现负载均衡。
以上图为例,画了两层GSLB,是因为分运营商和地域。希望不同运营商的用户,可以访问相同运营商机房中的资源,这样可以不跨运营商访问,有利于提高吞吐量,减少时延。
- 第一层GSLB,通过查看请求它的本地DNS服务器所在的运营商,就知道用户所在运营商是移动。通过CNAME方式,通过另一个别名object.yd.yourcompany.com,告诉本地DNS请求第二层的GSLB。
- 第二层GSLB,通过查看请求它本地DNS服务器所在地址,就知道用户的地理位置,然后将距离用户位置比较近的Region里面,六个内部负载均衡(SLB,Server Load Balance)地址,返回给本地的DNS服务器。
- 本地DNS服务器将结果返回给本地的DNS解析器
- 本地DNS解析器将结果缓存,返回给客户端
- 客户端开始访问属于相同运营商距离最近的Region1的对象存储,当然客户端得到了6个IP地址,它可以通过负载均衡的方式,随机或者轮询一个访问。对象存储一般会有三个备份,从而可以实现对存储读写的负载均衡。
5.5.4 HTTPDNS
由于DNS缓存失效、运营商自定义缓存、出口NAT转换导致无法识别运营商、域名更新等问题会导致DNS失效。这里引入了HTTPDNS,不走传统的DNS解析,自己搭建基于HTTP协议的DNS服务器集群,分布在多个地点和运营商,当客户端需要DNS解析时,直接通过HTTP协议进行请求这个服务器集群,得到就近的地址。
(HTTPDNS暂时不做过多的篇幅,后续有空再补充)
网友评论