关于HTTP的几个个人预言
不得不说, http同html一样, 虽然拥有来自着上个世纪的资历和荣耀, 同时也携带着着来自上个世纪的历史包袱. 所以我们能看到, 从http/1.1到h2再到草稿中的http/3, http显然在革新的路上努力挣扎. 但依旧被历史包袱拖得速度缓慢.
下面介绍些未来可能发生的变化, 和一些已经在草稿中的变化.
状态码语义化
http返回包中的状态码(Status Code)是一个用来表示http返回数据的响应状态的一个3位十进制数值. 状态码是HTTP / 1.1标准(RFC 7231)的一部分。比如404代表资源找不到(not found).
虽然不用去死记硬背每一个状态码对应的含义, 但是常用的状态码还是需要记住以便同事之间交流, 比如200, 302, 304, 400, 403, 404, 500, 502......
但是随着"数字编号语义化"的趋势在软件行业越来越明显, http状态码也有"语义化"的趋势.
文本取代编号
什么叫"数字编号语义化"? 指的是在各种场景下使用一个数值来代表一种状态或者对象, 这些数值有被字符串取代的趋势, 比如IP地址被域名取代, 列表被字典取代, 键盘的keycode被key(比如左箭头由原来的37变成现在的"ArrowLeft")取代...这些变化都将原来不方便记忆的数值(number)淘汰掉, 取而代之的是语义明显文本(string), 这就是"数字编号语义化"的趋势.
虽然还没有发生, 但可以意淫一下, 未来HTTP的状态码, 服务器的端口号, 都会被一个string类型的字段取而代之, 让web平台更加亲民.
UDP将取代TCP
在今天"一切应用层协议都基于TCP"的年代, 你敢想象tcp有可能被曾经的小弟udp给超越吗? 还真有可能: HTTP 3.0规范中初步确定将使用UDP来取代使用了20多年的TCP !
不妨先回顾一下tcp的作用: UDP中的"U"经常被调侃为"unreliable", 即不可靠的数据报文, 而TCP通过确认重传机制保证了每一个数据包的可达性, 以防止数据包在中途意外死亡. 毕竟在许多年前, 网络传输的效率和可靠性都很差, 只能通过3次握手和4次回收来弥补网络层的缺陷.
但是在当今以及未来的网络环境下, 网络效率已经不成问题, ip网络传输的可靠性已经达到99%, 如果为了弥补那不到1%的掉包率而对每一个数据包回复"确认", 显然是一种资源浪费, 而且随着数据摘要和认证机制的成熟, 网络层不可达的问题往往都在应用层来检测, 然后可能的重传. tcp提供的数据可靠机制不再重要!
5G时代下的HTTP/3和QUIC协议
那TCP过时了吗? 过时了, 但没有淘汰. 只能说在5G的光环下, 网络可靠性问题不再那么严重, 已经45岁的TCP协议不需要再肩负保证网络可达的伟大使命.
那个很久以来被称为HTTP-over-QUIC的协议,如今改名了。官宣!该协议正式成为“HTTP/3”。毫无悬念, 即将到来的新HTTP版本,HTTP/3,将使用QUIC来传输(quic是应用层协议)。QUIC现在也是所有Google产品的默认协议.
QUIC的有点就不放在这里说了, 以后单独写一篇介绍之, 无论如何不可否认的是:
QUIC将取代TCP...
以后面试的时候不用担心关于TCP的各种问题了, 可以直接告诉面试官, TCP正在成为历史, 我们应该放眼未来..
网络安全和可靠性全部交给应用层 !!
从传统意义上, 我们认为网络层, 也就是电信运营商的主要责任是保证网络传输的安全性和可靠性, 保证数据"读"和"写"的安全, 但时代变了, 保证网络可靠和安全的任务逐渐从网络服务层移交到应用层, 也就是http协议. 仔细想一想, 我们根本需要ISP来保证数据安全, 因为我们有应用层的数据加密和认证(https).
同时我们也不需要传输层提供的网络可靠性保证(tcp), 因为我们有应用层的校验技术(哈希重传).
原来由TCP/IP来维护的网络安全和可靠性的任务现在全部由我们大HTTP来揽包了, 这个趋势势不可挡, 现在, 运营商ISP的任务只剩下网络布线, 以及ip地址的规划....
至此我们重新定义了网络层和传输层, 曾经不可一世的OSI参考模型终于退出历史舞台...
重新定义head, body以及cookie
http/2定义了二进制的head格式, 是一个划时代的举动, 以后可以在head中写入任何数据而不同考虑特殊字符了.但是通常传文件的时候body也是二进制的, 这引发了我们思考: 为啥http包非要分成1个head和1个body呢? 如果我不需要head呢(比如即时通讯)? 如果我需要2个body怎么办(比如一次穿2个文件)? 当然办法总是有的, 但这些特殊情况下head和body显得很鸡肋, 因为每次请求和回应都要传输一些没用的字段. websocket的诞生也是来自对http格式死板的失望, ws直接触发了http格式弱化的趋势.
HTTP未来的格式是BSON
如果把整个http包定义为一个json就会舒服得多, 类似这样:
{
head:{},
body:{},
other:{}
}
当然, 为了能够传输二进制内容, 我们得用BSON, 这个mongodb发明的二进制json格式我觉得最有可能成为下一代http标准格式.
我在这里大胆的预言: 未来http的格式是BSON.
逃.....
如果说http定义head和body略显多此一举的话, cookie就是一个失败的设计了. cookie的初衷是好的:希望通过head中一个字段来维护一个短连接, 但是它的失败在于cookie的不灵活性, 强制性的发送cookie还容易造成网络资源的浪费. 一些比较时潮的web开发者都喜欢手写cookie: 自己定义http头部字段, 按需发送cookie. 这种做法虽然略微辛苦, 但是却很自由, 最重要的是, 提升了性能.
传统cookie将被淘汰...
或者说, cookie将从一个"真实存在"的浏览器机制变成一种"不存在"的设计模式.
相爱相杀的数字与字符
数值对应着二进制数据, 字符串也就是文本, 字符串是对数字的一层语义抽象. 数字与字符是程序员日常打交道最频繁的2个相对的概念. 本文一开始说的"状态码语义化"的预言是一种数字向字符转化的趋势, 而之后提到的"BSON化"预言则是一种字符向数字转化的趋势. 虽然2者转化的方向相反, 但是我们能很清晰的看出含义: 向字符转化是为了给人提供友好的接口, 向数字转化则是为机器服务.
数字化趋势在webassembly上体现的淋漓尽致, 我们不妨想想一下以后JavaScript文件也会编译成和wasm一样的二进制文件来传输.
关于字符化的趋势我们也可以意淫一下, 会不会在以后的编程语言中出现更多的新字符甚至是中文字符? 别忘了现在所有人都在用UTF-8来编写只包含ASCII字符的源代码..(虽然体积一样)
扯远了, 回到http上来吧.
websocket也要被淘汰了吗?
非也, 虽然http/2的推送技术和http/3可能的长连接会降低wesocket的使用率, 但目前而言, websocket仍然是一个polyfill般的存在, 它的核心仍然是通过协商来保证后来的信息利用率.
很显然, 如果我上面的预言都实现的话, websocket的所有优势最终也会被http取代. websocket和前端框架vue它们一样, 虽然最终归宿都是败给标准库, 但它们的设计模式和思想会融入标准库.
结束语
本来想好好研究一下http/2的特性的, 但是后来放弃了, 原因是计划赶不上变化, 也许特性还没学完就被http/3取代了... 但并不是不要学http/2, 而是不要深究, 只要了解它利用那些可行的方式实现了哪些功能即可, 不用纠结是否合理, 因为http本身就有太多不合理的地方, 改变需要慢慢来..
关于上面那些不切实际的预言, 大放厥词的"取代"和"淘汰", 我期待评论里的吐槽声~
---------------------