“超文本传输协议”

d697ba915bcca40a11b8a25571516720.jpg

HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。 通常跑在 TCP/IP 协议栈上,依靠 IP 协议实现寻址和路由、TCP 协议实现可靠数据传输、DNS 协议实现域名查找、SSL/TLS 协议实现安全通信。

HTTP 特点

7808b195c921e0685958c20509855d4a.png

  • 灵活可扩展:报文各个组成部分可以定制
  • 可靠传输:基于 TCP/IP 协议
  • 应用层协议:能够传输任意数据
  • 请求 - 应答:请求方主动发起请求,应答方被动回复请求
  • 无状态:每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息

    HTTP 报文

    HTTP 协议的核心内容:传输的报文内容

报文结构

77ada417e9ed1dfdd571774333115e471603772700252.png

  1. 起始行(start line):描述请求或响应的基本信息
  2. 头部字段集合(header):使用 key-value 形式说明报文
  3. 消息正文(entity):实际传输的数据

    请求行

    描述客户端想要如何操作服务端的资源

  1. GET / HTTP/1.1

36108959084392065f36dff3e12967b9.png

  1. 请求方法:表示对资源的操作
  2. 请求目标:URI,标记请求方法要操作的资源
  3. 版本号:报文使用的 HTTP 协议版本

    状态行

    服务器响应的状态

  1. HTTP/1.1 200 OK

a1477b903cd4d5a69686683c0dbc3300.png

  1. 版本号:HTTP 协议版本
  2. 状态码:表示处理的结果
  3. 原因:作为数字状态码的补充,提供更详细的解释

    头字段

  4. 通用字段:在请求头和响应头都出现

  5. 请求字段
  6. 响应字段
  7. 实体字段:属于通用字段,专门描述 body 的额外信息

微信截图_20210310181127.png
微信截图_20210310181227.png
微信截图_20210310181243.png
微信截图_20210310181256.png

请求方法

微信截图_20210310182544.png

  1. HEAD:服务器不会放回请求的实体数据,只会返回响应头
  2. POST:新建
  3. PUT:修改
  4. OPTIONS:复杂请求发送之前,一般会需要通过这个方法发送一个预检请求,通过响应头来判断是否可以跨域

响应状态码(status code)

表示服务器对请求的处理结果

  • 1××:提示信息,表示目前是协议处理的中间状态,还需要后续的操作;
  • 2××:成功,报文已经收到并被正确处理;
  • 3××:重定向,资源位置发生变动,需要客户端重新发送请求;
  • 4××:客户端错误,请求报文有误,服务器无法处理;
  • 5××:服务器错误,服务器在处理请求时内部发生了错误。

    常用状态码

    微信截图_20210311104009.png
    1. // Location 标记服务器要求重定向的 URI
    2. Location:/index.html

    URI

    统一资源标识符(Uniform Resource Identifier)

作用:唯一地标记资源的位置或名字

基本组成

46581d7e1058558d8e12c1bf37d30d2a.png

  • scheme:表示资源应该用哪种协议来访问
  • authority:表示资源所在的主机名
    • host:主机名
    • port:端口号
    • path:标记资源所在位置(路径)
  • ?query:表示对资源附加的额外要求(”key=value”的字符串)

    1. http://www.chrono.com:8080/11-1?uid=1234&name=mario&referer=xxx

    完整格式

    ff41d020c7a27d1e8191057f0e658b38.png

  • user:passwd@:身份信息,表示登录主机时的用户名和密码(现在不使用)

  • fragment:定位的资源内部的”锚点“,只存在客户端不会发送给服务端

    HTTP 传输大文件

  1. 数据压缩
  2. 分块传输
  3. 范围请求
  4. 多段数据

    数据压缩

    1. Accept-Encoding: gzip, deflate, br(三种压缩算法)
    2. Content-Encoding: gzip

    分块传输

    1. Transfer-Encoding:chunked
    分块传输的编码规则:
  • 每个分块:长度头 + 数据块

25e7b09cf8cb4eaebba42b4598192410.png

范围请求(range requests)

允许客户端在请求头里使用专用字段来表示只获取文件的一部分

  1. // 请求头
  2. bytes=x-y x y 是以字节为单位的数据范围)
  3. Range: bytes=0-31
  4. // 服务端
  5. Content-Length: 32
  6. Accept-Ranges: bytes
  7. Content-Range: bytes 0-31/96

多段下载、断点续传

  1. 先通过 HEAD 获取服务端是否支持范围请求、获取文件大小
  2. 开 N 个线程,每个线程使用 Range 字段划分出各自负责下载的片段,发送请求传输数据
  3. 下载中断时,通过下载记录,用 Range 请求剩余部分

    多段数据

    一次性获取多个片段数据 “multipart/byteranges”,表示报文的 body 是由多段字节序列组成的 “boundary=xxx”给出段之间的分隔标记。

  1. // 请求头
  2. GET /16-2 HTTP/1.1
  3. Host: www.chrono.com
  4. Range: bytes=0-9, 20-29
  5. // 响应头
  6. HTTP/1.1 206 Partial Content
  7. Content-Type: multipart/byteranges; boundary=00000000001
  8. Content-Length: 189
  9. Connection: keep-alive
  10. Accept-Ranges: bytes
  11. --00000000001
  12. Content-Type: text/plain
  13. Content-Range: bytes 0-9/96
  14. // this is
  15. --00000000001
  16. Content-Type: text/plain
  17. Content-Range: bytes 20-29/96
  18. ext json d
  19. --00000000001--

fffa3a65e367c496428f3c0c4dac8a37.png

HTTP 的连接管理

57b3d80234a1f1b8c538a376aa01d3b4.png

  1. Connection:keep-alive/close

队头阻塞

6a6d30a89fb085d5f1773a887aaf5572.png

由 HTTP 的“请求 - 应答”模型导致 因为 HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。队列里的请求没有轻重缓急的优先级,只有入队的先后顺序,排在最前面的请求被最优先处理。

性能优化

  • 并发连接(concurrent connections):同时对一个域名发起多个长连接
  • 域名分片(domain sharding):多开几个域名,这些域名指向同一台服务器

    HTTP 的代理服务

    28237ef93ce0ddca076d2dc19c16fdf9.png

    作用

  1. 负载均衡:把外部的流量合理地分散到多台源服务器,提高系统的整体资源利用率和性能。
  2. 健康检查:使用“心跳”等机制监控后端服务器,发现有故障就及时“踢出”集群,保证服务高可用
  3. 安全防护:保护被代理的后端服务器,限制 IP 地址或流量,抵御网络攻击和过载
  4. 加密卸载:对外网使用 SSL/TLS 加密通信认证,而在安全的内网不加密,消除加解密成本
  5. 数据过滤:拦截上下行的数据,任意指定策略修改请求或响应
  6. 内容缓存:暂存、复用服务器响应

8c1fe47a7ca4b52702a6a14956033f7c.png

缓存代理

5e8d10b5758685850aeed2a473a6cdc2.png

服务器端的缓存控制

09266657fa61d0d1a720ae3360fe9535.png

客户端的缓存控制

47c1a69c800439e478c7a4ed40b8b992.png

参考资料

  1. 透视 HTTP 协议
  2. HTTP 常用头部整理
  3. 请你实现一个大文件上传和断点续传