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