网站内部相关文章:

http 发展

第一个网站

1990 年 12 月 20 日, 欧洲核子研究组织(CREN)的科学家 Tim Berners-Lee 在一台 NeXT 电脑上启动了世界上的第一个只有自己能够访问的网站, CREN 在 2013 年”复刻”该网站, 具体可以见:http://info.cern.ch/.

http 历史

  1. http 0.9

HTTP(Hyper Text Transfer Protocol) 协议的最早版本是 0.9, 发布于 1991 年(HTTP 0.9 https://www.w3.org/Protocols/HTTP/AsImplemented.html), 其仅仅支持 GET 请求, 无request headers, 用于展示静态文本内容, 此时的 web 仅仅是为了共享文档信息, 所以该协议恰好符合该需求, 例如获取一个网页:

1
GET /index.html

TCP 连接建立之后服务器仅仅支持 HTML 格式的字符串:

1
2
3
4
5
<html>
<body>
Hello World
</body>
</html>
  1. http 1.0

随着 web 的迅猛发展, 早期的协议版本逐渐不再适合新的环境, 1996 年 HTTP 1.0 诞生, 最突出的改进在于支持 POST, 基于 HTML 表单进行数据的提交工作, WEB 开始活跃起来, 相比于 HTTP/0.9, 1.0 大致增加了如下几点:

  • 任何格式的内容都可以发送, 传输文字, 图像, 视频, 二进制文件
  • 引入 POST, HEAD 命令, 丰富浏览器和服务器的互动
  • 引入 HTTP Header 的概念使得协议更加灵活, 具备了传输除纯文本之外的其他文档能力

此时一个典型的请求如下:

1
2
3
4
5
GET /mypage.html HTTP/1.0 User-Agent: NCSA_Mosaic/2.0 (Windows 3.1) 200 OK Date: Tue, 15 Nov 1994 08:12:31 GMT Server:
CERN/3.0 libwww/2.17 Content-Type: text/html
<html>
一个包含图片的页面<img src="/myimage.gif" />
</html>
  1. http 1.1

1999 年 HTTP 1.1 诞生, 其对 1.0 的一些多余设计做了精简和优化, 其消除了大量歧义内容并做了大量改进

  • 连接复用: 节省 TCP 重复握手次数
  • 管线化技术: 允许一个应答完全发送之前发送第二个请求, 降低通信延时
  • 支持响应分块
  • 引入额外的缓存控制
  • 引入内容协商机制
  • 引入 Host 头, 确保不同域名配置在同一个 IP 服务器上

http1.1是一个比较完善的协议, 其是真正意义上的第一个 HTTP 标准协议, 其从 1999 提出至今仍然是大部分网站的主流协议, TLS 协议也是在其基础上做了安全策略, 目前主流的 TLS 版本为tls1.2/tls1.3. 笼统而言, http 1.1 在两个方面对 http1.0 做了优化:

  • 加快网页加载速度: 长连接, 连接复用
  • 确保网页安全: 增加 tls 层确保访问安全环境
  1. http 2.0

随着互联网的发展, web 页面越来越复杂, 越来越多的数据通过 http 请求被传输, 此时 http 1.1 暴露了其一些问题.

​ a. http 队头阻塞: 顺序发送的请求序列中一个请求因为某个原因被阻塞, 则后面排队的所有请求也会一并阻塞, 为了解决该问题:

+ 受限于浏览器并发浏览请求数限制, 同一时刻对于同一域名下的连接数有限制, 每一个连接管道在同一个时刻又只能处理一个请求, 故将静态资源分散到不同的域名下以提升连接上限, 但此方法加大了网站维护和部署成本
+ 减少请求数量, 比如将图片资源直接以base64编码的方式内嵌到html中避免多次请求资源, 雪碧图, css和js文件合并或整合到html中

​ b. 大量重复请求头和响应头字段产生了不必要的网络流量
​ c. 不支持有效的资源优先级, 致使 TCP 的连接的利用率低下

为了解决上述以及未提到的问题, 在 2010 到 2015 年, 谷歌通过实践 SPDY 协议证明了一个客户端和服务器交互数据的另类方式, SPDY 通过降低延时, 头部压缩大大提高了传输效率, 最后在 SPDY 基础上引入流的概念提出http 2.0, 并最终在 2015 年正式标准化.

  • 高健壮性: H2 是一个二进制协议, 相比 H1 纯文本更加的方便和健壮, 不用考虑太多文本格式多样性的场景
  • 高性能: H2 使用多路复用, 其引入了二进制数据帧和流的概念, 确保同一个域名下的所有请求都是基于流, 在一个连接上进行并行传输, 解决了 http 队头阻塞问题
  • 网络开销低: H2 使用 HPACK 算法实现了头部压缩, 再配合原有的 http 压缩算法, 大大减少了传输数据量
  • H2 允许服务端进行 server push 功能, 比如一个 index.html 中的一些 css, js 资源, 服务端会主动进行推送, 但是该功能可能造成网络负载或其他问题, 不推荐使用

http 2.0 在标准化之后在大部分的大型网站上都已经做了适配操作, 从w3techs上可知截止 2022 年 1 月其普及率为 45%左右, 相比 http1.1 的 80%还是有一定的差距, 在国内可能普及率偏低. 这其中还有一个一点就是http 3.0的提出大大的降低了老项目升级到http 2.0的兴趣. 关于 http 2.0 更加详细的内容, 后续会再单独出一篇文章慢慢讲解下各种优化方案的具体实现逻辑.

  1. http 3.0

http 3.0 在 2022 年正式发布, 其相比于 http2 的最大提升就是效率, 通过替换网络层协议为 UDP, 增加 QUIC 协议层(quick), 从而拥有更低的延迟, 其效率相比 http1.1 可能达到 3 倍以上. 每一代 HTTP 协议都是建立在上一代 HTTP 协议的缺点上, 正如 HTTP 1.0 最大的问题就是传输安全性和不支持持久连接上, 针对此缺点 HTTP1.1 提出了保持长连接和 TLS. 那么 HTTP2 拥有哪些缺点呢?

  • TCP 三次握手, TCP 拥塞算法或处理, TCP 慢启动
  • TCP 对首阻塞
  • TLS 交互中 TLS1.3 可以实现 0RTT

虽然 HTTP2 解决了 HTTP 对首阻塞的问题, 但是其仍然是基于网络协议层的 TCP 协议, 其仍然不能避免 TCP 对首阻塞和 TCP 握手等问题, 但 TCP 的使用范围已经非常广, 此时不可能去改动 TCP 协议, 基于此原因 Google 基于 UDP 搞了一套 QUIC 协议并最终使用在 HTTP3 上(http2 over QUIC).

quic

关于 HTTP3 的更多知识后续会再单独出一篇文章慢慢讲解下.

管线化

上面在讲解 http 1 缺点的时候提过为了提高网页加载速度而采用了管线化技术, 这里简单的介绍下: 将多个 http 请求批量 send 而不需要等待服务器响应的技术, 通过管线化使得 HTML 网页载入的速度动态提升, 特别是在一些高延时的环境中, 例如卫星上网. 在 http 管道化提出之前, http 请求总是顺序发送的, 下一个请求只有在当前请求的响应被完全接收才会被发送, 而 http1.1 中管线化就允许批量发送多个请求, 其实际原理:

  • 将客户端的 FIFO 队列移动到服务端, 在现代浏览器之上, 在同一个连接上, 一个请求发送之后会立刻发送另外一个请求
  • 服务端维持 FIFO 队列, 保持一个缓冲区存放哪些已经处理好但是未被发送的响应

但是, 管线化可以批量发送多个请求, 但是在等待响应的时候仍然还是会按照 FIFO 逐一返回响应数据, 这也是为何 http 2 提出的原因之一. 除了 FIFO 先发先回问题之外, pipelining 还有如下的缺点:

  • 管线化仅仅支持幂等的请求, 例如 GET, HEAD, 因为非幂等请求可能存在先后关系
  • 大多数 http 代理服务器不支持 pipelining

网络请求

上文已经完整的讲解 http1.0 到 http3.0 的发展历史, 每一个 HTTP 版本的剔除都是为了解决 HTTP 网络请求慢的原因, 总体而言, 影响 HTTP 网络请求的因素主要有两个:

  • 带宽: 比如在拨号上网阶段, 管道化技术就大大提高了网页加载, 但是在 100Mbps 的带宽环境下管线化技术提升的技术就不是非常明显.
  • 延迟: 浏览器阻塞限制对同一个域名的最多连接数, DNS 查询, 建立连接过程中的握手和 TCP 慢启动等

HTTP 1.0 被抱怨最多的就是连接无法复用, 故 HTTP1.1 将长连接设置为默认值, 此项改动就是为了提高连接过程延迟过长导致的网页加载速度慢问题. 更进一步, http2.0 的提出一部分原因就是为了解决 HTTP 队头阻塞, 从而减少一个大型网页结构在需要批量获取大量资源时候的延迟.

Web 技术发展

静态网页和 CGI

  1. 静态网页

在此时没有 javascript, css, 网页就是纯粹的 HTML 和图片, 没有动态交互功能. 为了提高网页同浏览器交互的能力, 网景开发了 javascript 预研, 与此同时为了提高页面的画风, CSS 语言被提出以负责 HTML 标签样式.
1994 年, W3C 成立并对 javascript 和 css 两大前端语言逐渐设置标准, 静态网页慢慢的能够像桌面应用程序一样进行动态交互.

  1. 动态内容 CGI

随着业务发展, 静态网页不再满足于访问者需求, 客户端和服务器不仅仅从服务器获取数据, 还需要将数据提交并在服务器中持久化以便下次重新获取. 鉴于此需求, 1993 年 CGI(通用网关接口)出现, web 的动态信息服务开始蓬勃发展, CGI 定义了 web 服务器和外部应用程序之间的通信接口标准, 该接口计算式现在仍然还在使用中.

cgi

模板引擎

尽管 CGI 解决了网页动态数据的问题, 但是 CGI 本身的伸缩性不好, CGI 脚本本身还严重依赖于操作系统(当然现在可以用 python 作为 CGI 脚本语言解决了平台兼容问题), CGI 程序本身非结构化导致的代码难以维护等原因. 为了解决上述 CGI 问题, 模板的概念被提出并被广泛的使用(flask 的 Jinja 模板), 当然模板的使用也伴随着的不同语言的发展而发展, 比如php是全世界最好的语言

  1. PHP 和 ASP 时代

1994 年 PHP 诞生, PHP 可以把程序的动态内容嵌入到 HTML 模板中, 不仅能更好的组织 Web 应用的内容, 而且执行效率并 CGI 还高. 1996 年 ASP 被提出, 其是基于 VB 语言的模板引擎. 模板引擎的出现使得 HTML 代码和服务端代码得以分离开来(相较于之前), 使得开发流程更加规范和清晰, 更加利于维护, 大大提高了项目的开发进度.

  1. JSP 和 SERVLET 时代

在这个时间段, java 语言的发展也不可避免的代入模板引擎相关的技术, 其中 Servlet(Server Applet)是一个优秀的 Web 技术规范, 其是Java servlet api的简称, 称为小服务程序或服务连接器, 用 Java 编写的服务器端程序, 具有独立于平台和协议的特性, 主要功能在于交互式地浏览和生成数据, 生成 web 动态内容.

由于前后端交互的问题, sun 公司又发布了 JSP(java server pages), 它和 Servlet 技术一样, 都是 sun 公司定义的一种用于开发动态 web 资源的技术. JSP 最大的特点就是可以在页面中嵌套 JAVA 代码已提供动态数据(类似 django 中的 jinja 模板), 实际上此时前后端分离的思想已经开始慢慢产生. 在这个阶段, 美工把页面原型图画好并交给前端工程师编写静态页面, 后端开发工程将 html 代码改造为 JSP 等模板引擎可以识别的代码即可.

jsp

前端 MVC

随着 web 的不但发展, 后端技术规范稳定之后, 各种辅助 web 开发的技术不断被提出, 其中 MVC 的概念开始被引入到 web 开发中. 2004 年出现的 Struts 就是当时非常流行的 Java Web 开发的 MVC 框架. MVC 早在 1978 年就作为 Smalltalk 的一种设计模式被提出来了, 应用在 web 应用上:

  • 模型 Model 用于封装与业务逻辑相关的数据和数据处理方法
  • 视图 View 是数据的 HTML 展现
  • 控制器 Controller 负责响应请求

协调 model 和 view, 将 MVC 的三个角色分割开来, 这是一种典型的关注点分离, 单一原则的思想体现, 在服务器性能已经能够适配大部分服务的时候, 加快服务开发效率, 提高代码复用性, 提高组织工作效率自然而然就会被采用, 一个简单的 MVC 结构如下:

mvc

最终, 随着 AJAX 技术的提出, 使得前端技术可以较大程度上脱离后端, 在后端提供数据的基础上进行自我放飞式的页面构造, 至此 javascript 语言生态开发大放异彩, 前后端分离技术开始真正被应用到实际场景中. 随着前端业务需求的不断增长, 原始的 javascript 已经开始慢慢不再适合于前端程序员开发, 大量复杂的业务逻辑从后端转移到了 JavaScript 文件中, 大量的逻辑处理使得 javascript 的代码量激增, 于是前端 MVC 框架开始被提出并使用. 通过 MVC 框架又衍生出了许多其它的架构, 简称为MV, 最常见的是MVPMVVM.

MV 框架的提出是为了解决前端开发的复杂度, 提供一套规则组织代码, 分层, 通过合理的组织和分层是的前端的代码职责明确, 清晰, 便于开发与测试. 目前可知的前端 MVC 三大框架: Angular.js, Vue.js, React.js.

web 发展

关于 web 的发展上面两个章节已经介绍过了, 这里从 web 发展模式的视角简单描述下 web 的发展和 web 未来的方向, 其中关于 web3.0 的概念目前也没有一个非常明确的概念, 有得人将其与去中心化, 智能合约, 数据资产, 物联网等概念结合在一起, 有人将其与元宇宙等概念结合, 但是这些概念的技术都是基于人工智能技术的不断发展, 数字化基础设施的构建紧密相关的.

web123

  1. web1.0

web1.0 主要对应最早期的静态网站或者后来慢慢发展的新闻网站, 在线搜索, 门户网站, 电子商务等, 其本身也是一个不断发展进化的过程

  • 粗略简陋的静态页面, 一个 html 就是存在在服务器上的文件, 配合 CGI 进行一些简陋的动态生成, 见 2.1 节介绍
  • 基于 javascript 和 css 技术, 基于个人 PC 电脑和服务器性能的提升, 门户网站, 个人博客, 在线搜索, 电子商务等开始出现, 当然这个过程也是动态变化的

有些人将 web1.0 直接划定为最早期的仅仅提供静态服务的 web, 然后将动态 HTML 的生成归为 web2.0, 这两者之间没有什么明显的分界线, 技术不断的在发展, 发展过程都是不断迭代的, 在迭代到一定的周期之后 web2.0 的概念就自然而然被提出.

  1. web2.0

相比 web1.0, web2.0 最主要的变动就是用户本身参与到整个互联网内容的构建当中, 因为家用电脑, 服务器性能的不断提升, 特别是移动设备的更新换代, 移动设备的”随时随地”将所有人都构建在一个庞大的社交网络中. 社交服务, O2O, 网络直播, 短视频, facebook 等服务器开始出现.

  1. web3.0

随着技术的不断发展, 物联网, 人工智能(简略), 区块链技术的提出, 结合 web1.0 和 web2.0 构成了 web3.0 的数字化生态, 数字就是资产, 参与到网络中的所有实体都是主体, 其本身就是有价值的个体.

api 发展

本节主要简略的介绍下 API 架构发展历史和他们之前的对比, 每一个 API 架构的详细介绍见各自的文章介绍. API 架构的发展历史如下:
apihistory

其中主要的几个 API 架构有: RPC, SOAP, REST, GraphQL, 注意, 虽然不同的 API 架构提出的时间差别很大, 有些 API 架构技术已经提出非常久, 但并不意味着他们已经被弃用, 在不同的应用场景他们仍然在发挥自己的价值, 下面是这四个 API 架构的风格区别:
apiarchite

关于各个 API 架构的详细信息见站内链接中的相关文章.

引用