HTTP

http是目前应用最广泛的应用层协议,截止到目前为止已经发布了多个版本,最常用的是http1.1和http2。

http0.9是最早的版本,功能很简单,没有header,只支持GET。

http1.0

  • 只支持短连接,即每次请求一个资源就会新建一次tcp连接,服务器写完响应行后立刻将TCP连接关闭

    由于tcp连接的建立和关闭需要经历三次握手和四次握手,再加上tcp慢启动特性,报文一开始不会满负荷传输,所以不仅开销很大,而且效率很低。

  • 相比于上一版本,增加了http header,和status code用于声明请求的结果,content-type字段也可以用来声明传输其他文件,头部还增加了协议的版本号。

http1.1是1997年发布的,是现在使用最广泛的版本,这个版本引入了长连接,减少了tcp连接建立和关闭的消耗。

  • 新加了connection请求头字段,false表示短连接,keep-alive表示长连接(默认)

    在持久连接模式中,由于服务器不会立刻关闭TCP连接,所以需要在响应中加上一个Content-Length的响应头来表示响应体的长度,让浏览器判断HTTP响应是否结束。如果没有这个响应头的话,浏览器会处于pending的状态,因为在它看来还有数据要接收。

    所以长连接无非就是通过Content-Length字段把连接关闭的主动权交给了客户端。

  • 支持分块传输编码,可以发送动态数据,只在1.1版本中可以使用

    使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小,使得服务器可以发送动态生成的数据。

    设置相应头Transfer-Encoding:chunked,此时消息体便由数量未定的块组成,并以最后一个大小为0的块结束。

    HTTP/1.1 200 OK\r\n
    \r\n
    Transfer-Encoding: chunked\r\n
    ...\r\n
    \r\n
    <chunked 1 length>\r\n
    <chunked 1 content>\r\n
    <chunked 2 length>\r\n
    <chunked 2 content>\r\n
    ...\r\n
    0\r\n
    \r\n
    \r\n

其他的改变还有增加了Host头,让服务端知道用户请求的是哪个域名等。

2014年,更新了内容,增加了TLS支持,即https传输,除了短连接和长连接模型,还支持服务端push模型,websocket模型。

Http2是2015年发布的,主要就是提升安全性与性能,gRPC底层就是使用的http2协议。

  • 多路复用(Multiplexing):就是说 HTTP/2 可以重复使用同一个 TCP 连接,并且连接是多路的,多个请求或响应可以同时传输,这也是gRPC支持客户端流和服务器端流的原因

    • 对比之下,HTTP/1.1 的长连接也能复用 TCP 连接,但是只能串行,不能“多路”。

    • Rest API通常构建在http1.1上,是请求响应模式。如果一个微服务收到多个客户端请求,每次只能处理一个,即使构建在http2上,依旧是请求响应模式,无法发挥http2的优势:多路复用。

      gRPC构建在http2上,支持流式通信和双向通信,通过不断流式传输信息同时处理这些请求。但双向流模式依旧需要客户端发起调用。这里的流式通信,不是全双工的,只是将原本的请求响应风格,变为了同时可以发送多个请求,服务器也能发送多个响应。

  • 二进制协议:HTTP/2 的消息头使用二进制格式,而非文本格式。并且使用专门设计的 HPack 算法压缩。

  • 服务器推送:服务端能够直接把资源推送给客户端,当客户端需要这些文件的时候,它已经在客户端了。(HTTP/2推送服务器只能被浏览器来处理,而不是应用)

  • 通讯双方cache一份header filed表,用来差量更新头部字段,避免重复header的传输

HTTP3

2018年发布,基于谷歌的QUIC,底层使用udp代码tcp协议,

这样解决了队头阻塞问题,同样无需握手,性能大大地提升,默认使用tls加密。

WebSocket

websocket是一个双向通信协议,它在握手阶段采用http1.1

握手过程

  1. 发起握手请求

    HTTP/1.1 101 Switching Protocols  // 状态行
    Upgrade: websocket // required
    Connection: Upgrade // required
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= // required,加密后的 Sec-WebSocket-Key
    Sec-WebSocket-Protocol: chat // 表明选择的子协议
  2. 服务器如果支持websocket,返回101响应

    HTTP/1.1 101 Switching Protocols  // 状态行
    Upgrade: websocket // required
    Connection: Upgrade // required
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= // required,加密后的 Sec-WebSocket-Key
    Sec-WebSocket-Protocol: chat // 表明选择的子协议

WebSocket 提供两种协议:不加密的 ws:// 和 加密的 wss://. 因为是用 HTTP 握手,它和 HTTP 使用同样的端口:ws 是 80(HTTP),wss 是 443(HTTPS)

HTTP2 vs WebSocket

WebSocket是全双工的,可以双向通信,主要应用在实时通信的场景中,服务器可以实时推送数据给客户端。

HTTP/2 虽然也支持 Server Push,但是服务器只能主动将资源推送到客户端缓存!那不是应用程序可以感知的,主要是让浏览器(用户代理)提前缓存静态资源。

在典型的HTTP 1.x工作流中,浏览器请求一个页面,服务器在响应中返回一个HTML,然后就时等待浏览器解析响应并发送额外请求来获取额外的内嵌资源(JavaScript、CSS等)。服务器推送使服务器能够试探性地向客户端发送资源。此时,浏览器不必解析HTML页面并找到需要加载的其它资源;而是服务器能够立即开始发送它们。

但是人类的想象力是非常丰富的。比如为了让服务器可以推送消息给客户端,使用了一个“偏方”。它就是SSE(Server Sent Event)。SSE是一种让服务器能够在客户端服务器建立连接之后异步推送数据给客户端的机制。由于SSE是基于HTTP的,其天然适配于HTTP/2,这样SSE就可以集两者之长:HTTP/2可以基于多路复用流形成一个高效传输层,同时SSE给应用提供了API使之能够进行推送。

Websocket技术可能会继续使用,但是SSE和其EventSource API同HTTP/2的能力相结合可以在多数场景下达到同样的效果,但是会更简单。

HTTP2和WebSocket的更多相关文章

  1. Android okHttp网络请求之Get/Post请求

    前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...

  2. Android网络框架比较

    今天,公司需要为一个安卓app选择一个合适的网络框架,具体我了解,主要的安卓网络框架有okhttp,retrofit,android-async-http,volley. 查找网上的资料,大致可以得到 ...

  3. Jetty 9.3庆祝20周年生日快乐,并添加HTTP/2支持

    本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2015/06/Building-Distributed-Systems 今年6月12日 ...

  4. channels 2.x的使用

    转载:https://www.vimiix.com/post/2018/07/26/channels2-tutorial/ 认识 Channels 之前,需要先了解一下 asgi ,全名:Asynch ...

  5. [转载]前端 阿里p6面试题集锦含答案

    1.说一下你了解CSS盒模型. 盒模型分为:IE的怪异盒模型和标注浏览器的盒模型,然后可以通过box-sizing属性控制两种盒模型的变换. 2.说一下box-sizing的应用场景. 这个也不难,简 ...

  6. 3月web前端面试小结

    说一下box-sizing的应用场景 box-sizing的属性值分为两个,border-box和content-box,其中, border-box:width=content+padding+bo ...

  7. jdk11新特性

    JDK 11主要特性一览 jdk11即将在9月25号发布正式版.确定的新特性包括以下17个 181 嵌套类可见性控制 309 动态文件常量 315 改进 Aarch64 Intrinsics 318 ...

  8. 详解golang net之transport

    关于golang http transport的讲解,网上有很多文章读它进行了描述,但很多文章讲的都比较粗,很多代码实现并没有讲清楚.故给出更加详细的实现说明.整体看下来细节实现层面还是比较难懂的. ...

  9. HttpCanary——最强Android抓包工具!

    迎使用HttpCanary——最强Android抓包工具! HttpCanary是一款功能强大的HTTP/HTTPS/HTTP2网络包抓取和分析工具,你可以把他看成是移动端的Fiddler或者Char ...

随机推荐

  1. Android Service VS AsyncTask VS Thread

    这三种方式的设计目的是不同的. Service: 适用于在后台长期持续运行的动作,如:播放音乐,查看网络数据.注意,在开发文档中,service本身是在UI线程中,所以所需的操作应该创建一个新的线程来 ...

  2. Table.ReorderColumns移动…Reorder…(Power Query 之 M 语言)

    数据源: 至少两列 目标: 列顺序重新排列 操作过程: 选取待移动的列>鼠标拖放列标题 选取待移动的列>[转换]>[移动]>选取 M公式:  = Table.ReorderCo ...

  3. 深刨显式锁ReentrantLock原理及其与内置锁的区别,以及读写锁ReentrantReadWriteLock使用场景

    13.显示锁 在Java5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile.Java5.0增加了一种新的机制:ReentrantLock.与之前提到过的机 ...

  4. 小迪安全 Web安全 基础入门 - 第十天 - 信息打点-APP&小程序篇&抓包封包&XP框架&反编译&资产提取

    一.本节知识点思维导图 二.APP-外在资产收集 1.将APP安装在模拟器中,修改模拟器代理设置,使用Fiddler.Burpsuite.Charles等抓包工具抓取APP访问的http协议数据包,抓 ...

  5. LuoguP2378 因式分解II 题解

    Content 输入一个多项式 \(x^2+ax+b\)(不保证 \(a,b\neq0\)),请对这个多项式进行因式分解(形式为 \((x-x_1)(x-x_2)\),其中 \(x_1>x_2\ ...

  6. LuoguP7593 凑数 题解

    Content 给定 \(n\) 个整数 \(1,2,\dots,n\),请问是否能从这 \(n\) 个数中恰好选 \(k\) 个数,使得这 \(k\) 个数的和为 \(s\). 数据范围:\(t\) ...

  7. 简单聊聊mysql的脏读、不可重复读

    最近,在一次 mysql 死锁的生产事故中,我发现,关于 mysql 的锁.事务等等,我所知道的东西太碎了,所以,我试着用几个例子将它们串起来.具体做法就是通过不断地问问题.回答问题,再加上" ...

  8. JAVA整合kaptcha生成验证码 (字母验证码和算术验证码)

    引入maven <!--图片验证码--> <dependency> <groupId>com.github.penggle</groupId> < ...

  9. software engineer's resume(帮助你写程序员简历)

    关键词 参考 简历模板 参考 下面开始是正文(关键词原文) 介绍 本项目由海外兔 (https://osjobs.net) 维护,海外兔团队由一线互联网面试官组成,提供海内外公司一对一入职套餐以及算法 ...

  10. 【LeetCode】663. Equal Tree Partition 解题报告 (C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...