全站快取時代

2021-09-19 05:05:51 字數 3787 閱讀 4125

原則:動靜分離,分級快取,主動失效。

web 開發中,介面會被分為以下幾類:

純動態頁面。實時性,個性化要求比較高。頁面變化很大,或者每個使用者看到的都不一樣,比如:朋友圈。

短時靜態頁面。在一定時間內基本不會變化,或者是容忍不需要實時更新。比如:文章、新聞。

動靜結合頁面。這個頁面既有動態,也有靜態內容。也是實際應用中最多的。

對於以上型別的頁面,可以做不同的快取方案。各位大神們應該根據自己業務的情況,靈活調整快取方案。以下內容可以作為參考。

高速發展的模板引擎,給前端渲染帶來了活力。mustache、jade、hbs 靈活的模板語法讓頁面開發變得更省力和高效。

htmldom == veiwengine.render(template ,data);

瀏覽器只認識 dom 結構的字串,也就是常說的 html5 格式。對於前端來渲染 dom,還是後端渲染的問題,在此不用討論,為了情況前端的效能和體驗,後端渲染會更合適。對於同乙個頁面,每次請求都會產生一次渲染嗎?渲染總是要計算的,這樣多浪費伺服器效能啊!確實是這樣,除非你用了快取。

直接放 cdn。純靜態頁面的訪問量一般不會很大,程式直接響應也是可以的。

都說是動態頁面了,那就不要做頁面快取了。可以考慮做資料快取,或者是 redis、db 快取。

1. 伺服器端檔案快取

請求-->處理介面--> 模板渲染 ---> 儲存檔案---> 響應檔案

快取動態頁面,你也可以把生成的檔案存到 cdn,然後讓 cdn 去響應請求。如果你的請求需要過一些驗證,那就把檔案儲存到伺服器,由業務伺服器去響應請求。檔案還有乙個好處是:流。例如:filereadstream.pipe(responsestream)。響應的時候,不需要把檔案的內容載入到記憶體,而是直接用 stream 的方式響應。但是弊端也不少,檔案儲存,會有併發讀寫死鎖問題。

還有乙個問題,分布式系統。可能你有 a、b、c 三個伺服器。a 伺服器生成了乙個檔案,還需要實時同步到 b 和 c。當然也可以讓 a、b、c 掛載同乙個磁碟。問題又來了,這個檔案要不要備份呢?

2. redis cache

請求--> 介面介面---> 模板渲染 --> 儲存資料--> 響應 dom

把請求的 url 當做 key,把模板渲染好的資料當做值,然後根據快取規則,把資料儲存到 redis。

這種小成本的快取在我們的系統中有實踐,的確大幅提高了系統的響應時間和 qps,頁面的請求大部分是從 redis 讀資料,然後返回,單機測試過極限效能,14k qps。簡單描述一下。我們稱之為靜態化staticize

開始請求

請求校驗,filter 等等

查詢快取 redis

如果有快取,則直接響應

沒有快取,查詢資料,重新渲染,儲存到 redis.

響應如果需更新快取,只需要刪掉對應的redis 值

這種頁面在實際情況中更常見。原則:靜態頁面快取,動態部分非同步請求。

靜態部分也是模板渲染過來的,瀏覽器會從 cdn 或者後台快取中獲取到靜態頁面。頁面響應的時間和瀏覽器的渲染會直接影響使用者體驗。動態更新的部分一般會在一些細節部分,比如頁面的登入狀態。對於所有使用者來說,我看到的這個頁面,只有使用者頭像部分會不一致。如果系統為每個使用者生成乙個靜態頁面成本就太高了,而且完全沒必要。

這個頁面就變成了:頁面 == 短時靜態頁面 + 區域性動態頁面。

『使用者狀態資訊』這個特殊的動態內容,還需要用到本地的快取機制。使用者在切換頁面的時候,每個頁面都需要動態載入使用者資訊,所以我們的做法是在第一次請求到這個資訊的時候,儲存到 localstorage,然後設定過期時間。退出的時候,主動清理 localstorage。

以上的方案同樣適用於非同步請求。

一般會有主動失效和自動失效快取機制。

cdn 和 redis 等快取都可以根據規則設定快取時間。快取過期後,會再次獲取新的資料。

主動更新一般會用 api 呼叫方式實現。比如刪除 key,或者呼叫 cdn 介面進行刪除操作

一般會在第一次請求的時候生成快取,如果伺服器端沒有快取,然後在同一時刻出現高併發請求,請求會直接到達業務邏輯部分,很可能導致系統直接掛掉。

解決辦法:

主動建立快取。快取求由系統定時建立。

請求的時候設定標誌位。第乙個請求到達,標識這個 url 正在建立快取,其他請求進入等待佇列。

cdn 動態加速如下圖所示:

// 短時快取,動靜結合

api/user/1// 純動態

post/hello-world// 永久靜態

所以,1、3頁面會放到 cdn,2 直接去源站請求。怎麼做到呢?

在 cdn 配置自主源站。意味著請求 cdn 位址的時候,cdn 會去源站請求資料,然後快取到 cdn 節點。

設定快取規則

/ 快取 1 分鐘

/post/* 快取 1 年

/api/ 不設定快取

cname www.localhost.com 到 cdn 提供的空間網域名稱

乙個 url 可能會在不同的平台有不同的返回和表現形式。

產品的想法都是很完美,乙個按鈕在不同的平台會有不同的顯示狀態。實際情況非常複雜,在我們的系統中,出現過乙個頁面出現在 七 個平台,每個平台的顯示效果會不一致。不管是模板渲染,或者是 js 處理按鈕狀態等等都是非常複雜的,或者 pc 和移動端頁面表現出樣式和結構差異。如果還要把這個頁面放到快取,就更加複雜了。

為每個平台生成乙份快取?可以!

cdn 識別**去讀取不同的檔案,就需要 cdn 那邊做一些開發工作了。upyun、七牛這邊暫時不支援的。bat這種大公司他們自己維護的 cdn 就能完美地做到。

另一種思路:

1個專案,兩個網域名稱,2個動態 cdn。pc 和移動端頁面分離、介面共享。

例如:為同乙個專案配置兩個網域名稱:www.localhost.comm.www.localhost.com,同時為這兩個網域名稱各設定乙個動態 cdn。

由一專案提供兩個網域名稱服務,比如:indexcontroller.main處理請求/homepage,移動端和 pc 端的請求路徑分別為

mainaction 會根據請求**url,分別渲染不同的頁面。不同的網域名稱頁面,也就被不同的動態 cdn 快取起來。

對於/api/***x的介面,自然不需要做 pc 和移動端或者其他平台的區分,乙個 action 就可以解決了。這樣就避免了維護兩套系統的問題。

以上,全站快取基本完成。

不要憑空去拉高 qps或者亂用快取,根據你的業務和實際情況來對待。最重要的事情就是要牢記:保持簡潔,按需使用。

python全站爬蟲

通過正規表示式找到當前頁面中的所有url,儲存在set中 剔除重複 用類似圖資料結構的深度優先遍歷演算法遍歷set,實現全站爬蟲。from urllib import request from bs4 import beautifulsoup as bs import re import time ...

PHP全站防注入

arrfiltrate array union 出錯後要跳轉的url,不填則預設前一頁 strgourl 是否存在陣列中的值 functionfunstringexist strfiltrate,arrfiltrate returnfalse 合併 post和 get 驗證開始 foreach ar...

實現全站HTTPS加密

阿里雲大學課程 實現全站https加密 課程介紹 最近幾年隨著各種網際網路安全事件的頻繁發生,https逐漸取代http,成為傳輸協議界的新標準。阿里巴巴集團也在 天貓也啟動了規模巨大的業務改造,將百萬計的頁面從http切換到https,實現網際網路加密 可信訪問,使用https技術對 進行全站加密...