写点什么

HTTP/2 协议的优点解析

  • 2019-07-21
  • 本文字数:2867 字

    阅读完需:约 9 分钟

HTTP/2协议的优点解析


HTTP 协议于 1991 年引入,至今已有近 30 年的历史。自第一个文档化版本(后来称为 0.9)以来,它已经经历了一段相当长的历程。在本文中,我们将简要回顾 HTTP 协议的发展历史,重点介绍 HTTP/2 带来了什么,以及我们如何从中获益。我们将使用 Node.js 服务端来实现它。

HTTP 协议简史

HTTP 的第一个版本只能传输超文本标记语言(HTML)文件,因此我们称之为超文本传输协议。它真的很简单,唯一可用的方法就是 GET。它没有 HTTP 头文件或状态代码。如果出现问题,服务器可以使用带有错误描述的 HTML 文件进行响应。


1996 年 1.0 版本出现了。与前一个版本相比,它进行了许多改进,其中最重要的是状态代码、POST 和 header 等附加方法。现在,我们可以使用 Content-Type 头来传输普通 HTML 之外的文件。


1997 年发布的 HTTP/1.1 引入了一些其它的改进。除了添加像 OPTIONS 这样的方法外,它还引入了 Keep-Alive 头。它允许一个连接对多个 HTTP 请求保持打开状态。因为这点,连接不必在每次请求之后关闭,然后再重新打开。在 HTTP/1.1 中,我们通常一次只能有 6 个连接。例如,如果其中一个请求由于服务器上的某些复杂逻辑而卡住,那么它们中的每一个都可以一次处理一个请求,整个连接就会冻结并等待响应。这个问题称为前端阻塞。

实现 Node.js HTTP/2 的好处

堆栈中有很多实现 HTTP/2 的方法。一种常见的方法可能是在 web 服务器上实现它,但是在本文中,我们在应用程序层中实现它,以便拓展 Node.js 的相关知识。因为浏览器不支持未加密的 HTTP/2,这意味着我们需要通过 HTTPS 协议实现 TLS 连接。要在本地完成此操作,我们使用以下命令生成证书:


openssl req -x509 -newkey rsa:4096 -keyout key.pem -out certificate.pem -days 365 -nodes
复制代码


如果你想了解详细信息,请查看《使用OpenSSL证书实现HTTPS》


import * as http2 from 'http2';import * as fs from 'fs';import * as util from 'util'; const readFile = util.promisify(fs.readFile); async function startServer() {  const [key, cert] = await Promise.all([    readFile('key.pem'),    readFile('certificate.pem')  ]);    const server = http2.createSecureServer({ key, cert })    .listen(8080, () => {      console.log('Server started');    });   server.on('stream', (stream, headers) => {    stream.respond({      'content-type': 'text/html',      ':status': 200    });    stream.end('<h1>Hello World</h1>');  });   server.on('error', (err) => console.error(err));} startServer();
复制代码

解决某些复杂应用程序中的前端阻塞问题

即使使用 HTTP/1.1 进行 6 个并行连接也可能不够用,尤其是当我们遇到前端阻塞时。HTTP/2 通过允许一个连接同时处理多个请求解决了这个问题,这是因为即使其中一个请求被卡住,其它的请求也可以继续。在上面的这个简单示例中,我们使用普通 HTML 进行响应。每当有人向我们的服务器发出请求时,流事件就会触发。


如果你想了解更多关于流的信息,请查看《可读流的暂停和流动模式》《可写流、管道和流程流》


在 headers 参数中,我们有即将到来的请求的所有 header。它是一种检查方法,比如请求的方法和路径。现在,由于我们使用 HTTP/2,浏览器使用一个非阻塞的连接。一个可以关注的例子是Golang团队创建的一个网格演示。在使用 HTTP/2 时,由于在同一连接上处理并行请求和处理前端阻塞问题,你可以看到性能的显著提高。

报头压缩

HTTP/2 使用了一种新的报头压缩算法,我们称之为 HPACK。一些参与定义 HTTP/2 协议的开发人员也在开发 SPDY,它以前也用于压缩报头。不幸的是,后来人们发现它容易受到 CRIME 攻击。HPACK 不仅使整个过程更加安全,而且在某些情况下速度更快。

使用服务端推送缓存数据

当我们实现 HTTP/2 时,上面所有的改进都是开箱即用的。这并不是它全部的能力。通过服务器推送,我们现在可以在客户机缓存中填充数据。我们甚至可以在浏览器请求之前完成。一个基本的使用场景是当用户请求 index.html 文件时的情况。


server.on('stream', (stream, headers) => {  const path = headers[":path"];  switch(path) {    case '/': {      stream.respond({        'content-type': 'text/html',        ':status': 200      });      stream.end(`         <head>          <link rel="stylesheet" type="text/css" href="style.css">        </head>        <body>          <h1>Hello World</h1>        </body>      `);      break;    }    case '/style.css': {      stream.respond({        'content-type': 'text/css',        ':status': 200      });      stream.end(`        body {          color: red;        }      `);      break;    }    default: {      stream.respond({        ':status': 404      });      stream.end();    }  }});
复制代码


在上面的示例中,当用户访问主页时,它请求 index.html 文件。当它得到一个样式表时,它会注意到还需要 style.css 文件。在请求 index.html 和 style.css 之间有一些延迟,我们可以使用服务端推送来处理它。因为我们知道用户将需要 style.css 文件,所以可以将它与 index.html 一起发送。


server.on('stream', (stream, headers) => {  const path = headers[":path"];  switch(path) {    case '/': {      stream.pushStream({ ':path': '/style.css' }, (err, pushStream) => {        if (err) throw err;        pushStream.respond({          'content-type': 'text/css',          ':status': 200        });        pushStream.end(`          body {            color: red;          }        `);      });      stream.respond({        'content-type': 'text/html',        ':status': 200      });      stream.end(`         <head>          <link rel="stylesheet" type="text/css" href="style.css">        </head>        <body>          <h1>Hello World</h1>        </body>      `);      break;    }    case '/style.css': {      stream.respond({        'content-type': 'text/css',        ':status': 200      });      stream.end(`        body {          color: red;        }      `);      break;    }    default: {      stream.respond({        ':status': 404      });      stream.end();    }  }});
复制代码


现在使用 stream.pushStream 只要有人请求 index.html,我们就发送 style.css 文件。当浏览器处理它时,它会看到<link>标记,并注意到它还需要 style.css 文件。由于服务端推送,它已经缓存在浏览器中,因此不需要发送另一个请求。


总结

HTTP/2 旨在通过满足日益复杂的 web 页面的需求来提高性能。我们使用 HTTP 协议发送的数据量增加了,HTTP/2 通过处理前端阻塞等方法解决了这个问题。另外由于在同一连接上处理并行请求,这也解除了 HTTP/1.1 的一些限制。


英文原文:https://wanago.io/2019/07/15/node-js-typescript-benefits-http2-protocol/


2019-07-21 15:118214

评论

发布
暂无评论
发现更多内容

【活动报名】 拥抱公平《 Impact Tech, She Can 》

亚马逊云科技 (Amazon Web Services)

人工智能

开门见山|首期《崖山论“见”》技术 Meetup启程

YashanDB

在 Kubernetes 中部署应用交付服务(第 1 部分)

NGINX开源社区

软件测试/测试开发丨app自动化测试之Appium 源码修改定制分析

测试人

软件测试 自动化测试 测试开发 appium

瓴羊Quick BI数据门户,让管理企业像浏览网页一样轻松

对不起该用户已成仙‖

2023年好用的谷歌浏览器插件推荐(Chrome必备扩展程序) 安装教程

互联网搬砖工作者

小程序营销模板的发展现状及前景分析

没有用户名丶

小程序

矩阵佛萨奇(MetaForce)合约开发源码搭建

薇電13242772558

web3

ChatGPT能否取代程序员?仍然是一个需要认真探讨的问题,对此你怎么看?

兴科Sinco

OpenAPI openai #人工智能 ChatGPT

BugBuilder: 高质量大规模缺陷库自动构建方法

华为云开发者联盟

开发 华为云 补丁 华为云开发者联盟 企业号 3 月 PK 榜

JAVA实战:如何让单元测试覆盖率达到80%甚至以上

Java你猿哥

Java ssm 单元测试 Java工程师 java实战

模型训练过程中,混合精度训练稳定性解决方案

Openlab_cosmoplat

模型训练 开源社区

ITSM | 如何通过设计提升工单处理效率

嘉为蓝鲸

IT ITSM 流程管理

MySQL中这14个小玩意,让人眼前一亮!

Java你猿哥

Java MySQL 后端 ssm Java工程师

2023年实用性好的堡垒机推荐

行云管家

网络安全 堡垒机

开发和测试融合,到底该怎么做?

BY林子

敏捷开发 敏捷测试

gRPC快速整合SpringCloud

Java你猿哥

Java gRPC Spring Cloud 后端 ssm

精华抢先看|龙蜥社区操作系统安全两大白皮书即将重磅发布

OpenAnolis小助手

操作系统 白皮书 系统安全 Meetup 龙蜥社区

电力行业等保定级评级依据是什么?分为几个等级?

行云管家

电力 等保 等保测评

蛇形走线用在哪里,一文告诉你

华秋PCB

信号 PCB PCB设计 布线 滤波

手把手教你如何使用MyBatisPlus

Java你猿哥

mybatis 实战 Mybatis-Plus

2023飞书未来无限大会谢欣演讲highlight:三件套、Office提升、出海

B Impact

优秀!阿里甩出GC面试小册,仅7天Github获赞96.9K

Java你猿哥

Java ssm 面经 GC Java工程师

记一次 rr 和硬件断点解决内存踩踏问题

NebulaGraph

数据库 debug

XLD音频无损解码器:X Lossless Decoder中文激活版

真大的脸盆

Mac Mac 软件 音频解码 音频处理工具 音频管理

赋能数字经济新动能 焱融科技获评「人工智能高质量发展-行业责任担当」企业

焱融科技

人工智能 文件存储 容器存储 分布式文件存储 全闪存储

聊聊池化层和步长为2的卷积层

华为云开发者联盟

人工智能 华为云 华为云开发者联盟 企业号 3 月 PK 榜 卷积层

大数据计算引擎 EasyMR:拥抱开源,引领技术创新

袋鼠云数栈

大数据 大数据基础平台

直击面试!阿里技术官手码12W字面试小册在Github上爆火

Java你猿哥

Java 后端 面经 简历 Java工程师

HTTP/2协议的优点解析_语言 & 开发_wanago​_InfoQ精选文章