国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

以 Okhttp3源碼 為例 ------ 探索 緩存機(jī)制 的原理和實(shí)現(xiàn)(一)

2019-11-09 17:37:11
字體:
供稿:網(wǎng)友

緩存機(jī)制一直以來是一個不可忽視的重要模塊,廣泛地被運(yùn)用到 網(wǎng)頁端和移動端。對于服務(wù)器而言,客戶端的緩存很大程度上緩解了它的壓力,更是為用戶帶來了產(chǎn)品快速響應(yīng)的體驗(yàn),擁有很多好處。既然是網(wǎng)絡(luò)請求,必然與HTTP協(xié)議聯(lián)系緊密,不論你是否有這之類的經(jīng)驗(yàn),此篇將會從基礎(chǔ)開始總結(jié),共同學(xué)習(xí)緩存機(jī)制。


一. 初識緩存機(jī)制原理

1. 為何需要緩存?

緩存減少了冗余的數(shù)據(jù)傳輸,節(jié)省了網(wǎng)絡(luò)費(fèi)用。緩存緩解了網(wǎng)絡(luò)瓶頸的問題,不需要更多的網(wǎng)絡(luò)帶寬就能更快的加載頁面。緩存降低了對原始服務(wù)器的要求,服務(wù)器可以更快的響應(yīng)。


2. 緩存的原理

這里寫圖片描述

如上圖片所示,這就是瀏覽器的緩存原理圖,以流程圖的形式描繪出了大致的緩存機(jī)制??催^幾遍后,便以為緩存機(jī)制也不過如此,移動端的緩存更是簡單,但實(shí)際并非如此,何時(shí)采取緩存?緩存何時(shí)失效?緩存失效后的做法?等等,有許多值得思考的地方,不過有些部分瀏覽器已經(jīng)代替實(shí)現(xiàn)了,所以,先來了解瀏覽器的緩存原理


(1)首先在有緩存的前提下,判斷緩存是否過期,因?yàn)榫彺嫦鄬Χ詴幸粋€存在的有效時(shí)間,如過期的話需要進(jìn)一步判斷是否向服務(wù)器發(fā)送請求。

(2)接著就是判斷 Etag ,它是關(guān)于緩存的一個字段,每次請求都會存在的一個標(biāo)識符,將文本哈希編碼來標(biāo)識當(dāng)前文本的狀態(tài)。首先會判斷這個Etag是否存在,如果存在便會向服務(wù)器發(fā)送請求,在請求時(shí)會攜帶參數(shù),參數(shù)If-None-Match會將Etag標(biāo)記上一起發(fā)送給服務(wù)器。服務(wù)器再決策Etag是否過期,根據(jù)返回的響應(yīng)碼來決定從緩存讀取還是請求響應(yīng)。

(3)但是Etag 這個字段并不是必須存在的,當(dāng)它不存在時(shí),會再次判斷 Last-Modified字段是否存在,這個字段表示響應(yīng)中資源最后一次修改的時(shí)間,說白了就是服務(wù)器最新一次修改文件的時(shí)間。如果存在的話,如同Etag一樣會向服務(wù)器發(fā)送請求,只是攜帶參數(shù)是會用If-Modified-Since去標(biāo)識Last-Modified字段,一起發(fā)送給服務(wù)。在服務(wù)器決策時(shí),會將Last-Modified與服務(wù)器修改文件的時(shí)間進(jìn)行比較,若無變化則直接從緩存中讀取,否則請求響應(yīng),接收新的數(shù)據(jù)。

以上內(nèi)容就是瀏覽器的緩存機(jī)制,了解下來并非簡單地判斷緩存過期后,就去訪問服務(wù)器,還要再次進(jìn)行一系列的判斷,真正確定緩存與服務(wù)器上內(nèi)容不同時(shí),需要更新時(shí),才是去訪問服務(wù)器請求最新數(shù)據(jù)。

這里,還需要強(qiáng)調(diào)一點(diǎn),雖然緩存已經(jīng)過期了,但是并非緩存與服務(wù)器的內(nèi)容不同,比如服務(wù)端的數(shù)據(jù)并未做出任何更改,說明此時(shí)緩存的依舊是最新數(shù)據(jù)!所以還需要更詳細(xì)的判斷再來決定是否需要請求服務(wù)器更新數(shù)據(jù),所以,避免了不必要的請求,這種緩存機(jī)制很大程度上減輕了服務(wù)器的壓力!




3. 緩存相關(guān)的字段

以下字段都是在HTTP協(xié)議中的重要字段。

(1)Expires:實(shí)體主體的過期時(shí)間。

此字段最初出現(xiàn)于 HTTP 1.0協(xié)議,指定緩存內(nèi)容的失效時(shí)間(如果該文本內(nèi)容支持緩存),使用的是一個絕對值。(格林威治時(shí)間GMT標(biāo)準(zhǔn))


(2)Cache-Control:控制緩存的行為。

此字段與Expires含義相同,那為何要存在兩個含義相同的字段呢?上面有提到,Expires是一個絕對值,服務(wù)器同客戶端校驗(yàn)的時(shí)候,有可能出現(xiàn)偏差,因?yàn)榭蛻舳说臅r(shí)間可以隨意進(jìn)行修改。即我們可以人為快進(jìn)客戶端時(shí)間,則服務(wù)器收到該時(shí)間后判斷當(dāng)前緩存已失效,可實(shí)際上緩存并未失效,所以這個字段就會出現(xiàn)一些問題。在HTTP 1.1協(xié)議出現(xiàn)了Cache-Control字段,它使用的是一個相對值,指令的參數(shù)有:

no-cache :無緩存指令,即每次請求直接從服務(wù)器獲取?!盋ache-Control”: “no-cachemax-age :代表緩存的有效時(shí)間,如果緩存只是用來和服務(wù)器做驗(yàn)證,可是設(shè)置更有效的”Cache-Control”:”max-age=0”。only-if-cached :先使用用緩存的數(shù)據(jù),如果客戶端有緩存,會立即顯示客戶端的緩存,這樣你的應(yīng)用程序可以在等待最新的數(shù)據(jù)下載的時(shí)候顯示一些東西, 重定向request到本地緩存資源,添加”Cache-Control”:”only-if-cached”。max-stale :即使緩存已過期,也可先展示出來。有時(shí)候過期的response比沒有response更好,設(shè)置最長過期時(shí)間來允許過期的response響應(yīng): int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale “Cache-Control”:”max-stale=” + maxStale。

(3)Last-Modified:資源的最后修改日期時(shí)間。

響應(yīng)中資源最后一次修改的時(shí)間,用于判斷服務(wù)器和客戶端資源是否一致的重要字段。


(4)ETag:資源的匹配信息。

也是用于判斷服務(wù)器和客戶端資源是否一致的重要字段響應(yīng)中資源的校驗(yàn)值,為何會存在相同意義的字段?因?yàn)槿绻阍诜?wù)器端修改資源后,Last-Modified會改變,可是此時(shí)客戶端與服務(wù)器端資源是否一定不同呢?也許你只是多加了一個空格,此時(shí)Last-Modified的改變意味著緩存已失效,可這樣請求服務(wù)器獲取到的數(shù)據(jù)卻是相同的。所以 HTTP協(xié)議推出了ETag, 它將服務(wù)器返回的 response整個編碼處理加密得到的一個值,在服務(wù)器上某個時(shí)段是唯一標(biāo)識的,將此值與客戶端緩存中的ETag進(jìn)行比較,可避免Last-Modified漏掉的問題。主旨在于比較兩者的內(nèi)容是否發(fā)生變化,而不是單純的比較時(shí)間。


(5)Date:創(chuàng)建報(bào)文的時(shí)間。

服務(wù)器創(chuàng)建報(bào)文時(shí)的時(shí)間。


(6)If-Modified-Since:比較資源的更新時(shí)間。

(判斷緩存是否失效時(shí)標(biāo)識在請求頭的標(biāo)識量)客戶端存取的該資源最后一次修改的時(shí)間,同Last-Modified


(7)If-None-Match:比較實(shí)體標(biāo)記。

(判斷緩存是否失效時(shí)標(biāo)識在請求頭的標(biāo)識量)客戶端存取的該資源的檢驗(yàn)值,同ETag。




4. 舉例熟悉HTTP 字段

這里寫圖片描述 這里寫圖片描述

以上文件是騰訊網(wǎng)的一個js文件,從右側(cè)可以得知:

Cache-Control:它支持緩存,緩存時(shí)間為259200秒,也就是三天。Date:表示資源發(fā)送的時(shí)間,指的是服務(wù)器的時(shí)間,與當(dāng)時(shí)請求時(shí)間并非相同!Expires:資源過期的時(shí)間,用Date加上緩存有效時(shí)間 max-age而得。Last-Modified :最后一次修改的時(shí)間。Etag:改js文件被編碼加密后得到的一個標(biāo)識值。




二. 了解 Okhttp3網(wǎng)絡(luò)框架 緩存功能

以上講解的部分,已經(jīng)初始了緩存機(jī)制的原理,接下來先通過一個小例子來見識 Okhttp3網(wǎng)絡(luò)框架的緩存機(jī)制。

1. 例子測試緩存功能

public class CacheHttp { public static void main(String args[]) throws IOException { int maxCacheSize = 10 * 1024 * 1024; //緩存大小的限制:10M //創(chuàng)建cache 類,需要兩個參數(shù)(文件目錄,文件大小) Cache cache = new Cache(new File("/Users/gym/source"), maxCacheSize); OkHttpClient client = new OkHttpClient.Builder().cache(cache).build(); Request request = new Request.Builder().url("http://www.QQ.com/"). cacheControl(new CacheControl.Builder().maxStale(365, TimeUnit.DAYS).build()). build(); Response response = client.newCall(request).execute(); String body1 = response.body().string(); System.out.關(guān)于以上代碼需要注意的是:response請求資源后的相應(yīng)有兩個相關(guān)方法,networkResponse()cacheResponse()。從字面意義上理解,一個是從網(wǎng)絡(luò)請求中獲取資源,另一個是從緩存中獲取資源。如果該資源是從服務(wù)器獲取的,networkResponse()返回值不會為null,即cacheResponse()返回值為null;如果是從緩存中獲取的,networkResponse()返回值為null,cacheResponse()返回值不為null。



這里寫圖片描述

以上截圖就是測試后的結(jié)果:因?yàn)轵v訊網(wǎng)是默認(rèn)有緩存的,所以我在第一次請求網(wǎng)絡(luò)時(shí),電腦中并無緩存,資源從服務(wù)器上獲取,cacheResponse()返回值為null。第二次重復(fù)請求騰訊網(wǎng),自然是從緩存中獲取資源。




2. 剖析緩存文件

從以上的小例子可得知Okhttp3網(wǎng)絡(luò)框架的緩存功能,再更詳細(xì)了解它的緩存,我在代碼中指定了將緩存放到文件夾中,在兩次請求網(wǎng)絡(luò)過后,文件夾多出了三個文件,如下圖所示: 這里寫圖片描述


(1)7f4c79817fabaeaa0e909754cfe655e7.0 文件

這里寫圖片描述

了解了HTTP協(xié)議中的字段后,發(fā)現(xiàn)這個內(nèi)容很是熟悉,是請求騰訊網(wǎng)后返回的response的一些數(shù)據(jù)。比如說請求的url、請求方式、HTTP協(xié)議、返回碼,下面的就是騰訊網(wǎng)響應(yīng)頭的數(shù)據(jù),不妨來看看哪些與緩存相關(guān)?

Cache-Control:騰訊網(wǎng)支持的緩存有效時(shí)間為60秒。Date:請求資源時(shí)的服務(wù)器時(shí)間(注意!該時(shí)間與客戶端的時(shí)間是不對應(yīng)的)。Expires:緩存失效時(shí)間,即Date加上緩存有效時(shí)間max-age。

(2)7f4c79817fabaeaa0e909754cfe655e7.1 文件

了解了一些基本數(shù)據(jù)后,騰訊網(wǎng)具體資源展示是在第二個文件,由于全部都是二進(jìn)制數(shù)據(jù),這里就不截圖展示了。

其實(shí)觀察前兩個文件名,很相似卻又有些不一樣,其實(shí)這是根據(jù)騰訊網(wǎng)的url加密后所得。



(3)journal 文件

這里寫圖片描述

此文件用于 Okhttp 緩存讀取目錄時(shí)會用到的,可以查看當(dāng)前客戶端請求網(wǎng)絡(luò)的次數(shù)和具體調(diào)用請求的地方。看第一行數(shù)據(jù),這個也是DiskLruCache所要用到的目錄結(jié)構(gòu)。




第一篇是介紹總結(jié)一下緩存機(jī)制有關(guān)的原理和Ohttp3網(wǎng)絡(luò)框架有關(guān)的功能,先鋪墊一下基礎(chǔ)。第二篇正式從解析源碼。

這里正式感謝nate老師對此的講解,我才得以總結(jié)學(xué)習(xí),thx~

希望對你們有幫助 :)


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宁蒗| 黎城县| 溧阳市| 博客| 易门县| 玛曲县| 禄劝| 登封市| 平乐县| 青海省| 哈尔滨市| 南阳市| 萨迦县| 龙井市| 迁安市| 思南县| 山阳县| 北流市| 芒康县| 株洲市| 武宁县| 东乡族自治县| 高安市| 石柱| 丰宁| 建宁县| 石棉县| 松潘县| 苍山县| 商水县| 平泉县| 大冶市| 和龙市| 石屏县| 福鼎市| 遵化市| 彭水| 池州市| 伊川县| 东宁县| 易门县|