web性能提升錄:全站緩存的時代已經跟不上需求

来源:http://www.cnblogs.com/zhaowmm/archive/2016/06/27/5620295.html
-Advertisement-
Play Games

原則:動靜分離,分級緩存,主動失效。 Web 開發中,介面會被分為以下幾類: 純靜態頁面。打死我都不會修改的頁面。很長一段時間內,基本上不會修改。比如:關於我們。 純動態頁面。實時性,個性化要求比較高。頁面變化很大,或者每個用戶看到的都不一樣,比如:朋友圈。 短時靜態頁面。在一定時間內基本不會變化, ...


  原則:動靜分離,分級緩存,主動失效。

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

  純靜態頁面。打死我都不會修改的頁面。很長一段時間內,基本上不會修改。比如:關於我們。

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

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

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

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

  模板渲染

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

  HtmlDOM == VeiwEngine.render(template ,data);

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

  頁面緩存的方案

  1. 純靜態頁面

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

  2. 純動態頁面

  都說是動態頁面了,那就不要做頁面緩存了。可以考慮做數據緩存,或者是 redis、DB 緩存。

  3. 短時靜態頁面

  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 值

  4. 動靜結合的頁面

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

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

  這個頁面就變成了:頁面 == 短時靜態頁面 + 局部動態頁面。

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

  比如:個性化,個人推薦這種因人而異的板塊都可以做成局部動態頁面的形式。

  5. 數據緩存

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

  對於CDN 或者其他緩存來說,緩存不知道你存的內容是 DOM 還是 JSON,還是其他格式。它只是幫你存儲數據。你同樣可以的把,數據介面、局部 DOM 結構(非完整 html 格式)存儲到 CDN 或者是 redis 中。比如:頁面的配置信息,或者從相關推薦系統請求的 dom 結構。

  緩存更新

  一般會有主動失效和自動失效緩存機制。

  CDN 和 redis 等緩存都可以根據規則設置緩存時間。緩存過期後,會再次獲取新的數據。主動更新一般會用 API 調用方式實現。比如刪除 key,或者調用 CDN 介面進行刪除操作

  緩存穿透

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

  解決辦法:

  主動創建緩存。緩存求由系統定時創建。

  請求的時候設置標誌位。第一個請求到達,標識這個 url 正在創建緩存,其他請求進入等待隊列。

  全站 CDN 加速

  CDN 動態加速如下圖所示:

  例如我的網站有以下介面和頁面:

  http://www.localhost.com/

  http://www.localhost.com/api/user/1

  http://www.localhost.com/post/hello-world

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

  在 CDN 配置自主源站。意味著請求 CDN 地址的時候,CDN 會去源站請求數據,然後緩存到 CDN 節點。

  設置緩存規則

  / 緩存 1 分鐘

  /post/* 緩存 1 年

  /api/ 不設置緩存

  cname www.localhost.com 到 CDN 提供的空間功能變數名稱

  多平臺 Mulit Origin

  一個 URL 可能會在不同的平臺有不同的返回和表現形式。

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

  為每個平臺生成一份緩存?可以!

  平臺的識別來自 UserAgent,不同的瀏覽器或者 app,都有不同的UserAgent。不同的來源我們稱之為 Origin。Origin + url 就可以生成唯一的 key,去識別唯一的緩存。緩存不限於 redis 和 文件緩存。

  CDN 識別來源去讀取不同的文件,就需要 CDN 那邊做一些開發工作了。Upyun、七牛這邊暫時不支持的。BAT這種大公司他們自己維護的 CDN 就能完美地做到。

  另一種思路:

  1個項目,兩個功能變數名稱,2個動態 CDN。PC 和移動端頁面分離、介面共用。

  例如:為同一個項目配置兩個功能變數名稱: www.localhost.com 和 m.www.localhost.com ,同時為這兩個功能變數名稱各設置一個動態 CDN。

  由一項目提供兩個功能變數名稱服務,比如: IndexController.main 處理請求 /homepage ,移動端和 PC 端的請求路徑分別為

  http://m.www.localhost.com/homepage

  http://www.localhost.com/homepage

  main action 會根據請求來源url,分別渲染不同的頁面。不同的功能變數名稱頁面,也就被不同的動態 CDN 緩存起來。

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

  結語

  以上,全站緩存基本完成。

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • //獲取到當前時間 Date date=new Date(); DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time=format.format(date); ...
  • <!doctype html><html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" src="jquery.js"></script> </head> ...
  • <!doctype html><html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" src="jquery.js"></script> </head> ...
  • 使用sui mobile做的選擇控制項,其中sm.js有修改,增加自定義api,詳情請看index.html的註釋,不多說了,上代碼 引用文件及demo:http://pan.baidu.com/s/1i5tuuzz ...
  • 1、JS中的記憶體空間分為兩種:棧記憶體、堆記憶體 棧記憶體:提供JS代碼執行的環境;存儲基本數據類型的值; ->全局作用域或者私有的作用域其實都是棧記憶體 堆記憶體:存儲引用數據類型的值(對象是把屬性名和屬性值存儲進去,函數是把函數體中的代碼當做字元串存儲進去) 2、當瀏覽器載入我們HTML頁面的時候,首先會 ...
  • <img class="desc_img" src="http://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=html&step_word=&pn=0&spn=0&di=87025285600&pi=&rn=1&tn=baid... ...
  • 博客近兩個月沒有更新了,沒有時間只是藉口,主要還是沒有養成寫博客的習慣,需自省!把做的東西寫出來,把不會的人教會,這是個知識內化的過程,也是提升自己的過程,so...博客還需繼續,前端的路很遠,還需繼續努力~ 1 線上編輯試題頁面設計 最近在做一個線上編輯試題系統,該系統是基於UEditor做的二次 ...
  • 前幾篇文章,我們介紹瞭如何使用HTML5 + WebGL,從零開始一步一步打造一個基於web的3D機房展示程式,並陸續增加了資產管理和動環等效果。這篇文章是前三篇文章的延伸,進一步把3D機房從房間做了擴展,實現從“地球(地圖)”— “園區”— “樓宇”— “機房”的炫酷效果,以及一些其他3D應用的開... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...