HTTP超文本传输协议相关知识

366 阅读10分钟

🤔思考

  • http 常见的状态码有哪些
  • 什么是 Restful-API
  • http 哪些常见 header
  • http 为何需要缓存
  • cache-control 是什么意思 - http 强制缓存
  • Etag 和 Last-Modified 是什么意思 - http 协商缓存
  • 刷新页面对 http 缓存的影响
  • 关于HTTP版本演进,不同版本都解决了什么问题
  • CDN有用过吗?API可以用CDN吗
  • 何设计缓存方案,既可以首屏快,又可以获取到最新资源

HTTP状态码分类

分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器处理请求的过程中发生了错误

熟悉常见状态码

  • 200 成功
  • 301 Found 永久重定向(配合Location浏览器自动处理)
  • 302 临时重定向(配合Location浏览器自动处理) image.png
  • 304 Not Modified 资源未被修改
  • 400 Bad Request
    • 语义有误,当前请求无法被服务器理解
    • 请求参数有误
  • 401 Unauthorized
    • 没有权限。当前请求需要用户验证
  • 403 Forbidden
    • 服务器已经理解请求,但是拒绝执行它。
  • 404 Not Found 找不到资源
  • 500 Internal Server Error 服务器
  • 502 Bad Gayway
    • 此错误响应表明服务器作为网关需要得到一个处理这个请求的响应,但是得到一个错误的响应。
  • 504 Gaywey Timeout
    • 当服务器作为网关,不能及时得到响应时返回此错误代码。

什么是 Restful-API

REST: Representational State Transfer 变现层状态转换

  • Restful-API: 一种新的API设计方法
    • 把每个URI当做一个资源
    • 不使用url参数
    传统API设计: /api/list?pageIndex=2
    Restful-API设计: /api/list/2
    
  • 传统的API设计: 把每个URI当做一个功能

如何设计成一个资源

  • 不使用参数
  • 用method表示操作类型
    • GET 获取数据
    • POST 新键或更新
    • PATCH/PUT 更新(修改)
    • DELETE 删除

对比例子

  • 传统API设计

    • 增 post: /api/create-blog
    • 改 post: /api/update-blog?id=2
    • 查 get: /api/get-blog?id=2
  • Restful-API设计

    • 增 post: /api/blog
    • 改 put/patch: /api/blog/2
    • 查 get: /api/blog/2

学会设计API

参考资料

常见header

根据不同上下文,可将消息头分为:

  • Request headers
GET /home.html HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/testpage.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"
Cache-Control: max-age=0
  • Response headers
200 OK
Access-Control-Allow-Origin: *
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Mon, 18 Jul 2016 16:06:00 GMT
Etag: "c561c68d0ba92bbeb8b0f612a9199f722e3a621a"
Keep-Alive: timeout=5, max=997
Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT
Server: Apache
Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=31449600; Path=/; secure
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
X-Backend-Server: developer2.webapp.scl3.mozilla.com
X-Cache-Info: not cacheable; meta data too large
X-kuma-revision: 1085259
x-frame-options: DENY

Request headers

  • Accept 浏览器可以接受的数据格式
  • Accept-Encode 浏览器可接收压缩算法
  • Accept-Language 浏览器可接收的语言
  • Connection

    决定当前的事务完成后,是否会关闭网络连接。如果该值是“keep-alive”,网络连接就是持久的,不会关闭,使得对同一个服务器的请求可以继续在该连接上完成。

  • Cookie 存储
  • Host 域名
  • User-Agent 浏览器信息
  • Content-type 发送数据的格式 如application/json
  • If-Modified-Since
  • If-None-Match
  • Cache-Control

Response headers

  • Content-type 返回数据的格式 如application/json
  • Content-length 返回数据的大小 单位为字节
  • Content-Encoding 返回数据的压缩算法
  • Set-Cookie 服务端向客户端发送cookie
  • Access-Control-Origin-Allow 指定允许资源共享的origin
  • Etag
  • Last-Modified

缓存headers

  • Catch-Control Expires
  • If-None-Match Etag
  • If-Modified-Since Last-Modified

自定义headers

HTTP缓存

强制缓存

  • expires 已被 Cache-Control替换
    • 判断缓存是否过期 Cache-Control: max-age=31536000(单位是秒)

image.png

  • Cache-Control取值
    • max-age 失效时间 单位秒
    • no-cache 使用no-cache指令的目的是为了防止从缓存中返回过期的资源。

      no-cache从字面意义上很容易误解为不缓存,但是no-cache代表不缓存过期的资源,缓存会向服务器进行有效处理确认之后处理资源,更确切的说,no-cache应该是 do-not-serve-from-cache-without-revalidation

      而no-store才是真正的不进行缓存。

      使用no-cache的目的就是为了防止从缓存中获取过期的资源。

      原文链接:blog.csdn.net/mymilkbottl…

    • no-store 规定缓存不能在本地存储请求或响应的任一部分。
    • private 只可以缓存在客户端,不可以缓存到服务器,不共享缓存
    • public 可以缓存在客户端和服务器,共享缓存
    image.png

协商缓存(服务端缓存策略,由服务端来判断)

Etag 和 Last-Modified区别

  • 会优先使用Etag
  • Last-Modified只能精确到秒级别
  • 如果资源被重复生成,而内容不变,则Etag(指纹)更精确

Etag

sequenceDiagram
浏览器->>服务器: 初次请求
服务器->>浏览器: 返回资源,和Etag
浏览器->>服务器: 再次请求,Request Headers携带if-None-Match
服务器->>浏览器: 返回304 或返回新的资源和新的Etag

Last-Modified

sequenceDiagram
浏览器->>服务器: 初次请求
服务器->>浏览器: 返回资源,和Last-Modified
浏览器->>服务器: 再次请求,Request Headers携带if-Modified-Since
服务器->>浏览器: 返回304 或返回新的资源和新的Etag

http缓存的流程

TODO: 根据哪里判断?浏览器?request header?response header?

  1. 判断Cache-Control是否有强制缓存
      • max-age是否过期
        • 过期 -> 2.判断是否有Etag和Last-Modified
        • 无 加载(完)
  2. 判断是否有Etag和Last-Modified
      • 携带if-None-Match和if-Modified-Since向服务器发起请求
        • 判断协商缓存是否有效(通过)
          • 有 304(完)
          • 无 加载(完)
      • 正常请求数据 (完)

刷新页面,不同操作方式对 http 缓存的影响

  • 正常操作(一般用户): 输入url、点击链接、前进后退
    • 强制缓存有效,协商缓存有效
  • 手动刷新:F5
    • 强制缓存无效,协商缓存有效(分强制缓存和协商缓存的原因)
  • 强制刷新:Ctrl + F5
    • 强制缓存无效,协商缓存无效

image.png

image.png

image.png

历史版本演进

HTTP/1.0、HTTP/1.1

缺点

  • 连接慢,无法跟上迅猛发展的互联网

HTTP2.0

Google忍受不了HTTP1.1缺点,独立开发自己的浏览器Chrome。

HTTP/2的制定考虑互联网现状

  • 宽带
  • 移动
  • 不安全 在高度兼容HTTP/1.1的同时在性能改善方面做了很大努力,主要有一下特点:
  1. 二进制协议,不再是纯文本
  2. 可发起多个请求,废弃了1.1里的管道
  3. 使用专用算法压缩头部,减少数据传输量
  4. 允许服务器主动向客户端推送数据
  5. 增强了安全性,“事实上”要求加密通信

HTTP/2基本解决“队头阻塞”问题

  • 头部压缩
  • 二进制分帧
  • 虚拟的“流”与多路复用

缺点(有缺点,才有演进,HTTP3.0 解决): 基本上解决队头阻塞,但是没有根本解决队头阻塞

客户端用 TCP 发送了三个包,但服务器所在的操作系统只收到了后两个包,第一个包丢了。那么内核里的 TCP 协议栈就只能把已经收到的包暂存起来,“停下”等着客户端重传那个丢失的包,这样就又出现了“队头阻塞”。

由于这种“队头阻塞”是 TCP 协议固有的,所以 HTTP/2 即使设计出再多的“花样”也无法解决。 time.geekbang.org/column/arti…

HTTP3.0

UDP 是无序的,包之间没有依赖关系,所以就从根本上解决了“队头阻塞”。 image.png

  • HTTP/3 基于 QUIC 协议,完全解决了“队头阻塞”问题,弱网环境下的表现会优于 HTTP/2;
  • QUIC 是一个新的传输层协议,建立在 UDP 之上,实现了可靠传输;
  • QUIC 内含了 TLS1.3,只能加密通信,支持 0-RTT 快速建连;
  • QUIC 的连接使用“不透明”的连接 ID,不绑定在“IP 地址 + 端口”上,支持“连接迁移”;
  • QUIC 的流与 HTTP/2 的流很相似,但分为双向流和单向流;
  • HTTP/3 没有指定默认端口号,需要用 HTTP/2 的扩展帧“Alt-Svc”来发现。

比如你下班回家,手机会自动由 4G 切换到 WiFi。这时 IP 地址会发生变化,TCP 就必须重新建立连接。而 QUIC 连接里的两端连接 ID 不会变,所以连接在“逻辑上”没有中断,它就可以在新的 IP 地址上继续使用之前的连接,消除重连的成本,实现连接的无缝迁移。

如何设计缓存方案,既可以首屏快,又可以获取到最新资源

CDN有用过吗?API可以用CDN吗

CDN(Content Delivery Network 或 Content Distribution Network),中文名叫“内容分发网络”。

CDN 的最核心原则是“就近访问”

CDN 就要“分发”源站的“内容”了,用到的就是“缓存代理”技术。

在 CDN 领域里,“内容”其实就是 HTTP 协议里的“资源”,比如超文本、图片、视频、应用程序安装包等等。

  • 资源

    • 静态资源
      • 图片、音频
    • 动态资源
      • 动态变化,后台服务器计算生成,每次访问可能都不一样
      • 如果设置了Cache-Control的缓存时间,这段时间就会成为“静态资源”

    资源按照是否可缓存又分为“静态资源”和“动态资源”。所谓的“静态资源”是指数据内容“静态不变”,任何时候来访问都是一样的,比如图片、音频。所谓的“动态资源”是指数据内容是“动态变化”的,也就是由后台服务计算生成的,每次访问都不一样,比如商品的库存、微博的粉丝数等。

    如果动态资源指定了“Cache-Control”,允许缓存短暂的时间,那它在这段时间里也就变成了“静态资源”,可以被 CDN 缓存加速。

CDN的负载均衡

全局负载均衡系统(GSLB: Global Sever Load Balance)

解决的是用户如何找到“最近的”边缘节点,对整个 CDN 网络进行“负载均衡”。

实现方式

  • DNS负载均衡

缓存系统

CDN重要概念

  • 命中 就是指用户访问的资源恰好在缓存系统里,可以直接返回给用户;
  • 回源 则正相反,缓存里没有,必须用代理的方式回源站取

🤔思考

  1. 网站也可以自建同城、异地多处机房,构建集群来提高服务能力,为什么非要选择 CDN 呢?
  • 自建成本太高
  1. 对于无法缓存的动态资源,你觉得 CDN 也能有加速效果吗?
  • cdn一般有专用的高速网络直连源站,或者是动态路径优化,所以动态资源回源要比通过公网速度快很多。

参考:time.geekbang.org/column/arti…