1、HTTP
1.1 概述
HTTP 就是超文本传输协议(HyperText Transfer Protocol)
HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范
- HTTP 是一个用在计算机世界里的协议,它确立了一种计算机之间交流通信的规范。
- HTTP 专门用来在两点之间传输数据,不能用于广播、寻址或路由。
- HTTP 通常跑在 TCP/IP 协议栈之上,依靠 IP 协议实现寻址和路由、TCP 协议实现可靠数据传输、DNS 协议实现域名查找、SSL/TLS 协议实现安全通信。
1.2 相关协议
1.2.1 TCP/IP
IP 协议是“Internet Protocol”的缩写,主要目的是解决寻址和路由问题,以及如何在两点间传送数据包。
TCP 协议是“Transmission Control Protocol”的缩写,意思是“传输控制协议”,它位于 IP 协议之上,基于 IP 协议提供可靠的、字节流形式的通信,是 HTTP 协议得以实现的基础
1.2.2 DNS
域名系统(Domain Name System),用有意义的名字来作为 IP 地址的等价替代
域名解析,把域名做一个转换,“映射”到它的真实 IP
1.2.3 URI/URL
URI(Uniform Resource Identifier),中文名称是 统一资源标识符,使用它就能够唯一地标记互联网上资源
URL(Uniform Resource Locator), 统一资源定位符,也就是我们俗称的“网址”,它实际上是 URI 的一个子集
http://nginx.org/en/download.html
URI 主要有三个基本的部分构成:
- 协议名:即访问该资源应当使用的协议,在这里是“http”;
- 主机名:即互联网上主机的标记,可以是域名或 IP 地址,在这里是“nginx.org”;
- 路径:即资源在主机上的位置,使用“/”分隔多级目录,在这里是“/en/download.html”
1.2.4 HTTPS
HTTPS 全称是“HTTP over SSL/TLS”,也就是运行在 SSL/TLS 协议上的 HTTP
SSL/TLS,它是一个负责加密通信的安全协议,建立在 TCP/IP 之上,所以也是个可靠的传输协议,可以被用作 HTTP 的下层
HTTPS 相当于“HTTP+SSL/TLS+TCP/IP”
1.2.5 代理
代理(Proxy)是 HTTP 协议中请求方和应答方中间的一个环节,作为“中转站”,既可以转发客户端的请求,也可以转发服务器的应答。
1.2.6 CDN
CDN,全称是“Content Delivery Network”,翻译过来就是“内容分发网络”。它应用了 HTTP 协议里的缓存和代理技术,代替源站响应客户端的请求。
CDN 位于浏览器和服务器之间,主要起到缓存加速的作用;
用户在上网的时候就不直接访问源站,而是访问离他“最近的”一个 CDN 节点,术语叫“边缘节点”(edge node),其实就是缓存了源站内容的代理服务器,这样一来就省去了“长途跋涉”的时间成本,实现了“网络加速”。
1.2.7 小结
- TCP/IP 是网络世界最常用的协议,HTTP 通常运行在 TCP/IP 提供的可靠传输基础上;
- DNS 域名是 IP 地址的等价替代,需要用域名解析实现到 IP 地址的映射;
- URI 是用来标记互联网上资源的一个名字,由“协议名 + 主机名 + 路径”构成,俗称 URL;
- HTTPS 相当于“HTTP+SSL/TLS+TCP/IP”,为 HTTP 套了一个安全的外壳;
- 代理是 HTTP 传输过程中的“中转站”,可以实现缓存加速、负载均衡等功能
1.3 分层模型
1.3.1 TCP/IP 网络
- 链接层(link layer),负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标记网络上的设备,所以有时候也叫 MAC 层
- 网络层(internet layer),可以在“链接层”的基础上,用 IP 地址取代 MAC 地址,把许许多多的局域网、广域网连接成一个虚拟的巨大网络,在这个网络里找设备时只要把 IP 地址再“翻译”成 MAC 地址就可以了
- 传输层(transport layer),保证数据在 IP 地址标记的两点之间“可靠”地传输,是 TCP 协议工作的层次,另外还有它的一个“小伙伴”UDP
- 应用层(application layer),有各种面向具体应用的协议。例如 Telnet、SSH、FTP、SMTP、HTTP 等等。MAC 层的传输单位是帧(frame),IP 层的传输单位是包(packet),TCP 层的传输单位是段(segment),HTTP 的传输单位则是消息或报文(message)。可以统称为数据包
1.3.2 OSI 网络
- 第一层:物理层,TCP/IP 里无对应;
- 第二层:数据链路层,对应 TCP/IP 的链接层;
- 第三层:网络层,对应 TCP/IP 的网际层;
- 第四层:传输层,对应 TCP/IP 的传输层;
- 第五、六、七层:统一对应到 TCP/IP 的应用层。
1.4 域名
1.4.1 域名形式
域名是一个有层次的结构,是一串用“.”分隔的多个单词,最右边的被称为“顶级域名”,然后是“二级域名”,层级关系向左依次降低
最左边的是主机名,通常用来表明主机的用途,比如“www”表示提供万维网服务、“mail”表示提供邮件服务,不过这也不是绝对的
1.4.2 域名解析
就像 IP 地址必须转换成 MAC 地址才能访问主机一样,域名也必须要转换成 IP 地址,这个过程就是“域名解析”
DNS 的核心系统是一个三层的树状、分布式服务,基本对应域名的结构:
- 根域名服务器(Root DNS Server):管理顶级域名服务器,返回“com”“net”“cn”等顶级域名服务器的 IP 地址;
- 顶级域名服务器(Top-level DNS Server):管理各自域名下的权威域名服务器,比如 com 顶级域名服务器可以返回 apple.com 域名服务器的 IP 地址;
- 权威域名服务器(Authoritative DNS Server):管理自己域名下主机的 IP 地址,比如 apple.com 权威域名服务器可以返回 www.apple.com 的 IP 地址。
例如,你要访问“www.apple.com”,就要进行下面的三次查询:
- 访问根域名服务器,它会告诉你“com”顶级域名服务器的地址;
- 访问“com”顶级域名服务器,它再告诉你“apple.com”域名服务器的地址;
- 最后访问“apple.com”域名服务器,就得到了“www.apple.com”的地址。
**缓存:**减轻域名解析压力
- 网络运行商都会建立自己的 DNS 服务器,作为用户 DNS 查询的代理,代替用户访问核心 DNS 系统。
- 操作系统里也会对 DNS 解析结果做缓存
- 操作系统里还有一个特殊的“主机映射”文件(hosts 文件)
1.4.3 域名的“新玩法”
负载均衡:
第一种方式,因为域名解析可以返回多个 IP 地址,所以一个域名可以对应多台主机,客户端收到多个 IP 地址后,就可以自己使用轮询算法依次向服务器发起请求,实现负载均衡。
第二种方式,域名解析可以配置内部的策略,返回离客户端最近的主机,或者返回当前服务质量最好的主机,这样在 DNS 端把请求分发到不同的服务器,实现负载均衡
1.4.4 小结
- 域名使用字符串来代替 IP 地址,方便用户记忆,本质上一个名字空间系统;
- DNS 就像是我们现实世界里的电话本、查号台,统管着互联网世界里的所有网站,是一个“超级大管家”;
- DNS 是一个树状的分布式查询系统,但为了提高查询效率,外围有多级的缓存;
1.5 原理
1.5.1 报文
HTTP 协议的请求报文和响应报文的结构基本相同:
起始行(start line):描述请求或响应的基本信息;(请求行)
头部字段集合(header):使用 key-value 形式更详细地说明报文;(请求头)
消息正文(entity):实际传输的数据,纯文本、图片、视频等二进制数据。(body)
(1)请求行
-
请求方法:是一个动词,如 GET/POST,表示对资源的操作; (GET / HTTP/1.1)
-
请求目标:通常是一个 URI,标记了请求方法要操作的资源;
-
版本号:表示报文使用的 HTTP 协议版本。
(2) 响应行
- 版本号:表示报文使用的 HTTP 协议版本;(HTTP/1.1 200 OK)
- 状态码:一个三位数,用代码的形式表示处理的结果,比如 200 是成功,500 是服务器错误;
- 原因:作为数字状态码补充,是更详细的解释文字,帮助人理解原因。
1.5.2 URI
(1) 基本组成
- 协议名(scheme),表示资源应该使用哪种协议来访问。http、https、ftp、ldap、file、news
- authority,表示资源所在的主机名,通常的形式是“host:port”,即主机名加端口号。path 采用了类似文件系统“目录”“路径”的表示方式
- query,多个“key=value”的字符串,这些 KV 值用字符“&”连接,浏览器和客户端都可以按照这个格式把长串的查询参数解析成可理解的字典或关联数组形式
(2)URI 的编码
在 URI 里对“@&/”等特殊字符和汉字必须要做编码,否则服务器收到 HTTP 报文后会无法正确处理。
URI 转义的规则有点“简单粗暴”,直接把非 ASCII 码或特殊字符转换成十六进制字节值,然后前面再加上一个“%”。
例如,空格被转义成“%20”,“?”被转义成“%3F”。而中文、日文等则通常使用 UTF-8 编码后再转义,例如“银河”会被转义成“%E9%93%B6%E6%B2%B3”。
1.5.3 状态码
RFC 标准里规定的状态码是三位数,所以取值范围就是从 000 到 999。
RFC 标准把状态码分成了五类,用数字的第一位表示分类,由 000~999 变成了 100~599
- 1××:提示信息,表示目前是协议处理的中间状态,还需要后续的操作;
- 2××:成功,报文已经收到并被正确处理;
- 3××:重定向,资源位置发生变动,需要客户端重新发送请求;
- 4××:客户端错误,请求报文有误,服务器无法处理;
- 5××:服务器错误,服务器在处理请求时内部发生了错误。
1.5.4 特点
- HTTP 是灵活可扩展的,可以任意添加头字段实现任意功能;
- HTTP 是可靠传输协议,基于 TCP/IP 协议“尽量”保证数据的送达;
- HTTP 是应用层协议,比 FTP、SSH 等更通用功能更多,能够传输任意数据;
- HTTP 使用了请求 - 应答模式,客户端主动发起请求,服务器被动回复请求;
- HTTP 本质上是无状态的,每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。
(1)优点
-
HTTP 最大的优点是简单、灵活和易于扩展;
-
HTTP 拥有成熟的软硬件环境,应用的非常广泛,是互联网的基础设施;
-
HTTP 是无状态的,可以轻松实现集群化,扩展性能,但有时也需要用 Cookie 技术来实现“有状态”;
(2)缺点
- HTTP 是明文传输,数据完全肉眼可见,能够方便地研究分析,但也容易被窃听;
- HTTP 是不安全的,无法验证通信双方的身份,也不能判断报文是否被窜改;
- HTTP 的性能不算差,但不完全适应现在的互联网,还有很大的提升空间
1.5.5 数据类型与编码
HTTP 协议定义了两个 Accept 请求头字段和两个 Content 实体头字段,用于客户端和服务器进行“内容协商”。客户端用 Accept 头告诉服务器希望接收什么样的数据,而服务器用 Content 头告诉客户端实际发送了什么样的数据。
- 数据类型表示实体数据的内容是什么,使用的是 MIME type,相关的头字段是 Accept 和 Content-Type;
- 数据编码表示实体数据的压缩方式,相关的头字段是 Accept-Encoding 和 Content-Encoding;
- 语言类型表示实体数据的自然语言,相关的头字段是 Accept-Language 和 Content-Language;
- 字符集表示实体数据的编码方式,相关的头字段是 Accept-Charset 和 Content-Type;
- 客户端需要在请求头里使用 Accept 等头字段与服务器进行“内容协商”,要求服务器返回最合适的数据;
1.5.6 传输 / 连接管理
(1)大文件传输
- 压缩 HTML 等文本文件是传输大文件最基本的方法;
- 分块传输可以流式收发数据,节约内存和带宽,使用响应头字段“Transfer-Encoding: chunked”来表示,分块的格式是 16 进制长度头 + 数据块;
- 范围请求可以只获取部分数据,即“分块请求”,实现视频拖拽或者断点续传,使用请求头字段“Range”和响应头字段“Content-Range”,响应状态码必须是 206;
(2)连接管理
- 早期的 HTTP 协议使用短连接,收到响应后就立即关闭连接,效率很低;
- HTTP/1.1 默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率;“Connection: keep-alive”字段表示启用了长连接;“Connection: close”就意味着长连接即将关闭;
- 过多的长连接会占用服务器资源,所以服务器会用一些策略有选择地关闭长连接;
- “队头阻塞”问题会导致性能下降,可以用“并发连接”和“域名分片”技术缓解
1.5.7 重定向/转发
重定向是服务器发起的跳转,要求客户端改用新的 URI 重新发送请求,通常会自动进行,用户是无感知的;301/302 是最常用的重定向状态码,分别是“永久重定向”和“临时重定向”;
请求转发的时候,url不会产生变化,重定向(跳转)时候,url地址栏会发生变化
1.5.8 Cookie机制
Cookie 是服务器委托浏览器存储的一些数据,让服务器有了“记忆能力”;
响应报文使用 Set-Cookie 字段发送“key=value”形式的 Cookie 值;
1.5.9 代理服务
HTTP 代理就是客户端和服务器通信链路中的一个中间环节,为两端提供“代理服务”;
代理处于中间层,为 HTTP 处理增加了更多的灵活性,可以实现负载均衡、安全防护、数据过滤等功能
- 计算机领域里最常用的性能优化手段是“时空转换”,也就是“时间换空间”或者“空间换时间”,HTTP 缓存属于后者;
- 缓存代理是增加了缓存功能的代理服务,缓存源服务器的数据,分发给下游的客户端;
1.6 安全
通信过程具备四个特性,就可以认为是“安全”的:机密性、完整性,身份认证和不可否认。
1.6.1 HTTPS
HTTPS:HTTP 下层的传输协议由 TCP/IP 换成了 SSL/TLS,由“HTTP over TCP/IP”变成了“HTTP over SSL/TLS”,让 HTTP 运行在了安全的 SSL/TLS 协议上
SSL/TLS 是信息安全领域中的权威标准,采用多种先进的加密技术保证通信安全;
1.6.2 对称/非对称加密
(1)对称加密
“对称加密”,就是指加密和解密时使用的密钥都是同一个,是“对称”的。只要保证了密钥的安全,那整个通信过程就可以说具有了机密性。
(2)非对称加密
非对称加密可以解决“密钥交换”的问题。网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所以就无法破解密文
(3) 混合加密
1、在通信刚开始的时候使用非对称算法,比如 RSA、ECDHE,首先解决密钥交换的问题。
2、然后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。因为会话密钥很短,通常只有 16 字节或 32 字节,所以慢一点也无所谓。
3、对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就不再使用非对称加密,全都使用对称加密。
1.6.3 数字签名与证书
黑客也可以伪造身份发布公钥。如果你拿到了假的公钥,混合加密就完全失效了。
所以,在机密性的基础上还必须加上完整性、身份认证等特性,才能实现真正的安全。
在 TLS 里有什么东西和现实中的签名、印章很像,只能由本人持有,而其他任何人都不会有呢?只要用这个东西,就能够在数字世界里证明你的身份
这个东西就是非对称加密里的“私钥”,使用私钥再加上摘要算法,就能够实现“数字签名”,同时实现“身份认证”和“不可否认”
1.6.4 优化
可以有多种硬件和软件手段减少网络耗时和计算耗时,让 HTTPS 变得和 HTTP 一样快,最可行的是软件优化;
HTTPS 连接是计算密集型,而不是 I/O 密集型。所以,如果你花大价钱去买网卡、带宽、SSD 存储就是“南辕北辙”了,起不到优化的效果。可以选择更快的 CPU SSL 加速卡
1.7 发展
1.7.1 HTTP/2
- HTTP 协议取消了小版本号,所以 HTTP/2 的正式名字不是 2.0;
- HTTP/2 在“语义”上兼容 HTTP/1,保留了请求方法、URI 等传统概念;
- HTTP/2 使用“HPACK”算法压缩头部信息,消除冗余数据节约带宽;
- HTTP/2 的消息不再是“Header+Body”的形式,而是分散为多个二进制“帧”;
- HTTP/2 使用虚拟的“流”传输消息,解决了困扰多年的“队头阻塞”问题,同时实现了“多路复用”,提高连接的利用率;
- HTTP/2 也增强了安全性,要求至少是 TLS1.2,而且禁用了很多不安全的密码套件。
1.7.2 HTTP/3
- HTTP/3 基于 QUIC 协议,完全解决了“队头阻塞”问题,弱网环境下的表现会优于 HTTP/2;
- QUIC 是一个新的传输层协议,建立在 UDP 之上,实现了可靠传输;
- QUIC 内含了 TLS1.3,只能加密通信,支持 0-RTT 快速建连;
- QUIC 的连接使用“不透明”的连接 ID,不绑定在“IP 地址 + 端口”上,支持“连接迁移”;
- QUIC 的流与 HTTP/2 的流很相似,但分为双向流和单向流;
- HTTP/3 没有指定默认端口号,需要用 HTTP/2 的扩展帧“Alt-Svc”来发现。
1.7.3 WebSocket
HTTP 的“请求 - 应答”模式不适合开发“实时通信”应用,效率低,难以实现动态页面,所以出现了 WebSocket;一个“全双工”的通信协议,相当于对 TCP 做了一层“薄薄的包装”,让它运行在浏览器环境里;
WebSocket 的名字容易让人产生误解,虽然大多数情况下我们会在浏览器里调用 API 来使用 WebSocket,但它不是一个“调用接口的集合”,而是一个通信协议,所以我觉得把它理解成“TCP over Web”会更恰当一些
1.8 面试
1.8.1 浏览器 HTTP 请求过程
- 浏览器从地址栏的输入中获得服务器的 IP 地址和端口号;(域名的话,涉及域名解析)
- 浏览器用 TCP 的三次握手与服务器建立连接;
- 浏览器向服务器发送拼好的报文;
- 服务器收到报文后处理请求,同样拼好报文再发给浏览器;
- 浏览器解析报文,渲染输出页面。
1.8.2 优化
(1)优化方向
-
能优化是一个复杂的概念,在 HTTP 里可以分解为服务器性能优化、客户端性能优化和传输链路优化;
-
服务器有三个主要的性能指标:吞吐量、并发数和响应时间,此外还需要考虑资源利用率;
-
客户端的基本性能指标是延迟,影响因素有地理距离、带宽、DNS 查询、TCP 握手等;
-
从服务器到客户端的传输链路可以分为三个部分,我们能够优化的是前两个部分,也就是“第一公里”和“中间一公里”;
(2)有效手段
- 后端应该选用高性能的 Web 服务器,开启长连接,提升 TCP 的传输效率;
- 前端应该启用 gzip、br 压缩,减小文本、图片的体积,尽量少传不必要的头字段;
- 缓存是无论何时都不能忘记的性能优化利器,应该总使用 Etag 或 Last-modified 字段标记资源;