http1.0/1.1/2.0/3.0

智极漫步
• 阅读 2832

http1.0

  • http是无状态链接,即他只管链接,不管你们之前是否链接过,故通常通过设置cookie来记录用户的登录状态,服务器生成session来用记录用户登录的上下文,并生成sessionId来唯一标识这条记录,然后将其放到响应头李,后续浏览器发起请求再次带上该请求头,即可分辨其用户状态;
  • http基于TCP链接,从建立链接到断开要经过三次握手以及四次挥手,并且一个http链接只新建一个tcp链接,请求以及响应以文本形式传输,每次传输完数据就断开链接;
  • 同时如果发生了丢包,需要重新建立tcp链接
  • 这就导致了http1.0下传输效率其实并不高,每个资源的请求以及响应都要在队列中进行排队,等待传输

http1.1

  • 为了解决上面的问题,提出了http1.1
  • http1.1默认使用长链接,减少了tcp建立链接耗费的时间
  • 同时http1.1支持pipeline,即允许在一个tcp连接上发起多个请求,但是这种特性有个限制,就是虽然可以发起多个请求,但请求本身的发起是有先后顺序的,同时要求服务器的返回也需要按照这个顺序返回,不然无法识别响应对应哪个请求
  • 也就是http1.1的pipeline其实节省的是发起请求的时间,允许同时发起请求,而无需等下一个请求回来后再发起第二个请求
  • 但由于这种机制限制较多,实现起来比较麻烦,现代浏览器多数是通过建立多个tcp链接来实现并发的,同时由于浏览器本身的限制,一并允许兵法的tcp链接数量为6个

http2.0

  • 为了真正解决并发的问题,提出了http2.0
  • http2.0采用了叫做多路复用的技术,就是将报文以二进制的形式编码,同时将其分为多个帧,叫做二进制帧,同一个请求的二进制帧带有相同的标识,供接收方将其拼凑成一个完整的报文
  • 同时http2.0所有请求都是建立在一个tcp连接上,通过二进制帧的技术,无需像http1.1那样要求响应顺序与请求顺序一致,服务器先收到哪个请求就先响应该请求,浏览器可以通过标识得到完整报文
  • 另外,http2.0还采用了头部压缩的技术,简单讲就是在服务器和浏览器各自维护一份相同的请求头字典,后续请求头的发送就直接用字典的key值进行代替,减少传输量
  • 并且http2.0允许从服务器推送消息到浏览器,通过预测浏览器的请求,服务器可以提前把所需资源推送给浏览器,减少资源传输的时间
  • 但是http2.0依然有没被解决的问题,那就是丢包时的性能问题
  • 由于tcp协议本身的限制,数据传输采用的是应答机制,数据包发送后需要得到接收方的回复,若超时未收到回复,即认为当前发送的包丢失了,需要重新发送
  • 同时tcp通过“滑动窗口”的机制来提升传输效率,即尽可能多的发送数据包而无需等待,但这个无需等待发送的量是有上限的,换句话说他是通过批量发送。批量确认应答来进行数据传输,发送方会根据收到的最大连续序列的包来移动窗口,而如果某个包丢失了,没有发回应答,那么窗口就会停止移动,进行数据包的重新发送
  • 而http2.0的所有请求都是建立在一个tcp请求上的,也就是说某个请求的丢包会阻塞别的请求的发送

QUIC(http3.0)

  • QUIC - quick udp internet connection,是谷歌提出的一个协议,他放弃了使用tcp而转向udp协议
  • udp与tcp不同,无需等待应答,一旦建立链接,只管进行数据的发送,一般用在实时通话或视频等,对时效性要求高的场景中
  • QUIC解决http2.0的阻塞问题,根本思路就是,无需批量等待应答,某个数据包的应答收到后,就将窗口后移,发送下一个包
  • tcp的数据传输是基于sequence_no和ack来确保可靠性的,其中sequence_no是数据包中字节的序号,而ack是基于sequence_no加一,发生丢包时,必须等待该包重新发送,并收到ack应答,才能继续往下走,否则如果跳过丢失的包继续往前走,就无法知道哪些包丢失了
  • 结合前面的滑动窗口,接收方会根据自身收到的包,对应发回ack
  • 如果接收方接收到的sequence_no是连续的,发送方只需要确认最后一个ack即可,根据这个ack即可移动窗口
  • 但如果发现数据包中的sequence_no不是连续的,接收方就会返回最近一个ack,当发送方接收到3次相同的ack时,就得知数据丢包了,就要重新进行数据的发送,同时因为发送方不知道除了ack代表的那个包丢失外还有没有别的包丢失了,所以很可能需要将丢失包开始的所有数据重新发送一遍,即使接收方可能已经接收到了这些包,所以tcp丢包时不仅造成阻塞还浪费带宽
  • QUIC,它采用的是packet_no来确保可靠性,该标识从0开始,每发送一个包就加一,即使丢包了,重新发送时也是基于当前的packet_no加一
  • 同时,QUIC利用多路复用时的strem_id以及QUIC新增的stream_offset来判断当前的数据包的正确序列,offset即当前数据包在整个数据流中的偏移量,这样即使packet_no不一致,也可以通过stream_id和stream_offset识别数据包顺序进行重组,换句话说QUIC支持乱序传输数据
  • 与tcp不同,中间ack的丢失对数据传输影响不大,因为其只需要确认最后一个ack即可,但QUIC要求每个数据包都有明确的ack返回,没返回的就认为是丢包了
  • QUIC就是通过这种方法提供数据的传输效率
  • QUIC另外还提供了纠错机制,通过增加一个冗余包的发送,当发生仅一个包丢失的时候,可以根据之前接收的包与冗余包反推出丢失的那个包
  • 原理是将所有数据包进行异或求值得出冗余包,即假设有5个包,异或出一个冗余包,共六个,根据异或的原理

    • 相同数异或为0
    • 0与任何数异或等于那个数本身
  • 假设现在丢失了3号包,只需要将1、2、4、5以及冗余包一起进行异或运算即可得到3号包
  • 虽然这种纠错机制只能在仅丢失一个包的基础上生效,但根据网络环境,选取适当的包的总数进行异或处理,可能基本防止丢包重传的情况
  • 最后,QUIC采取了类似TFO(TCP fast open)的思想,通过cookie的缓存识别客户端身份,实现了首次连接耗时1-RTT(Round-Trip Time),后续连接0-RTT的开销

https:

  • 简单说一下对称加密和非对称加密
  • 对称加密,通过一个token对数据进行加密编码,服务器接收到加密数据后用同一个token解密,但这种形式容易被破解
  • 非对称加密,使用公钥加密,只能用私钥才能解开,所以服务器生成公钥,然后传给客户端,客户端使用公钥加密后,回传服务器,服务器用私钥解密,这样能防止信息被盗,但非对称加密运算量大,十分消耗性能
  • 通常采用对称加密和非对称加密相结合的方法,客户端请求服务器,服务器生成一个公钥传给客户端,客户端生成一个随机数,利用公钥,进行非对称加密,然后把这个加密的信息返回服务器,服务器利用私钥进行解码,得到客户端生成的随机数,后续数据传输,客户端使用自己生成的随机数对信息进行对称加密,这样就既保证对称加密token不被暴露,也保证了传输效率
点赞
收藏
评论区
推荐文章
Chase620 Chase620
4年前
记录Vue项目实现axios请求头带上token
在vue项目中首先npm命令安装axios:npminstallaxiosSaxios的封装使用请求带上token,token通过登录获取存在vuex,为防止刷新丢失token使用持久化vuexpersistedstate插件保存数据npmiSvuexpersistedstateimportpersistedStat
_dolphin _dolphin
4年前
.net core Cookie的使用
缘起:  公司领导让我做一个测试的demo,功能大概是这样的:用户通过微信扫一扫登陆网站,如果用户登录过则直接进入主界面,否则就保留在登录界面。实现方法:  首先先把网站地址生成个二维码,在扫描二维码后去获取Cookie如果有值那么就证明登录过直接跳转到主界面,如果Cookie不存在用户通过登录记录的用户信息并保存到Cookie。什么是Cookie:  储存
喷火龙 喷火龙
4年前
cookie和session的详解与区别
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。本章将系统地讲述Cookie与Session机制,并比较说明什么时候不能用Cookie,什么时候不能用Session。1.1 C
Stella981 Stella981
3年前
Django用户认证
COOKIE与SESSION概念cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这
Stella981 Stella981
3年前
JWT 在 Web 服务中进行无状态授权的原理
JWT指的是JSONWebTokens,是一串数据加密后生成的Token字符串,通过以下方式服务器端可以判定客户端的身份。1、客户端用户userA使用用户名密码登录服务器2、服务器返回给用户数据和一串Token3、userA再次请求数据带上Token,而不用再次输入用户名密码4、服务器解密Token,拿出其中标识用户
可莉 可莉
3年前
21.Shiro在springboot与vue前后端分离项目里的session管理
1.前言当决定前端与后端代码分开部署时,发现shiro自带的session不起作用了。然后通过对请求head的分析,然后在网上查找一部分解决方案。最终就是,登录成功之后,前端接收到后端传回来的sessionId,存入cookie当中。之后,前端向后端发送请求时,请求Head中都会带上这个sessionid。后端代码通过对这个se
Stella981 Stella981
3年前
Django_cookie和session
cookie和session1.cookie:在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次
Wesley13 Wesley13
3年前
HttpHandler
 今天简单的做下HttpHandler的练习:只有登录用户才能下载images下地图片文件(Session中标识是否登录),如果用户没有登录则首先重定向到登录界面让用户登录,用户登录成功则跳转到下载列表页面,下载链接固定写好即可。如果登录用户是普通用户则在图片左上角加上“免费用试用”的字样。1.首先建立名为UserAuthority的数据库,然后新建
Stella981 Stella981
3年前
SpringBoot整合SpringSeesion实现共享Session方案
Http协议本身是无状态的,为了保存会话信息,浏览器Cookie通过SessionID标识会话请求,服务器以SessionID为key来存储会话信息。在单实例应用中,可以考虑应用进程自身存储,随着应用体量的增长,需要横向扩容,多实例Session共享问题随之而来。下面假设我们使用Nginx来实现负载均衡横向扩节点:!(https://oscimg
Easter79 Easter79
3年前
SpringBoot整合SpringSeesion实现共享Session方案
Http协议本身是无状态的,为了保存会话信息,浏览器Cookie通过SessionID标识会话请求,服务器以SessionID为key来存储会话信息。在单实例应用中,可以考虑应用进程自身存储,随着应用体量的增长,需要横向扩容,多实例Session共享问题随之而来。下面假设我们使用Nginx来实现负载均衡横向扩节点:!(https://oscimg
3A网络 3A网络
2年前
一文读懂浏览器存储与缓存机制
一文读懂浏览器存储与缓存机制浏览器存储CookieCookie是HTTP协议的一种无状态协议。当请求服务器时,HTTP请求都需要携带Cookie,用来验证用户身份。Cookie由服务端生成,存储在客户端,用来维持状态。通常Cookie由以下值构成:名称(name)值(value)域(Domain)值(value)路径(Path)