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

前言

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

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

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

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

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

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

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

張大胖一聽知道 套(chui)近(niou)乎的機會來了道:

登一下 TeamViewer 哥遠程講給你聽 !


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

Spring

Spring


春日 【朝代】宋 勝日尋芳泗水濱,無邊光景一時新。 等閒識得東風面,萬紫千紅總是春。

奠定互聯網時代的基石

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分鐘。


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


隨著互聯網的興起, 各廠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緩存介紹

HTTP緩存是一把雙刃劍 , 我們瀏覽一個頁面時發現頁面數據異常時, 通常第一個懷疑是不是瀏覽器做了緩存, 所以大家會 Ctrl+F5 強制刷新一次這個頁面, 強制刷新的數據絕對是最新的。

為什麼 強制刷新就一定能夠請求到沒有緩存的頁面呢?

  • 首先是在瀏覽器端, 如果是按 Ctrl+F5 組合鍵刷新頁面, 那麼瀏覽器會直接向目標 URL 發送請求, 而不會使用瀏覽器緩存的數據。
  • 其次訪問到達 URL 的 CDN 緩存服務器 也會MISS掉 再向服務器發起請求。
  • 如果 HTTP請求的 URL 存在熱點數據緩存那就無解了. 返回熱點數據緩存.
  • 所以說 客戶端與服務器之間的協議級緩存, 必然通過HTTP來控制。

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


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


HTTP緩存的兩大陣營

強緩存


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


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

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

協商緩存


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


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

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


學而時習之網絡篇:又是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服務器等

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

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


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


ETag/if-None-Match

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

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

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

Etag 驗證器分為強驗證器和弱驗證器。

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

  • 強驗證:


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


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


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


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


不同刷新的請求執行過程

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

HTTP緩存最佳實踐


學而時習之網絡篇:又是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 技術內幕
  • 掘金社區
  • 掘金社區

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


分享到:


相關文章: