原創(chuàng)|其它|編輯:郝浩|2009-11-23 09:43:46.000|閱讀 805 次
概述:為了提升系統(tǒng)的性能或減輕數(shù)據(jù)庫的壓力等原因,我們經(jīng)常在系統(tǒng)中使用緩存來把那些經(jīng)常使用的數(shù)據(jù)保留在內(nèi)存中。如果因?yàn)槟承┰颍彺嬷羞@些經(jīng)常使用的數(shù)據(jù)不能及時與數(shù)據(jù)源進(jìn)行同步更新,那么采用定時刷新緩存中的數(shù)據(jù)有可能就是一種合適的選擇。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
1.緣起:
為了提升系統(tǒng)的性能或減輕數(shù)據(jù)庫的壓力等原因,我們經(jīng)常在系統(tǒng)中使用緩存來把那些經(jīng)常使用的數(shù)據(jù)保留在內(nèi)存中。如果因?yàn)槟承┰颍彺嬷羞@些經(jīng)常使用的數(shù)據(jù)不能及時與數(shù)據(jù)源進(jìn)行同步更新,那么采用定時刷新緩存中的數(shù)據(jù)有可能就是一種合適的選擇。
如果你的緩存是定時刷新,那么你就需要自己為其維護(hù)一個定時器或循環(huán)引擎。如果你的系統(tǒng)中像這樣定時刷新的緩存有多個,而且每個緩存定時刷新的時間間隔又要求不一樣,那么,使這些緩存按照你預(yù)想的情況進(jìn)行運(yùn)轉(zhuǎn),你就需要花費(fèi)一些氣力。
我設(shè)計了定時刷新緩存管理器IRefreshableCacheManager來幫助你管理你系統(tǒng)中所有需要進(jìn)行定時刷新的緩存。它可以根據(jù)每個緩存的刷新時間間隔要求,在正確的時刻,刷新其所管理的緩存。你不用再自己手動去處理定時器或循環(huán)引擎,IRefreshableCacheManager自動為你完成這一切。
2.適用場合:
(1)系統(tǒng)中需要使用一個或多個需要進(jìn)行定時刷新的緩存。
(2)每個緩存所要求的刷新時間間隔可能都不一樣。
(3)刷新的時間間隔并不要求精確。
3.設(shè)計思想與實(shí)現(xiàn)
本節(jié)所講述的是定時刷新緩存管理器IRefreshableCacheManager,其重點(diǎn)在于“管理器”,而不是在于“緩存”,這點(diǎn)是必須清楚的。緩存只是被管理器管理的對象。
能夠被IRefreshableCacheManager管理的緩存必須是可定時刷新的緩存,也就是說,這些緩存必須實(shí)現(xiàn)IRefreshableCache接口以表明自己可以接受管理器的管理。IRefreshableCache定義如下:這個接口相當(dāng)簡單,它只要求緩存提供Refresh方法進(jìn)行刷新,并通過RefreshSpanInSecs屬性表示出自己希望進(jìn)行定時刷新的時間間隔。如果這個屬性設(shè)置為0(默認(rèn)值),則表示該緩存接受管理器的統(tǒng)一調(diào)度。
LastRefreshTime屬性用于記錄最后一次刷新結(jié)束的時間,該屬性的值由管理器進(jìn)行設(shè)置。
我們從IRefreshableCache接口的定義看到,管理器不用關(guān)心與緩存中的數(shù)據(jù)相關(guān)的任何信息,這是由具體的應(yīng)用在實(shí)現(xiàn)IRefreshableCache接口時才指定的。
接下來,我們看看IRefreshableCacheManager接口的定義:這個接口也有一個RefreshSpanInSecs屬性,如果被管理的緩存的RefreshSpanInSecs屬性設(shè)置的是0,那么管理器將用自身的這個屬性對其進(jìn)行調(diào)度。IRefreshableCacheManager接口的RefreshSpanInSecs屬性是為了簡化那種被管理的所有緩存都采用統(tǒng)一刷新時間間隔的情況而存在的。
RefreshableCacheManager在實(shí)現(xiàn)時仍然是借助前面介紹的循環(huán)引擎來進(jìn)行定時控制的。
IRefreshableCacheManager提供了AddCache和RemoveCache方法用于在運(yùn)行中動態(tài)的添加或移除緩存。
當(dāng)某個緩存在刷新時,拋出異常,則IRefreshableCacheManager會觸發(fā)CacheRefreshFailed事件,事件參數(shù)包含了出現(xiàn)異常的緩存和異常對象。
關(guān)于RefreshableCacheManager的實(shí)現(xiàn),要注意以下幾點(diǎn):
(1)管理器的實(shí)現(xiàn)是線程安全的,可以使用于多線程的環(huán)境中。我們對其內(nèi)部的緩存列表進(jìn)行了加鎖控制。
(2)管理器在初始化(Initialize)時,啟動了循環(huán)引擎(其DetectSpanInSecs必須設(shè)置為1秒),而且,將所有被管理的緩存的LastRefreshTime都設(shè)置為當(dāng)前時間。
(3)在實(shí)現(xiàn)EngineAction方法時,必須在foreach塊中使用try來捕捉引擎刷新時拋出的異常,而不是在try塊中進(jìn)行foreach。這個順序是重要的,如果在try塊中進(jìn)行foreach,那么當(dāng)一個緩存在刷新時拋出異常而導(dǎo)致foreach中斷后,后續(xù)緩存的刷新方法都將不會被檢測和調(diào)用。
(4)使用鎖不僅僅是為了同步對內(nèi)部緩存列表集合的修改,手動調(diào)用刷新方法RefreshNow也需要被同步,否則就可能出現(xiàn)兩個線程同時進(jìn)行檢測和刷新緩存的情況(一個是循環(huán)引擎的線程,另一個是手動調(diào)用RefreshNow方法的線程)。
4. 使用時的注意事項(xiàng)
(1)由于管理器內(nèi)部實(shí)現(xiàn)采用了循環(huán)引擎,所以定時刷新的時間間隔不可能很精確,而且,針對每個緩存的刷新方法的順序調(diào)用也是導(dǎo)致這種不精確的另一個原因。
(2)也由于管理器內(nèi)部實(shí)現(xiàn)采用了循環(huán)引擎,循環(huán)引擎能設(shè)置的最小檢測時間間隔為1秒,所以緩存的刷新時間間隔也不可能小于1秒。
(3)如果某個緩存在刷新時拋出異常,那么其LastRefreshTime屬性還是記錄的上一次成功刷新的時間。
5.擴(kuò)展
定時刷新緩存管理器通過事件暴露緩存刷新失敗的通知,當(dāng)緩存刷新發(fā)生異常時,我們可能需要將異常記錄到日志中。如果是這樣,那就可以直接使用ESBasic提供的RefreshableCacheExceptionLogBridge來完成。
RefreshableCacheExceptionLogBridge借助ESBasic.Logger.IAgileLogger組件來將異常的詳細(xì)信息記錄到目標(biāo)日志中。日志可以是文本文件,也可以是數(shù)據(jù)庫等其他存儲。ESBasic提供了IAgileLogger接口的實(shí)現(xiàn)FileAgileLogger,用于將日志寫入文本文件中。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:博客園