从HTTP 2.0想到的关于传输层协议的一些事

0.HTTP协议的历史

我也不知道...

1.关于HTTP 2.0

收到了订阅的邮件,头版是说HTTP 2.0的内容,我本人不是很关注HTTP这一块儿,但是闲得无聊时也会瞟两眼的。HTTP 2.0的最大改进我觉得有两点:
第一:新增了帧层
帧层的好处在于重新分发流信息,服务器处理顺序可以不再依赖用户提交请求的顺序了。另外就是不必一定用TCP传输HTTP了,实际上规范一开始就是这么说的。
第二:HTTP头的内容可以增量交互了

多的HTTP头里面的信息都是参数的协商,每次都要携带,如key/value的形式,HTTP
2.0改变了,它只携带新增的或者变化的内容。既然HTTP是基于请求/应答会话的,那么何必不把参数保存在会话中呢?类似SSL/TLS的方式。即便是
IPSec这种无连接的协议族,也只是每次传输一个SPI索引而已。

2.不需要设计一种新的传输层协议

在传输层,只有TCP和UDP就够了,如果想扩展,那就在UDP上扩展好了。

3.几个关于TCP和UDP的误区

在协议改造之前,首先要澄清几个误区,那就是你要知道为何要使用UDP而不再使用TCP,或者反过来,你始终认为TCP比UDP好:

误区一:UDP更高效

很多人以为是因为UDP效率高,因为不需要ACK,这最有可能是从教科书上学到的,要么就是老师亲口告诉你的,但是看看你马上就要做的事,让UDP变得可靠,按序到达,那么除非你发明一种不要ACK的按序到达机制,否则你的ACK机制可能比TCP的更低效。

误区二:TCP更加健壮防攻击


是彻头彻尾的误区,TCP协议头里面有什么保证了安全?校验和吗?大多数情况是IP层先替你挡了一刀而已,如果IP层去掉了防火墙,校验和,手无寸铁的
TCP将面对什么!序列号吗?一个32位的数字而已,想让对端接收你伪造的TCP段,你只需要构造一个序列号在合理窗口范围内且匹配五元组的段即可。事实
上,TCP的协议规范中从来就没有安全机制,虽然你确实可以在TCP选项中放一些和PKI体系相关的东西。

误区三:TCP和UDP都不安全


实际上是一个伪命题。问题根本就不在点子上,可能IPv6的出现更加助长了持这种观点的人的威风。TCP也好,UDP也好,只是一个传输层协议,它提供的
是端到端的节点通信,在IP之上提供应用的多路复用机制,而已。安全不是它的职责,当然也不是IP层的职责。按照严格分层模型,身份认证属于会话层的职
责,而数据完整性则是表示层的职责。

误区四:TCP的低效在于其握手,慢启动等协商反馈机制

相反,基于反馈的慢启动和快速重传
/快速恢复都是合理的,它们的目的正是探测端到端路径的传输能力,TCP没有使用显式的NAK机制,而将丢包视为拥塞,将连续收到相同ACK视为丢包,这
一环套一环的反馈机制已经是TCP可以使用的最高效的方式了,更高效的方式当然是丢包点或者拥堵点直接发送源抑制反馈信号,但那样会破坏简单性原则。有人
为了减少TCP短连接的握手开销,发明了TCP重用,即TCP快速打开机制,使得在SYN包中都可以携带数据,这并不是一种好方式,为何要在相同两台端到
端主机之间频繁开启短连接呢?为何不在期间开一条长连接呢,然后将短连接的应用请求附着而上呢?用长连接平滑掉握手开销才是正解,握手是为了协商参数,这
点开销都承受不起,免费的午餐一定是剩饭!难道所谓能重用的连接不是以前遗留下来的吗?
       HTTP
1.1支持长连接,但是支持的不够好,每个请求必须按照请求发出的顺序被回应,如果两个请求是关联性很小的请求,第一个请求的处理延迟使得第二个请求被连
累,这是伤不起的。这如何解释??个人认为这是传输层协议的使用方式不对的问题而不是协议设计的问题,传输层只是在整个层次上提供了上层的多路复用机制,
而这个上层并不是说一定就得是应用层。谁让你把两个GET请求塞到一个TCP连接了啊,好吧,那你可以用两条TCP连接,也是,完全可以用多条TCP连
接!但是还是有问题,问题在哪儿呢?我们来看下应用的模式。

4.应用模式的演进

最初的史前年代,是没有所谓的应用的,如何非得
说有,那就是两类,一类是文件下载,另一类就是终端登录,看看那些著名的史前协议吧,FTP,Telnet...TCP当时和IP是在一起的,并没有分成
两个层级,也没有必要分开,因为不管是文件下载还是登录,都需要严格的数据按序到达,那时的网络其实就是一个数据精确按序到达的网络,但当它们发展到第三
个版本的时候,它们分手了,至于说它们为什么分手,说好听点就是分层模型的每一层只负责一类处理的职责原则,说得不那么好听但很容易理解一点就是出现了小
三,因为当时出现了一种需求,并不需要提供按序到达的机制,但要提供数据边界,属于一种发后不管的需求,很多的控制报文的投递属于这一种,它们不需要一个
长连接,但需要数据边界,即一个报文从哪里开始在哪里结束,这些控制报文本身提供额外的校验机制,并不需要网络的反馈。显然TCP-IP无法满足这些需
求,于是IP就纳妾了,从而变成了TCP/IP,实际上是(TCP-UDP)/IP。
      
按照抢先性原则,以后的应用要么使用TCP,要么使用UDP,也有很多不需要多路复用的直接使用IP,比如很多路由协议。随着应用的蓬勃发展,一直到
HTTP 2.0之前,TCP和UDP都能应对,即便出现了很多的效率问题,但总体上都有解决的方法。但是HTTP
2.0带来一个全新的时代,一切和以前都不同了。
      
一个应用要请求一台主机上的很多资源,按照以往对会话的理解,需要建立多个会话,但是为了效率,提倡共享一条TCP连接,HTTP
2.0和以往不同的是,它加入了一个新的帧层,将每一个HTTP数据包封装在一个帧中,每一个帧都携带一个流标号,这就意味着HTTP的回应不必按照请求
的顺序处理了,流标号可以识别一个HTTP回应对应哪个请求,然后问题还是存在,不过是出在了TCP层。虽然应用服务器不必再按照请求顺序将处理排队,但
是由于TCP连接是严格按序到达的,因此万一有丢包,其后续的数据将全部被阻塞,直到丢包到达,这是TCP一直都存在的颠簸问题,玩过祖马小游戏的都应该
体会过。在信号不稳定的无线环境下,一个TCP流的颠簸带来的问题是全面且严重的。HTTP 2.0 over
TCP带来的问题是TCP的阻塞代替了应用服务器的阻塞。那么怎么解决呢?

5.会话传输层设想

如果能有一个端到端协议,每个连接占据一个五元组,在该连接上提供帧边界的按序可靠到达,或者在该连接上复用多个流,每个流上按序可靠到达,这不就解决了HTTP 2.0的问题了吗?同时解决的还有端口资源占用的问题,再也不用为端口不够用犯愁了。
      
OSI模型中有会话层,但是TCP/IP模型没有,实际上这个层还是必要的,如果HTTP
2.0承载于会话层而不是传输层,那么传输层就可以用轻量级的UDP了,只要在会话层确保每一个会话按序处理即可,如果承载于传输层,那么对于TCP而
言,一个WEB应用的所有会话都要共享一个TCP连接,在按序处理上造成了互相牵制。

6.实现思路与措施

不知道你对OpenVPN的Reliable层有没有了解,这是一个活生生的例子,经过我个人的改造,在它之上实现一个基于UDP的多个流多路复用是很简单的,协议封装图如下:
基于Reliable层的stream1----基于Reliable层的stream2----基于Reliable层的stream3
----------------------------------------------------------------------------------------------------------------------------
                          UDP协议(我使用了一对OpenSSL的BIO来代替)
----------------------------------------------------------------------------------------------------------------------------

照上图,如果stream2中的一个中间数据包没有到达,它只会阻塞stream2的后续数据包向应用提交,而stream1和stream3的数据包即
便是在没有到达的stream2的数据包后面到达的,只要是按序的,就可以尽快提交给应用层。我的这个stream的协议头很简单,为了方便就两个字段,
一个标识session
ID,一个标识长度,其实这个长度也是不需要的,因为Reliable层中本来就有长度。按照这个思想,还有一个引申出的协议,即按照边界标识来提供按序
到达的语义,此时协议头中的长度字段就是必须的了,这个引申的意义是,我只要保证协议头中指示的长度为length的这些数据按序到达即可。如果这样,每
一个数据包都需要一个序列号,但是只有length范围内的序列号用于按序到达语义,如果序列号落到了length范围内,则按照按序语义处理,否则直接
提交给应用。在我的测试中,我没有提供性能优化措施,我只是调通了而已,因为我觉得优化总是有办法的,再说用BIO来模拟丢包也不是很准确。
      之所以使用OpenVPN的Reliable层,不是因为它有多么好,而是我比较熟悉它而已,据我对世界历史的了解,轮子只在美索不达米亚被发明过一次,借用总比重新来一遍要好。整个过程就是对OpenVPN的裁剪过程,最终剩下的C文件是:
buffer.c  error.c  interval.c  list.c  mbuf.c  memcmp.c  otime.c  packet_id.c  reliable.c  schedule.c  session_id.c  ssl.c
相应的H文件和Makefile也要改,我只是在bio_read/write和Reliable层之间加了一个复用的机制而已。BIO真是一个好东西,模拟UDP再好不过了,

6.看到些曙光了吗


到这里,我有点脱离HTTP 2.0了,其实本文的大部分都不是在说HTTP 2.0,而完全是针对TCP的,HTTP
2.0运行于TCP之上真的不合适了,因为TCP的逻辑太简单又太复杂。说它简单是因为它依然和几十年前一样,仅仅适合于文件传输和远程长连接登录,说它
复杂是因为针对这两类需求以及少量的这两类需求之外,TCP衍生了各种复杂的基于反馈的算法,要知道,只要是反馈系统就是复杂的,动物正是有了负反馈系统
而和植物区分开来!因此,如果应用逻辑越来越复杂的时候,比如如今的各类WEB应用,TCP能否作为一匹好马就值得怀疑了,HTTP
2.0正是为了应对复杂的WEB应用而出世的,绝不能被TCP牵绊住,总的来讲,TCP太重了,HTTP
2.0同样也不轻,TCP的诸多优化并不是针对WEB的。举一个最简单的例子,TCP的目标是填充带宽延时乘机的管道,为此它和端到端的流控机制有了冲
突,接收端只可以接收N个数据,难道发送端只能发N个吗?要知道N个数据还要在网络上跑一会儿呢!所以发送端应该发送的是N*延时个数据,可是如果延时很
长的话,你能保证延时期间接收端的接收窗口保持不变吗?特别在复杂WEB应用环境下,这个接收窗口转瞬即变,因此又需要反馈...如果是用于文件传输,就
没有问题了,因为文件传输的目的是尽量填满整个带宽,实现最大吞吐量。
       好了,说了这么多TCP怎么不适合HTTP
2.0,那么我的上面的想法就一定好吗?我不敢说,但是我觉得起码解决了几个问题,第一个就是你不用建立多个连接了(这实际上是HTTP
2.0解决的问题,但是本文不限于HTTP
2.0),要知道对于同一个目标,你的机器上的每个IP地址只能使用65535个端口,这不是你的机器的限制,而是协议的限制,在带宽稀缺且数据量不大
(载荷率很低)的年代,协议头里面的16位端口字段要比32端口字段节省很多的带宽!也许你会觉得,你在一个端口上复用多个session
ID,道理不也一样吗? 难道session ID就不怕浪费吗?是的,它也不是取之不尽的,问题的关键来了,这个关键可能推翻IPv6的糟糕架构!

问题是你愿意横向扩展还是愿意纵向扩展。我不得不用IP层的一个现实来说明问题,因此我不得不扯到IP层。以IPv4为例,它的地址空间总是被认为有限
的,人们一直担心它会耗尽,于是IPv6的思想之一很简单,那就是加大地址空间,一下子变成了128位,说什么地球上每一平方可以拥有多少地址之类的宣传
性言语,其无聊性不亚于经济大萧条时美国总统承诺每人锅里面有一只鸡!这么一来IPv6是解决了问题,但是协议栈不兼容了,整个IP层要重写,在重写其间
需要截断整个上下层的通信,但是这是不能截断的,因为IP目前基本成了所有通信的必经之路,这个很不像修路时那样,可以向左向右改道,IP实际上是一个双
向2车道的路径。
      
有没有办法呢?有!那就是LISP的思想,即将IP分成两层,外层标识位置,内层标识设备,这样是不是更好呢?类似IPv6的那种宣传,LISP可以说,
每一个位置都可以有2的32次方个IP地址,是不是更诱人呢?毕竟并没有说一个位置有多大!!和IPv6不同,实现这个很简单,只需要提供一个兼容层即
可,过渡很方便,如果支持LISP,那就处理,如果不支持,那就剥掉外衣直通。注意,我这里说的可不是标准的LISP,而是基于LISP思想而对IPv4
的改进。
       回到TCP/UDP的问题,我们如果采用类似的思想,是不是也不错呢?如果一个session
ID为32位,那么一个UDP端口就可以承载2的32次方个session!完全满足了当前复杂的应用需求,应用可以连接同一个UDP端点,但是发送不同
的业务数据,每一个业务或者说事务都是session独立的,互不影响。

从HTTP 2.0想到的关于传输层协议的一些事,布布扣,bubuko.com

时间: 2024-11-13 19:57:39

从HTTP 2.0想到的关于传输层协议的一些事的相关文章

可靠的传输层协议——TCP协议

TCP协议 TCP协议工作在传输层,虽然它与UDP的下一层都是IP但是它却和UDP的效果完全不同,它是一种可靠的传输层协议 一.TCP协议封装 TCP数据段头部共有20个字节,包括16位的源端口号,16位的目的端口号,端口号与前面各层中的协议类型相似,都指的是上层将要交给谁,这个端口号就是主机上一个进程所绑定的一个入口,所以通过端口号和IP就能找到唯一主机的唯一进程. 32位序号:用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节.如果将字节流看作在两个应用

UNIX网络编程笔记(1)—传输层协议

开始学习网络编程的经典<UNIX网络编程>(第3版)作为研究生阶段的副本练习吧,厚厚一本书,希望能坚持看下去,坚持做些笔记. 1.TCP/IP协议概述 IPv4 网际协议版本4(Internet Protocol version 4),32位地址,为TCP.UDP.SCTP.ICMP和IGMP提供分组递送服务. IPv6 网际协议版本6(Internet Protocol version 6).128位地址,为TCP.UDP.SCTP和ICMPv6提供分组递送服务. TCP 传输控制协议(Tr

传输层协议、应用层协议

传输层协议.应用层协议一.传输层协议1.传输层概述(1)传输层的作用IP层提供点到点的连接传输层提供端到端的连接(2)传输层的协议TCP(Transmission Control Protocol)传输控制协议可靠的.面向连接的协议:传输效率低UDP(User Datagram Protocol)用户数据报协议不可靠的.无连接的服务传输效率高2.TCP协议 (可靠地) 0 -- 1023 为常用端口号,已经被占用了,自定义端口号选1024以上,最大值是65535.(1)TCP 的封装格式 (2)

传输层协议介绍、重要的TCP三次/四次握手(理论部分,敲黑板!)

本次我和小伙伴分享的是网络七层中的传输层,我将会分成以下几步为大家进行分解说明:1.TCP协议介绍2.TCP报文格式3.TCP三次握手4.TCP四次握手5.UDP协议介绍6.常见协议及其端口 一.TCP和UDP协议1.TCP是面向连接的.可靠的进程到进程通信的协议2.TCP提供全双工服务,即数据可在同一时间双向传输3.TCP报文段(不超过1500字节,1.5kb) TCP将若干个字节构成一个分组,叫报文段(Segment) TCP报文封装在IP数据报中TCP报文段:1.源端口号(16)2.目标端

传输层协议(TCP/UDP)介绍

一,TCP/IP协议族的传输层协议概况:1,TCP:传输控制协议2,UDP:用户数据报协议二,TCP/UDP协议详解:1,TCPa.TCP是面向连接的,可靠的进程到进程通信的协议 :TCP提供全双工服务,即数据可在同一时间双向传输.b.TCP报文段:TCP将若干个字节构成一个分组.叫报文段.TCP报文段封装在IP数据报中.数据段详解:.序号(32):发送端为每个字节进行编号,便于接收端正常重组.确认号(32):用于确认发送端的信息.窗口大小(16):用于说明本地可接收数据段的数目,窗口大小是可变

TCP/IP中的传输层协议TCP、UDP

TCP提供可靠的通信传输,而UDP则常用于让广播和细节控制交给应用的通信传输. 传输层协议根据IP数据报判断最终的接收端应用程序. TCP/IP的众多应用协议大多以客户端/服务端的形式运行.客户端是请求的发起端,而服务端表示提供服务的意思,是请求的处理端.因此,作为服务端的程序有必要提前启动,准备接收客户端的请求.传输协议根据接收数据中的目标端口号识别目标处理程序. TCP.UDP比较 TCP提供可靠性传输.实行顺序控制或重发控制机制,还有流量控制和拥塞控制,提高网络利用率. UDP是不具备可靠

浅谈传输层协议TCP和UDP

在当今因特网的层次结构中,传输层的协议主要有两种,其一为Transmission Control Protocol,即TCP:其二为User Datagram Protocol,即UDP. 1.TCP service model TCP是使用最广泛的传输层通讯协议,它在两个端系统之间建立连接,并通过两端的状态机来维护连接,为应用层提供可靠的字节流传输服务. (1)TCP是面向连接的 在传输实际数据的字节流之前,两个端系统的TCP会通过三次握手来确定建立连接,即所谓的3-way handshake

前端工程师如何理解 TCP/IP 传输层协议?

网络协议是每个前端工程师都必须要掌握的知识,TCP/IP 中有两个具有代表性的传输层协议,分别是 TCP 和 UDP,本文将介绍下这两者以及它们之间的区别. TCP/IP网络模型 计算机与网络设备要相互通信,双方就必须基于相同的方法.比如,如何探测到通信目标.由哪一边先发起通信.使用哪种语言进行通信.怎样结束通信等规则都需要事先确定.不同的硬件.操作系统之间的通信,所有的这一切都需要一种规则.而我们就把这种规则称为协议(protocol). TCP/IP 是互联网相关的各类协议族的总称,比如:T

传输层协议总结

传输层 1.只有主机才有的层次 2.传输层使用网络层的服务为应用层提供通信服务 传输层的功能 1.传输层提供进程与进程之间的通信 2.网络层提供主机之间的逻辑通信 3.复用和分用 4.传输层对收到的报文进行差错检测 5.传输层的两种协议:tcp,udp tcp与udp tcp: 1.面向连接的传输控制协议tcp 2.传送数据之前必须建立连接,数据传送结束后要释放连接,不提供广播或多播服务,由于tcp要提供可靠的面向连接的传输服务,因此不可避免增加了许多开销,确认,流量控制,计时器及连接管理等 3