HTTP2.0 原理详解

摘要:
压缩头HTTP/2.0指定将在客户端和服务器端使用和维护“头表”,以跟踪和存储之前发送的键值对。对于同一个标头,不需要再次通过请求发送,只需发送一次。第一个表在HTTP2.0连接期间始终存在,并由客户端和服务器逐步更新。在二进制成帧层,HTTP2.0将把所有传输的信息分成更小的消息和帧,并以二进制格式对它们进行编码。HTTP1的标头信息。x将封装在Headers帧中,而我们的requestbody将封装在Data帧中。在HTTP2实践中,Node.js被用作服务器语言。

影响一个网络请求的因素主要有两个,带宽和延迟。今天的网络基础建设已经使得带宽得到极大的提升,大部分时候都是延迟在影响响应速度。

连接无法复用

连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。

head of line blocking

head of line blocking会导致带宽无法被充分利用,以及后续健康请求被阻塞。

HTTP2.0 原理详解第1张
HTTP1.0 -> HTTP1.1

不过pipelining并不是救世主,它也存在不少缺陷:

  • pipelining只能适用于http1.1,一般来说,支持http1.1的server都要求支持pipelining

  • 只有幂等的请求(GET,HEAD)能使用pipelining,非幂等请求比如POST不能使用,因为请求之间可能会存在先后依赖关系。

  • head of line blocking并没有完全得到解决,server的response还是要求依次返回,遵循FIFO(first in first out)原则。也就是说如果请求1的response没有回来,2,3,4,5的response也不会被送回来。

  • 绝大部分的http代理服务器不支持pipelining。

  • 和不支持pipelining的老服务器协商有问题。

  • 可能会导致新的Front of queue blocking问题。

HTTP2 VS HTTP1.1

多路复用

多路复用通过多个请求stream共享一个tcp连接的方式,解决了http1.x holb(head of line blocking)的问题,降低了延迟同时提高了带宽的利用率。

HTTP2.0 原理详解第2张

压缩头部

HTTP/2.0规定了在客户端和服务器端会使用并且维护「首部表」来跟踪和存储之前发送的键值对,对于相同的头部,不必再通过请求发送,只需发送一次。

事实上,如果请求中不包含首部(例如对同一资源的轮询请求),那么首部开销就是零字节。此时所有首部都自动使用之前请求发送的首部。

如果首部发生变化了,那么只需要发送变化了数据在Headers帧里面,新增或修改的首部帧会被追加到“首部表”。首部表在 HTTP2.0的连接存续期内始终存在,由客户端和服务器共同渐进地更新。

HTTP2.0 原理详解第3张

二进制分帧

在应用层与传输层之间增加一个二进制分帧层,以此达到“在不改动HTTP的语义,HTTP 方法、状态码、URI及首部字段的情况下,突破HTTP1.1的性能限制,改进传输性能,实现低延迟和高吞吐量。”

在二进制分帧层上,HTTP2.0会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中HTTP1.x的首部信息会被封装到Headers帧,而我们的request body则封装到Data帧里面。

HTTP2.0 原理详解第4张

客户端和服务器可以把HTTP消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来。注意,同一链接上有多个不同方向的数据流在传输。客户端可以一边乱序发送stream,也可以一边接收者服务器的响应,而服务器那端同理。

HTTP2.0 原理详解第5张

请求优先级

多路复用导致所有资源都是并行发送,那么就需要「优先级」的概念了,这样就可以对重要的文件进行先传输,加速页面的渲染。

服务器推送

服务器推送是指在客户端请求之前发送数据的机制。

另外有一点值得注意的是,客户端如果退出某个业务场景,出于流量或者其它因素需要取消server push,也可以通过发送RST_STREAM类型的frame来做到。

HTTP2 实践

这里使用 Node.js 作为服务器端语言。

1. 生成TLS证书

如果想要在生产环境中使用HTTP2,那么你可以去这里生成一个证书。

如果你仅仅开发环境使用,那么我们可以自己生成一个自签名的TSL证书。

  1. 安装OpenSSH

  2. 使用OpenSSH生成私钥

    openssl genrsa -des3 -passout pass:1234 -out server.pass.key 2048`

    这里 1234 为私钥密码,如果你不想使用密码,则可以去除私钥密码,敲入如下密令:

    openssl rsa -passin pass:x -in server.pass.key -out server.key
  3. 创建 证书签名请求
    这里使用无密码私钥,如果使用带密码私钥,只需将server.key更换为server.pass.key即可,密令如下

    openssl req -new -key server.key -out server.csr
  4. 创建证书

    openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

通过以上四个步骤,我们得到了三个文件

  1. server.key 你的TSL证书私钥

  2. server.csr 你的TSL证书签名请求

  3. server.crt 你的TSL证书

2. 使用Node.js 创建服务器

安装 node-http2 模块

npm install http2

创建服务器

var options = {
  key: fs.readFileSync('./server.key'),
  cert: fs.readFileSync('./server.crt')
};

require('http2').createServer(options, function(request, response) {
  response.end('Hello world!');
}).listen(8080);

启动服务器

node index.js

使用浏览器访问

http://localhost:8080

到此,一个简单的Demo就完成了。

Demo源码下载

点击这里访问完整Demo

https://github.com/zhanyouwei...

测试结果对比

HTTP2.0 原理详解第6张

HTTP2.0 原理详解第7张

通过上面两张截图可以发现,使用了HTTP2后,同样的请求,在数据传输大小与速度上都有非常大的提升,几乎可以预见,不久的将来,HTTP2将会大放异彩。

免责声明:文章转载自《HTTP2.0 原理详解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Django配置站点WPF 分页控件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java的(SXSSF)EasyExcel阿里开源excel导出和XSSF导出简单示例

一、EasyExcel阿里开源excel导出(SXSSF) 参考链接:EasyExcel阿里开源excel导出  1、建立映射到excel文件的映射类,然后get和set import com.alibaba.excel.annotation.ExcelProperty; public class DownloadAjgl { @ExcelPro...

Werkzeug教程

http://chaoxz2005.blog.163.com/blog/static/15036542012863405266/ http://www.dajo.com.cn/a/boke/python/2013/1125/146.html 这里我们将会创建一个仿制TinyURL的应用,将URLs存储到一个redis实例。为了这个应用,我们将会使用的库包括...

跨域拦截Access-Control-Allow-Origin设置多个origin

在Extjs和java项目碰到了需要同时处理跨域,外部要访问后台接口的问题 原来的代码是这样,只能设置一个extjs前台需要过滤的跨域请求 package com.xgt.config; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import ja...

Redis操作命令大全(NodeJS版)

/*—————————————————————————————— * 本文案例基于以下运行环境: * 系统: CentOS 5.x * NodeJS版本: 0.9 以上 * Redis版本: 2.8 * Redis-nodejs 扩展: 0.12.1  /*—————————————————————————————— Part 1: 安装扩展 使用以下命令...

精讲RestTemplate第7篇-自定义请求失败异常处理

本文是精讲RestTemplate第7篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层HTTP客户端类库的切换 精讲RestTemplate第3篇-GET请求使用方法详解 精讲RestTemplate第4篇-POST请求方法使用详解 精讲Res...

责任链模式——更灵活的if else

责任链模式 责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。 这种模式给予请求的类型,对请求的发送者和接收者进行解耦。属于行为型模式。 在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象...