从一个http请求说起
- 当我们访问一个网址,例如 www.xxxx.com 的时候。它首先会被DNS解析,由DNS返回给客户端真实IP地址
什么是DNS服务?
- DNS-Domain Name System,和http协议相同是位于应用层的协议,主要提供域名、IP的解析服务。
通常我们需要加速访问,于是有了CDN
CDN是什么?
- CDN—Content Delivery Network。表示内容分发网络。CDN本质上是一种网络缓存技术,一般用来存放静态资源,如图片、脚本、静态页面等。
发送请求的时候做了什么事?
Http协议通信原理
如何建立通信
- 一些需要注意的地方
- 常用通信协议一般有TCP和UDP
- 建立连接的握手过程
- http协议的通信是基于tcp/ip协议之上的一个应用层协议
- 其它的应用层协议FTP、DNS、SMTP、Telnet等
OSI七层网络模型和TCP/IP四层概念模型
HTTP请求在网络模型中-发送过程
-
请求发起过程中,在tcp/ip四层网络模型中所做的事情
- 应用程序通过TCP传输数据时,数据会被送入协议栈中,然后被转化为比特流送入网络。每一层都会对接收到的数据增加一些首部或者尾部信息。如下图示
- 应用程序通过TCP传输数据时,数据会被送入协议栈中,然后被转化为比特流送入网络。每一层都会对接收到的数据增加一些首部或者尾部信息。如下图示
-
首先由应用层发出请求
-
传输层对请求进行封装,增加TCP头
- TCP头,表示当前的协议头使用TCP协议进行传输
-
网络层增加IP头
- IP头是一个网卡在网络中的通讯地址,相当于门牌号。IP地址冲突是导致网络中断的原因之一。
-
数据链路层增加MAC头
- MAC头表示数据包要发送到的网卡地址,MAC地址是全局唯一的
- 得到目标机器的MAC地址是基于ARP协议
- ARP协议:已知目标机器IP,发送广播消息,目标机器发送MAC地址来响应
- ARP缓存:为了避免每次都使用ARP请求,机器本地会进行ARP缓存。当机器不停地上线下线,IP有可能会变,所以ARP的MAC地址会过期
- 数据包在数据链路上进行广播,拥有目标MAC地址的网卡接收数据包,打开IP包—校验IP—打开TCP包—校验端口—请求返回
-
物理层:转化为bit流进行传输-----目标主机接收
目标主机接收处理过程
-
目标主机接收到一个以太网数据帧,数据开始从协议栈中由底向上升,同时去掉各层协议的报文首部。
-
物理层:数据经过网卡校验
-
数据链路层
- 拿到MAC头信息,检查MAC地址和当前网卡的MAC地址是否匹配
-
网络层
- 拿到IP头信息,校验IP
-
传输层:TCP头中会携带端口信息,将报文交给指定的进程或线程进行处理
-
应用层:返回数据
Q:为什么有了MAC地址所在的层还要走IP所在的层呢?
A:MAC地址是设备的唯一标识,和设备的生产者,批次,日期等信息关联起来。拿到了一个机器的MAC地址,并不能找到目标主机。要实现机器之间的通信,所有才有了IP地址的用武之地,IP地址表示了当前机器在网络中的位置。通过IP,即网络层的寻址,可以实现全世界任意两台Internet上的机器间传输数据。
负载均衡
- TCP/IP协议按照层次分为4层
- 应用层、传输层、网络层和数据链路层
- 每一层专注于当前领域的事情
- 改动影响较少
- 架构灵活性更高,更简单
- 应用层、传输层、网络层和数据链路层
分层负载
- 了解了分层的概念,便于我们去理解二层负载、三层负载、四层负载和七层负载
- 一次http请求,一定会从应用层到传输层,完成整个交互。只要是在网络上的数据包,都是完整的。可以有下层没上层,绝对不能够有上层没下层。
二层负载
- 二层负载针对MAC地址。负载均衡服务器对外提供一个Virtual IP(虚拟IP),集群中不同的机器采用相同的IP地址。当负载均衡服务器接收到请求之后,通过改写报文的目标MAC地址的方式将请求发送到目标机器实现负载均衡
- 二层负载会通过一个虚拟的MAC地址接收请求,然后分配给真实的MAC地址
三层负载
- 针对IP,和二层负载类似。区别是,负载均衡服务器接收到请求之后,根据不同的负载均衡算法,通过IP将请求转发至不同的真实服务器
- 虚拟IP接收,分配给真实IP地址
四层负载
- 四层负载工作在OSI模型的传输层。只有 TCP/UDP协议 包含了源 IP、目标IP、源端口号和目的端口号。四层负载均衡服务器在接收到客户端请求之后,通过修改数据包地址信息的方式(IP+端口号)将请求转发到应用服务器。
- 四层负载通过虚拟IP+端口接收请求,然后分发给真实的服务器
七层负载
- 工作在OSI模型的应用层。常见的应用层协议有http、radius、dns等。七层负载基于这些协议来负载
- 七层负载通过虚拟的URL或主机名接收请求,然后分配到目标服务器
TCP/IP协议的深入分析
- 网络通信流程中-http协议的底层用到了TCP协议
TCP通信协议原理
TCP通信协议基本概念
- 传输控制协议(TCP,Transmissio Control Protocol)
- 是一种面向连接的、可靠的、基于字节流的传输层控制协议
TCP协议基本认识
- TCP协议是面向连接的,用于计算机之间的通信。TCP协议在两台服务器之间建立网络连接之前要先发数据包进行沟通,沟通后再建立连接,然后才是信息的传输。
- 而UDP协议类似于广播站,通过UDP协议发布广播内容
TCP握手协议
- TCP消息的可靠性首先来自于有效的连接建立,所以在数据传输前,需要通过三次握手建立一个连接。
- 所谓三次握手,即建立TCP连接时,需要客户端和服务端总共发送三个包来确认连接的建立
- 在socket编程中,该过程由客户端执行connect来触发
第一次握手
- 客户端的TCP向B发出连接请求报文字段,其首部中的同步位SYN=1,序号SEQ=x
- SEQ=x:表示传送数据时的第一个数据字节的序号是x。保存在包头的序列号(Sequence Number)字段里
- 发送完毕后,客户端进入SYN_SEND状态等待服务器确认
第二次握手
- 服务端接收到客户端发来的请求,同意建立连接,就发回一个确认包(ACK)应答
- SYN标识位和ACK标识位均为1。服务器选择自己ISN序列号,放到seq域里。同时将确认序号(Acknowledgement Number)设置为客户的ISN加1,即x+1
- 发送完毕后,服务器端进入SYN_RCVD状态
第三次握手
- 客户端再次发送确认包,SYN标识位为0,ACK标识位为1。
- 并且把服务器发来的ACK的序号字段+1,放在确认包中发送给对方,
- 数据段放写ISN完毕后,客户端进入ESTABLISHED状态,
- 服务端接收到这个包之后,也进入ESTABLISHED状态
- TCP握手结束
SYN攻击
-
在三次握手的过程中,Server发送SYN_ACK之后,
-
收到Client的ACK之前的TCP连接称为办连接(half-open connect)
-
此时Server处于SYN_RCVD状态,当收到Client发送的ACK之后
-
Server端转入ESTABLISHED状态。
-
SYN攻击是指Client在短时间内伪造大量不存在的IP地址,并向Server不断发送SYN包,Server回复确认包
-
并等待Client确认。由于源地址并不存在,因此,Server需要不断重发直至超时
-
伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞或瘫痪
-
SYN攻击是一种典型的DDOS攻击
- 当Server上有大量半连接状态,且源IP地址是随机的,即可判断遭到SYN攻击了
TCP四次挥手协议
- 四次挥手协议是指TCP断开连接的时候,需要Client和Server总共发送4个包以确认连接的断开;
- TCP是一个全双工协议-Client和Server均可主动发起挥手操作
- 在socket编程中,任何一方执行close()操作即可产生挥手操作
关于单工、半双工和全双工
- 单工: 数据传输只支持数据在一个方向上传输
- 半双工:数据传输允许数据在两个方向上传输,但在某一时刻,只允许在一个方向上传输。
- 全双工:数据通信允许数据同时在两个方向上传输。是两个单工通信方式的结合
四次挥手图示
第一次挥手
-
FIN=1 seq=x
-
客户端发送一个FIN标识位为1的包
-
表示自己已经没有数据可以发送了,但是仍然可以接受数据
-
发送完毕,客户端进入FIN_WAIT_1状态
第二次挥手
-
ACK=1 seq=v ack=u+1
-
Server确认Client发送的FIN包,然后发送一个确认包,表示接收到Client关闭连接请求,但未准备好关闭连接
-
发送完毕确认包,Server进入CLOSE_WAIT状态
第三次挥手
- FIN=1 ACK=1 seq=w ack=u+1
- Client接收到确认包,进入FIN_WAIT_2状态,等待服务端关闭连接
- 服务端准备好关闭连接时,向客户端发送关闭连接请求,FIN设置为1.
- 发送完毕后,服务器进入LAST_ACK状态,等待来自Client的最后一个ACK
第四次挥手
- ACK=1 seq=u+1 ack=w+1
- Client接收到来自服务器端的关闭请求,发送一个确认包,并进入TIME_WAIT状态
- 等待可能出现的要求重新发送确认包
- Server接收到确认包,关闭连接,进入CLOSED状态
- Client等待了某个固定时间(2MSL,two Maximum Segment Lifetime 两个最大段生命周期)之后
- 没有收到Server的ACK包,即认为Server已经正常关闭连接,于是自己关闭连接,进入CLOSED状态
问题
Q:为什么连接的时候是三次握手,关闭的时候却是四次握手?
A:三次握手是因为Server端收到Client端的SYN请求报文后,可以直接发送SYN+ACK报文。SYN-同步,ACK-应答。但是在关闭连接时,Server端收到FIN报文,由于可能存在未处理完毕的消息,所以先回复一个ACK报文,消息处理完毕,发送FIN报文,因此需要四次挥手。
Q:为什么TIME_WAIT状态,需要经过2MSL(最大报文段生存时间)才能返回到CLOSED状态?
A:TIME_WAIT状态用来重发可能丢失的ACK报文
协议通信的使用
- TCP连接建立之后,就可以基于这个连接通道来发送和接收消息了
- TCP、UDP是基于Socket概念上为某类应用场景而扩展出的传输协议
Q:什么是Socket?
A:Socket是一种抽象层,应用程序通过socket来发送和接收数据,socket可以把应用程序添加到网络中,并与同一网络中的其它程序进行通信。不同类型的Socket与不同类型的底层协议簇有关联。
Socket类型
- 主要的Socket类型
- 流套接字-stream socket
- 把TCP作为端对端协议(底层使用IP协议),提供一个可信赖的字节流服务
- 数据报文套接字-datagram socket
- 使用UDP协议(底层使用IP协议),提供一种”尽力而为“的数据报文服务
Socket通信模型
TCP通信原理以及IO阻塞
TCP协议通信过程
- 对于TCP通信来说,每个TCP Socket的内核中都有一个发送缓冲区和一个接收缓冲区
- TCP的全双工工作模式及滑动窗口就是依赖于这两个独立的Buffer和其填充状态
- Socket的接收缓冲区被TCP用来缓存网络上收到的数据,直到应用进程读走完毕
- 如果一直未被读取,Buffer满了之后—通知对端TCP协议中的窗口关闭,保证TCP缓冲区不会移除,可靠传输
- 若是直接发送了超过窗口大小的数据,那么则会把这些数据丢弃
滑动窗口协议
- TCP的滑动窗口协议,是一种流量控制技术
- 发送方和接受方都会维护一个数据帧的序列,该序列被称为窗口
发送窗口
- 发送端允许连续发送帧的序号表
- 发送端可以不等待应答而连续发送的最大帧数成为发送窗口的尺寸
接收窗口
-
接收方允许接收的帧序号表,处理落在窗口内的帧,丢弃落在窗口外的帧
-
接收方每次允许接收的帧数称为接收窗口的尺寸
关于通信阻塞
迭代服务器
- Socket定义accept()方法来接收客户端的请求,accept()方法是一个阻塞方法
- TCP服务器一次只能处理一个客户端请求,按照顺序处理客户端的请求
IO阻塞
BIO阻塞
- 为每个客户端创建一个线程
- 一连接一线程,一请求一应答
伪异步IO
- 线程池负责连接
- M请求N应答
非阻塞IO
- 首先了解一下阻塞IO的原理,什么是阻塞IO?
- 当客户端的数据从网卡缓冲区复制到内核缓冲区之前,服务端会一直阻塞。
- 以socket接口为例,进程从调用recvfrom开始到返回的整段时间内都是被阻塞的
- 因此又被成为阻塞IO模型
非阻塞IO模型
- 为了处理更多的连接:阻塞-非阻塞
- 进程调用recvfrom,若是缓冲区没有数据,直接返回EWOULDBLOCK错误
- 应用程序不断轮询来检查内核是否有数据过来
IO复用模型
- IO多路复用的本质是通过一种机制:系统单核缓冲IO数据
- 让单个进程可以监视多个文件描述符
- 一旦某个描述符就绪(读就绪或写就绪)就通知程序进行相应的读写操作
Q:什么是文件描述符(fd)?
A:在Linux中,内核把所有的外部设备当成文件来操作,对文件的读写会调用内核系统命令,返回一个fd。而对于socket的读写来说,也有相应的文件描述符,称之为socketfd
IO多路复用方式
- Linux API提供IO复用方式
- select、poll、epoll
select
- 进程可以把至少一个的fd传递给select系统调用
- 进程会阻塞在select操作上,由select系统检测多个fd是否处于就绪状态
存在问题
- 一个fd处于就绪状态,当前进程需要线性轮询所有的fd,监听的fd越多,性能开销越大
- select系统在单个进程中能打开的fd是有限制的,默认1024
epoll
- Linux提供epoll系统的调用
- 基于事件驱动方式代替顺序扫描,性能更高
- 主要原理
- 被监听的fd中,当有fd就绪,会告知当前进程具体的fd
- epoll所支持的fd上限是操作系统的最大文件句柄,远远大于1024
多路复用的优点
- 通过把多个IO的阻塞复用到同一个select阻塞上,从而使得系统在单线程的情况下可以处理多个客户端的请求