HTTP2 学习
一、HTTP1.x存在的问题
Http1.0时Connection无法复用,同一时间一个Connection只能处理一个request。Http1.1引入了Request pipelining来解决这一问题,Request pipelining。

Requestpipeling在FIFO基础上支持同一Connection并发处理多个Request,这里的FIFO是指Http Response发送顺序必须与Request的发送顺序保持一致。
详情前往https://en.wikipedia.org/wiki/HTTP_pipelining。
然而它并不完美,仍然有HOL Blocking问题。

所谓的行首阻塞是因于FIFO的原因,导致后面的Reponse由于其之前的Response由于资源抢占等原因无法输出而Block。
由于这样的限制,HTTP/1.0及HTTP/1.1时代需要对Server端创建多个连接,通过提高并发度来降低Latency。
另外Http2支持Header压缩,而Header压缩在此前是不支持的,此前一般是对body进行gzip压缩。
二、HTTP2的解决方案
HTTP2在协议上真正要求不同的Request可以在同一个Connection上交错进行,真正做到多路复用。所带来的好处显而易见,更少的Connection,更好的并发,更高效的网络资源利用。
支持流量控制及请求优先级,使得重要的请求优先得到处理,这一点对于应用来说是个大的优化点,以体验为目标,对不同的请求划分优先级以及流量控制,比如异步加载的内容重要性低,可以设置较低优先级。但是个人觉得这一点要做好很难,要依赖于浏览器,应用服务器,应用程序三个地方都有非常好的实现,是否是合理的实现还需要好的度量平台,视效果而定。
Server Push机制支持Server端应用程序可以预先输出内容暂未需要的内容,从而降低潜在的延时。举例:可以把css内容与html内容同步输出,而不需要等待html完全输出后,浏览器再加载css。
支持对Http Header进行压缩。
高效的二进制格式(相对文本格式)传输。
三、原理分析
将通过Jetty源码来分析Jetty如何支持Http2的
Jetty源码地址:git://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git
A. Jetty.io&Jetty.server主要类结构图:
Jetty.io主要是对EndPoint及Connection的定义和基本实现,Jetty.server实现了络的交互过程,包装了Socket,Channel,多路复用等实现。这两个包一起对应用程序端或协议格式端提供了网络交互过程,从而实现网络交互过程对于协议及应用的透明。

B. 与Http2协议的结合:
Jetty Basic如上图已经介绍,HTTP2的实现只扩展ServerConnection,ServerConnectionFactory即可,相当于Jetty内核上增加插件,扩展性好,另外也不需要关注网络细节

C. 对重点类的重点解读:
| 类名 | 职责 | 详细介绍 |
|---|---|---|
| HTTP2Flusher | Frame输出控制类 | 重点说明: HTTP2Flusher类中保存了各种Entry队列,Entry中包含Frame数据,其对应的Stream引用,以及对应的CallBack。 主要属性: Queue<WindowEntry> windows,WindowUpdateFrame类型的保存队列 ArrayQueue<Entry> frames,Frame数据队列 主要方法: window(), prepend(), append(), remove()等都是针对如上Queue的操作 process()真正执行Frame的输出。首先执行Window队列,将Window的窗口设置数据写入到对应的Stream或Session中;然后执行WindowsSize的限流逻辑,若对应的Session或Stream当前WindowSize不大于0,则不发送Frame,否则将WindowSize减去当前Frame的Size,应用于下次限流。最后调用Session中的EndPoint类的write方法将Frame输出 |
| FlowControlStrategy | 流控接口定义 | 重点说明: 其实现类主要实现了依据发送或接收的Frame的数据length,依据固定策略改写Session及Stream的WindowSize,以及Stream另一端EndPoint对于WindowSize的要求,完成输科和输出限流的完整逻辑 |
| Http2Session | ISession的实现类 | 主要属性: 1. EndPoint endPoint, 表征了此Session的网络端点,对于网络的操作通过调用endPoint的方法实现 2. Generator generator,用于按需生成各种格式的Frame,Frame被最终写入endPoint中 3. Listener listener,Session中被动接口的逻辑实现,面向接口编程,支持多种实现 4. FlowControlStrategy flowControl前面已经讲述 5. HTTP2Flusher flusher前面也已讲述 主要方法: 1.newStream(),创建新的流对象,以及HeaderFrame,将流写入Session的流缓存中,流缓存通过ConcurrentHashMap实现;并将流和HeaderFrame追加到Http2Flusher对象的ArrayQueue中; 2. push(), settings(), ping(), reset()的实现雷同,最终都是将对应格式的Frame放入Http2Flusher的ArrayQueue中。Http2Flusher是真正输出Frame的控制类。 3. onData(),接收DataFrame时的处理方法,首先更新当前FlowControl对象中的WindowSize,并执行Window限流逻辑,若未超出限流控制,则调用Stream的处理方法处理接收到的数据,否则直接丢弃当前Frame,最后将WindowSize恢复之前值 4. onHeaders()接收HeaderFrame时的处理方法,抽象方法,交由子类实现 5. onPriority(),Jetty默认未支持客户端发起的对优先级的支持 6. onReset(), onSettings(),onPing(),onGoAway(),onWindowUpdate(),onConnectionFailure()执行对应逻辑,通过Listener接口,支持对于这些请求数据的自定义实现 |
| HTTP2Stream | IStream的实现类 | 重点说明: 实现了IStream的主动接口及其被动接口Stream.Listener。其主动接口一般是通过调用对应的ISession接口实现 |
| HTTP2ServerSession | 继承HTTP2Session,实现Server端Session特有的逻辑 | 重点说明: 特有逻辑包括ServerSession在接收onPreface时,需回复一个Settings Frame;在接收Headers请求时需创建RemoteStream对象;当接收ServerPush时,报出异常,HTTP2中Client不能向Server发送Server Push。 |
| DataFrame | HTTP2协议的各种数据格式的封闭 | 重点说明: 针对不同的数据格式,如ServerPush,Preface等,有对应的子类实现 |
| DataGenerator | 构建如上的DataFrame | 重点说明: 对于不同的数据格式有不同的子类实现 |
| parser包 | 对接收的数据格式进行解析 | 重点说明: 对接收的数据格式进行解析 |
四、如何实现HTTP2
HTTP2还未被所有浏览器所支持,因此在实施时要支持多种协议并存.
需要Http Server端支持HTTP2协议,据我所知Tengine尚未支持,已支持的Server列表https://github.com/http2/http2-spec/wiki/Implementations。
若要充分利用HTTP2的所有优点,需要在应用程序端(甚至是JAVA)的输出行为作智能处理,如通过大数据来分析哪些资源适合用Server Push并行输出,哪些资源优先级可以隐藏低,如何在性能与复杂度及维护成本之间做出平衡,需要业内更多的人努力和尝试,
HTTP2 学习的更多相关文章
- 记升级一次的http2学习
首先,就先对比下http2和http1.X的区别和升级它的优势吧. 在 HTTP .X 中,为了性能考虑,我们会引入雪碧图.将小图内联.使用多个域名等等的方式.这一切都是因为浏览器限制了同一个域名下的 ...
- HTTP2和HTTPS来不来了解一下?
一.前言 只有光头才能变强 HTTP博文回顾: PC端:HTTP就是这么简单 PC端:HTTP面试题都在这里 微信公众号端:HTTP就是这么简单 微信公众号端:HTTP面试题都在这里 本文力求简单讲清 ...
- HTTP2 的前世今生
本文转载自HTTP2 的前世今生 导语 作为一名 Web 后端开发工程师,无论是工作中,还是面试时,对于 HTTP 协议的理解都是必不可少的.而 HTTP2 协议的发布更是解决了 HTTP1.1 协议 ...
- HTTP2和 HTTPS来不来了解一下?
本文力求简单讲清每个知识点,希望大家看完能有所收获 一.HTTP协议的今生来世 最近在看博客的时候,发现有的面试题已经考HTTP/2了,于是我就顺着去了解一下. 到现在为止,HTTP协议已经有三个版本 ...
- node.学习笔记(关于http2的讲解)
个人总结:读完这篇文章需要30分钟 http2部分很有学习价值,可以好好看. 用node搭建TCP服务器 用node搭建HTTP服务器 用node文件fs模块对文件读取,并用流的方式写入 用url路 ...
- ballerina 学习二十一 http2
ballerina 支持http2 协议,包含server push http2 协议 参考代码 import ballerina/http; import ballerina/log;endpoin ...
- HTTP2.0学习 与 Nginx和Tomcat配置HTTP2.0
目录 一.HTTP2.0 1.1 简介 1.2 新的特性 1.3 h2c 的支持度 二.Nginx 对 http2.0 的支持 2.1 Nginx 作为服务端使用http2.0 2.2 Nginx 作 ...
- HTTP2.0 的学习笔记
1 1 1 HTTP2.0 1 11 1 1 1 1 1 1 超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,也被称为HTTP ove ...
- 两年来的core折腾之路几点总结,附上nginx启用http2拿来即用的配置
序:一年多没更新博客园的内容了,core已经发生了翻天覆地的变化,想起2014年这时候,我就开始了从当时还叫k的那套preview都不如的vnext搭建这套系统,陆陆续续它每一次升级,我也相应地折腾, ...
随机推荐
- Mine Number(搜索,暴力) ACM省赛第三届 G
Mine Number Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 Every one once played the gam ...
- Modifiers: virtual, override, new, abstract, sealed, internal
internal 声明类.类成员.接口或接口成员具有内部可见性. internal 修饰符使类.接口或成员仅在当前包中可见. 当前包之外的代码不能访问 internal 成员.只有在同一程序集的文件中 ...
- linux知识点总结与随笔(关注linux爱好者公众号的一些笔记)
sysdig工具,可以有strace ,tcpdump,lsof的功能. 前台任务与后台任务,知识点:test.sh &,Ctrl+z,bg,shopt grep |huponexit(sho ...
- 7.1 Java中的堆和栈
栈与堆都是Java用来在Ram中存放数据的地方.Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.ane ...
- mvc-servlet---servletContext与servletConfig2
在编写servlet过程中,需要用到 ServletConfig.ServletContext对象,对这两种对象的介绍如下: ServletContext对象:servlet容器在启动时会加载web应 ...
- iOS手势(滑动)返回的实现(自定义返回按钮)
如果各位使用的是storyboard布局的话,且用的是系统的返回按钮,那么是自动会有滑动返回效果的,但是相信各位做项目的,一般都是用的自定义的返回按钮,所以我贴几行代码,看看怎么实现系统自带的滑动返回 ...
- 如何在Global.asax中判断是否是ajax请求
今天在一个应用场景中需要在Global.asax中判断一个请求是否是ajax请求,而在ASP.NET MVC中已经提供了一个现成的扩展方法IsAjaxRequest: namespace System ...
- windows下使用体验更好的控制台——ConsoleZ
转做前端开发以来,每天使用最频繁的工具就是控制台了,git提交代码要用,npm安装node包也要用,grunt task 也要用,可是系统自带的cmd太难用了, 那么问题就来了: "wind ...
- tomcat安全配置
1. 注释或删除 tomcat-users.xml 所有用户权限,看上去如下: <tomcat-users></tomcat-users> 2. 隐藏tomcat版本信息 1 ...
- Visual Studio 发布新版API智能提示
Visual Studio 新版API智能提示两周前发布.有了它,你可以在调用API的同时,方便了解到API的相关示例代码.这大大地有助于开发人员学习和使用API. 安装方法如下: 1. 打开Visu ...