學而時習之網絡篇: 又是HTTP緩存的鍋 !

前言

春來了, 萬物復甦, 陽光明媚, 一處農家院子前的一塊空地上, 小小的藤椅上擠着一個 葛優躺的胖子, 遠遠看過去他那像極了游泳圈的小肚子上還放着一臺 MacBook Pro 筆記本, 湊近了看筆記本屏幕上開着一個叫 碼雲企業版 的網站, 上面滿屏都是 一位叫 Yuki 的測試妹子 指給名爲 張大胖的 bug。


大胖撓了撓頭髮了條語音給 Yuki:
"雖說哥這個假期 王者榮耀上分6到飛起, 但這幾天不看代碼, 我這bug怎麼越改越多了"

看到消息的 Yuki 白了白眼說到:
"你的Bug全組第一多, 至今無人超越, 心裏沒點數嗎?"

"頭髮長見識短, 你是沒有看到我的交付時間,交付代碼量還是全公司第一呢 !"
張大胖撅着嘴 嘴嘟嘟囔囔的回答道

Yuki 無語道:
"快去改Bug吧, 後天就到交付日期了 !"

張大胖聽完埋頭執行起了測試用例. 看着測試用例覆蓋率 100%, 隨後陷入了沉思. 良久後說道:
"我這邊單元測試沒問題啊, 前端也沒有改啊. 是不是又是 HTTP緩存的問題 ?"

"我天天用 360 給電腦清理緩存, 那還有什麼 HTTP緩存 !"
Yuki 疑惑的摸摸頭道:

張大胖一聽知道 套(chui)近(niou)乎的機會來了道:
"登一下 TeamViewer 哥遠程講給你聽 !"

在這裏插入圖片描述

春日 【朝代】宋

勝日尋芳泗水濱,無邊光景一時新。

等閒識得東風面,萬紫千紅總是春。

奠定互聯網時代的基石

1946年2月14日 隨着世界上第一臺通用計算機的誕生, 摩爾定律見證着 計算機從神祕不可近的龐然大物變成多數人賴以生存的工具,改變人們生活的IT 技術從學術界走向工業界從而進入無數個普通家庭。

NetWork 信息互聯解決了世界上的信息不對稱, 人們逐漸從對立中消除矛盾走向 世界人民大團結萬歲 !

2019年1月30日 We Are Social&Hootsuite聯合發佈了2019年數字報告,報告顯示,全球人口數76.76億人,其中手機用戶51.1億人,網民43.9億人,有34.8億人活躍在社交媒體上。

報告還顯示,全球互聯網用戶平均每天上網時間爲6小時42分鐘,也就是人們生活中1/4的時間都在上網。這一數字略低於去年的6小時49分鐘。

各國互聯網普及率

隨着互聯網的興起, 各廠DAU幾何倍暴漲, 無數人靠着解決日常生活中的痛點而發家致富, 而繁榮背後是無數互聯網從業者日以繼夜的辛勞付出。

對於程序員而言業務系統 DAU 50萬 與 DAU 5000萬 在架構上是有着天壤之別的, 一個優秀的緩存策略可以縮短網頁請求資源的時延,減少延遲提高併發,並且由於冗餘的數據可以重複利用,還可以減少網絡IO,緩解併發瓶頸。 在用戶的DAU暴漲中各種的緩存手段也層出不窮, 主要分爲 服務端緩存, 客戶端緩存.

  • 服務端 (緩存方案 (ps:缺點)/技術實現)
    • 熱點數據緩存 (ps:緩存雪崩) / Redids, Memcached
    • 進程緩存 (ps:緩存共享麻煩) / Ehcache, Guave Cache, Hibernate
    • DNS&CDN網絡緩存 (ps:自建維護貴) / Squid , 雲計算
  • 客戶端
    • HTTP緩存 (ps:容易被測試找bug) / HTTP協議+Nginx&Tomcat
    • 數據預緩存 (ps:侷限於微信小程序) / 週期性更新&數據預拉取
    • 內存&本地緩存(ps: 需要管理維護) / Vuex, LocalStorage&SessionStorage

HTTP緩存最佳Demo

HTTP緩存是一個比較複雜但是又比較重要的機制, 我們瀏覽一個頁面時發現發現異常的情況下, 通常第一個懷疑是不是瀏覽器做了緩存, 所以一般的做法就是Ctrl+F5 組合鍵重新請求一次這個頁面, 重新請求的頁面肯定是最新的頁面。

爲什麼 重新請求就一定能夠請求到沒有緩存的頁面呢?

  • 首先是在瀏覽器端, 如果是按 Ctrl+F5 組合鍵刷新頁面, 那麼瀏覽器會直接向目標 URL 發送請求, 而不會使用瀏覽器緩存的數據。
  • 其次即使請求發送到服務器端, 也有可能訪問到的是緩存的數據。
  • 所以爲了保證用戶能夠看到最新的數據, 必須通過HTTP 來控制。

圖 1 所示 當我們使用 Ctrl+F5組合鍵刷新一個頁面時, 在HTTP的請求頭中會增加一些請求頭.來告訴服務器我們要獲取的是最新數據而不是緩存.

強刷新對比

HTTP緩存的兩大陣營

強緩存

服務端告知客戶端緩存存活時間後,由客戶端判斷並決定是否使用CDN緩存。

即首次發起請求時,服務端會在Response Headers 中寫入 緩存存活時間。當請求再次發出時,如果緩存沒有過期,將直接從 CDN 緩存服務器獲取資源,而不會再與服務器發生通信。


協商緩存

由服務端決定並告知客戶端是否使用緩存。

協商緩存機制下,瀏覽器需要向服務器去詢問緩存的相關信息,進而判斷是重新發起請求、下載完整的響應,還是從本地獲取緩存的資源。

http

各類HTTP緩存的特點以及應用場景

  • 強緩存(HTTP標準)
    • Cache-Control(HTTP1.1)&Pragma(HTTP1.0)
    • Expires (HTTP1.0)
  • 協商緩存
    • Last-Modifiy/if-Modify-Since(HTTP1.1)
    • ETag/if-None-Match(HTTP1.1)

Cache-Control&Pragme

Pragma: no-cache是爲了兼容 HTTP1.0 ,Cache-Control: no-cache 是 HTTP 1.1提供的, 個人認爲 Pragma 字段爲上古時期的設計Bug, 兩者相輔相成用於指定所有緩存機制在整個請求/響應鏈中必須服從的命令, 不僅可以控制瀏覽器緩存還可以控制代理服務器,CDN服務器等

多選值 作用
Public 所有內容都將被緩存,在響應頭中設置
Private 內容只緩存到私有緩存中,在響應頭中設置
no-cache 所有內容都不會被緩存,在請求頭和響應頭中設置
no-store 所有內容都不會被緩存到緩存或 Internet 臨時文件中, 在響應頭中設置
must-revalidation/proxy-revalidation 如果緩存的內容失效, 請求必須發送到服務器/代理以進行重新驗證,在請求頭中設置
max-age=xxx 緩存的內容將在 xxx 秒後失效, 這個選項只有在 HTTP 1.1 中可用, 比 Last-Modified 生效優先級高, 在響應頭中設置

Expires

Exprires 的值爲響應頭返回的數據到期時間 Expires: Sat, 25 Feb 2020 18:26:17 GMT , 當瀏覽器再次請求時的請求時間小於之前返回的 Exprires 時間,則直接使用緩存數據。但由於服務端時間和客戶端時間可能有誤差,這也將導致緩存命中的誤差.

Last-Modifiy/if-Modify-Since

服務器在響應請求時,會在響應頭上 用 Last-Modified 告訴瀏覽器資源的最後修改時間. 例: last-modified: Thu, 14 Nov 2019 04:56:25 GMT , 瀏覽器再次請求服務器的時候,請求頭會包含此字段,後面跟着在緩存中獲得的最後修改時間。服務端收到此請求頭髮現有if-Modified-Since,則與被請求資源的最後修改時間進行對比,如果一致則返回304和響應報文頭,瀏覽器只需要從緩存中獲取信息即可。
從字面上看,就是說:從某個時間節點算起,是否文件被修改了

  • 如果真的被修改:那麼開始傳輸響應一個整體,服務器返回狀態碼:200 OK
  • 如果沒有被修改:那麼只需傳輸響應header,服務器返回狀態碼:304 Not Modified

Last-Modifiy/if-Modify-Since

ETag/if-None-Match

Etag:
服務器響應請求時,通過此字段告訴瀏覽器當前資源在服務器生成的唯一標識(生成規則由服務器決定)
If-None-Match:
再次請求服務器時,瀏覽器的請求報文頭部會包含此字段,後面的值爲在緩存中獲取的標識。服務器接收到次報文後發現If-None-Match則與被請求資源的唯一標識進行對比。

不同,說明資源被改動過,則響應整個資源內容,返回狀態碼200。
相同,說明資源無新修改,則響應header,瀏覽器直接從緩存中獲取數據信息。返回狀態碼304.

但是實際應用中由於Etag的計算是使用算法來得出的,而算法會佔用服務端計算的資源,所有服務端的資源都是寶貴的,所以就很少使用Etag了。

Etag 強驗證器和弱驗證器
ETag 分爲強驗證器和弱驗證器。

強驗證器要求文檔的每個字節都相等,而弱驗證器只要求文檔的含義相等

  • 強驗證:

  • 弱驗證(前面會加上‘ W/’ 來標識):

不同刷新的請求執行過程

  • 瀏覽器地址欄中寫入URL,回車
    瀏覽器發現緩存中有這個文件了,不用繼續請求了,直接去緩存拿。(最快)
  • F5就是告訴瀏覽器,別偷懶,好歹去服務器看看這個文件是否有過期了。於是瀏覽器就膽膽襟襟的發送一個請求帶上If-Modify-since。
  • Ctrl+F5 告訴瀏覽器,你先把你緩存中的這個文件給我刪了,然後再去服務器請求個完整的資源文件下來。於是客戶端就完成了強行更新的操作.

HTTP緩存最佳實踐

張大胖長長鬆了口氣說: "我看你應該是在家辦公, 用的自己電腦沒有配置HTTP緩存強制刷新!"

HTTP緩存強制刷新

"矮油, 這樣子呀, 大胖哥哥,你可真厲害! 我以後能不能多請教你一些技術問題啊 ?"
Yuki 檢查了下紅着臉說道.

張大胖 二郎腿翹的老高然後故作鎮定道:

"沒什麼,不過是寫代(Bug)碼總結出來的經驗! 這算啥 灑灑水而已啦, 復工後隔離 14天 我們星巴克見, 慢慢講給你聽 !"

(๑•̀ㅂ•́) ✧ 邦 的一聲 , 張大胖一個沒坐穩從藤椅上摔了個底朝天 !

蕭子山的Tip

不同業務用的緩存類型就不一樣, 有的網站只用強緩存, 有的用協商緩存, 有的各用一點, 親愛的讀者們, 筆者佈置個作業, 下面這些網站 document 都用了 那些HTTP緩存技術呢 ?

  • www.zhihu.com/hot
  • mp.weixin.qq.com/s/FlZXj4kk_hfqeyEIYdyXGA
  • www.taobao.com

資料參考

  • 深入分析 Java Web 技術內幕
  • 掘金社區 <淺談HTTP緩存>
  • 掘金社區 <HTTP----HTTP緩存機制>

微信掃描二維碼,關注我的公衆號

深入淺出分享 Java 乾貨 , 找回對代碼的 Passion , 助力月入 20K+

  • 原文地址: https://mp.weixin.qq.com/s/qxZ6AZfDR0RZ1ntKWB2T5Q
  • 目錄地址: https://zhuanlan.zhihu.com/p/104224910
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章