- 此文章為中文譯文,有不足或者錯誤之處,敬請指正。原文傳送門:點選這裡
如果你曾在商場買過牛奶,那麼你將會很好地理解服務端及瀏覽器端的快取機制。
如果你是一個忠實的因特網使用者,你時時刻刻都在享受快取所帶來的好處。但是,你可能並不清楚它是在何時,以何種方式施展它的“魔法”。
從一個開發者的角度來說,快取機制使得建立一個高效能web應用或者web伺服器變得更為容易。開發者通過運用快取協議,就不必頻繁地去優化伺服器以應對大量請求而可能導致的伺服器崩潰。
雖說快取帶來的可能只是載入頁面時,兩秒變成一秒的差異,這種影響看上去似乎有一點...可有可無。但是,如果你的站點想要支援大量使用者使用,那麼這點變化是必要的。
在之前的web應用中使用了快取策略以後,我意識到可以用一些更為合適的方式去解釋快取機制,而不僅僅是通過一大堆術語。我注意到這個過程和牛奶從農場到你家冰箱這段路程很類似,所以我覺得這是一個不錯的解釋方式。
為了更好的理解本篇文章,你需要了解一下一些web伺服器的一些基本概念。現在我們開始吧!
沒有快取機制,網際網路會是什麼樣?
在我們深入瞭解快取之前,我們先來思考一下沒有快取的話,網際網路會是什麼樣?想象一下,假如你生活在18世紀至19世紀的某一個農村。你擁有一個農場,那時並沒有可用的冷藏裝置。你的農場飼養了幾頭奶牛,但是它們產的牛奶並沒有想象的有價值,因為很快牛奶就會變質。
讓我們把思緒拉回,即便是現在,也有很多地區和文明仍然沒有製冷技術。這些地方的人們會選擇直接從奶牛的奶頭中喝到新鮮的牛奶,或者把牛奶和穀物混合併發酵,以此來儲存。很有趣不是嗎?
不論如何,你肯定想把自家的牛奶出售給村裡的其他人。但是他們能喝牛奶的時間很有限。假設你的一頭奶牛一天能產出一加侖的牛奶。但是,如果太多的人來你家裡購買牛奶,你可能不得不讓一部分人先回家,等第二天再來購買。
同時,由於你分發有限,你甚至不能通過養殖更多奶牛來擴大你的生意。只有村裡的其他人才能購買你的牛奶,你受到一些明顯的限制。
相應的,如果沒有快取機制,你會受限於你的伺服器的計算力。快取就是用來載入一些靜態的資源,比如:
- 圖片
- css層疊樣式表
- html檔案
- javascript指令碼檔案
預設情況下,伺服器必須對每一個請求做出響應。但是,一個頁面的請求可能包含四個獨立的請求——以上的四種類可能都有一個。當你想要請求一個較大的影象檔案時,伺服器可能會因為全球的大量使用者(同時請求這個圖片檔案)而崩潰。然後,使用者將會經歷漫長的載入時間。
理想情況下,你希望通過儲存對常見請求的響應來緩解伺服器的壓力。你的伺服器不必處理每個獨立請求,相反,快取將會代替伺服器立即做出響應。你當然可以為更多伺服器買單,但是這比費用可是越來越可怕的。
什麼是服務端快取?
回到我們農場的設定中,知道如何能讓經營一家牛奶農場變得容易嗎?
一家帶有冰箱的超市!
如此一來,人們不必去你的農場就能立刻買到牛奶。你也可以把牛奶安全地儲存幾個星期。
超市緩解了大量你農場的壓力,因為你的奶牛不需要實時生產。超市將會處理這些需求。你只需要保證奶牛每天的生產效率即可。更好的是,附近村莊的村民都可以購買你的牛奶,因為人們總是可以在超市的冰箱裡購買到你的牛奶。
就像超市一樣,服務端快取將會處理一些常用的請求,並且更快更可靠地做出響應。
在上圖中我使用了一個術語——快取代理(caching proxy),快取代理是一個伺服器,它儲存用於響應公共請求的靜態檔案。快取代理將攔截常見的請求並快速響應。它可以防止這些請求對主web伺服器造成壓力。
現在你可能有一大堆問題,比如:
- 怎麼才算常用請求?
- 快取代理將儲存響應多長時間?
這需要在如何設定快取上學習更多,但是現在,你應該瞭解的一個概念是新鮮度。快取代理將具有在不同時間快取的不同檔案,它需要決定是否該繼續提供這些檔案的服務。這取決於你的快取策略。
這也和超市售賣牛奶很類似。超市經理需要決定你的牛奶上架售賣多久。快取代理通過快取命中率(通過快取伺服器提供的內容的百分比)來衡量其成功。
什麼是CDN?
至此,現在已經有一家商店在售賣你的牛奶了。雖然這是一個巨大的進步,但是你仍然沒辦法把你的牛奶賣給該商店覆蓋範圍之外的人。如果你想擴大你的生意,你得增加更多的商店和你合作。
假設你開始向更多的超市提供牛奶,你可以在更大範圍內滿足客戶的需要。這有點類似於一個內容交付網路,或者稱為CDN。CDN是一系列位於全球各地的代理伺服器(就像我們之前介紹的)。
作為最終的使用者,你可能覺得高速的網際網路讓大多數站點載入都很快。然而,這僅僅是因為這些站點使用了CDN,從而能夠快速地交付靜態檔案。
如果你正在英格蘭,並且你正在請求一個快取在弗吉尼亞伺服器上的檔案,你會體會到一些延遲,因為初始訊號只能沿著幾千公里的電纜傳輸。在英國的本地快取代理能夠讓這個站點載入更快。
所以,你的伺服器可以向CDN網路中的每個代理伺服器傳送靜態資源副本,它們可以處理本地請求,直到資源不再“新鮮”。一些常見的CDN提供者包括Rackspace、Akamai和Amazon Web服務。
那麼瀏覽器快取呢?
現在,全國(甚至全世界)的人們都可以買到你家生產的牛奶了。但現在還有一個小小的問題——顧客沒法在自己家儲存買來的牛奶。購買牛奶以後,顧客仍然需要儘快飲用,然後再去商店買更多。因此,這個系統仍然不能很好的服務顧客。
那有什麼解決辦法嗎?你需要一臺冰箱!
有了一臺冰箱,你可以在自己家中儲存牛奶,就不必反覆去商場購買了。在快取方面,我們談論的是完全獨立的儲存靜態資源的地方,因為它僅僅作用於客戶端,或者與瀏覽器位於同一臺計算機上。我們的代理伺服器可不是在本地的。
這對於facebook或者Amazon這類你可能經常瀏覽的站點來說是非常好的。這對他們的服務端成本也很有好處,因為他們可以減少必須處理的請求。
有一個關鍵的點——我們並不是說牛奶能夠“變魔術”似的直接到達你的冰箱裡,你還是需要發起一個初始請求到你的伺服器或者代理伺服器。在這之後,你可以快取一些檔案到本地。
瀏覽器是怎麼知道什麼時候該從伺服器中獲取新的檔案呢?如果沒有這個功能,你講永遠不會獲得這個檔案的更新版本。
emmm,就像廠家在他們生產的牛奶包裝盒上印刷上生產日期一樣,伺服器也會在http響應報文的頭部新增某種識別符號。實際上我們有4個獨立的HTTP快取系統。上面顯示的場景非常類似於“保質期”的形式。在傳送快取檔案之前,其他一些方法仍然需要瀏覽器檢查伺服器。
何時開始使用快取
假設你正在開發你的第一個web應用。在你擁有大量使用者之前,你可能不需要去擔心快取協議,因為伺服器成本是非常低的。然而,隨著你擴大規模,如果你想要快速載入你的應用,你需要使用快取技術。
以Heroku為例,這是一個快速部署應用的平臺。但是,它要求你使用單獨的服務來實現快取,就像亞馬遜的CloudFront或者CloudFlare。學習這些將會花費更多時間。
在瀏覽器端,在你嘗試更新靜態資源並重新載入頁面時,你可能已經體驗過快取的作用了,頁面可能並沒有什麼變化。不論你如何重新整理頁面,都不會有什麼變化。
這其實常常是因為瀏覽器端的一些快取協議。如果你想繞過瀏覽器的快取,強行從服務端重新請求資源,你可以使用Cmd+Shift+R(適用Mac)或者Ctrl+Shift+R(適用windows)。
獲取更多教程
假如你喜歡這篇教程,你可以在CodeAnalogies blog上檢視本文作者的更多教程。