ABP module-zero +AdminLTE+Bootstrap Table+jQuery權限管理系統第十五節--緩存小結與ABP框架項目中 Redis

ABP+AdminLTE+Bootstrap Table權限管理系統一期 Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMShtml

爲何要用緩存

爲何要用緩存呢,說緩存以前先說使用緩存的優勢。git

  • 減小寄宿服務器的往返調用(round-trips)。
  • 若是緩存在客戶端或是代理,將減小對服務器的請求,減小帶寬。
  • 減小對數據庫服務器的往返調用(round-trips)。
  • 當內容緩存在web服務器,可以減輕對數據庫的請求。
  • 減小網絡帶寬。
  • 避免了從新生成可重用內容的時耗。
  • 提升性能
  • 由於緩存減小了round-trips, network traffic(網絡帶寬),並避免- 了生成可重用內容的時耗,因此對性能有巨大的提升。

傳統的緩存方式

傳統的緩存方式以下面這張圖 github

image.png
以前咱們處理方式處理起來也很簡單

  1. 頁面輸出緩存,直接在 ASP.NET中頁面緩存的使用OutputCache 在aspx頁的頂部加這樣一句便可: <%@ OutputCache Duration="60" VaryByParam="none" %> Duration 表示緩存的時間秒,必選,不然報錯。
  2. 第二種方式 if (this.Cache["Keys"] == null) { this.Cache.Insert("Keys", List, null, DateTime.Now.AddHours(2), TimeSpan.Zero); }

這裏是檢查緩存中Keys是否存在,若是不存在,則寫入一個新的值List.還有其餘的一些使用方法。 web

image.png

上面兩種方式顯然不在如今使用範疇,也不在我想說的範疇以內。,年代貌似有點久遠,不用webform基本用不到。如今咱們更可能是的使用MVC。 咱們想說的是MVC輸出緩存。redis

MVC緩存

輸出緩存Outputcache ,分爲Action輸出緩存和Controller輸出緩存。使用的場景包括某個頁面的數據更新不是很頻繁,不須要每次都從數據庫區查詢。緩存起來從內存中讀取。數據庫

數據緩存:是相對於全局的。任何地方須要調用的時候均可以去調用。使用的場景包括權限管理這種模塊的。每一個角色對於菜單的訪問都是固定的,因此有必要將角色,權限,菜單這種數據作一個全局的數據緩存。修改時再作緩存的更新。windows

輸出緩存和數據緩存區別:打個比方輸出緩存就像是「局部變量」,數據緩存就像是全局變量(只是個比喻)。緩存

Controller輸出緩存和 Action緩存使用方式是同樣的,就是Controller 或Action上打[OutPutCache]特性標籤。可是他們之間又是有區別的。安全

1、控制器緩存服務器

Control緩存的做用域是整個控制器,因此在這個控制器下的全部Action都會被緩存起來。Control緩存的粒度比較粗,應用也比較少些。 [OutputCache(Duration = 10)] public class HomeController : Controller { public ActionResult Index() { ViewBag.CurrentTime = DateTime.Now; return View(); } } 2、Action緩存 將[OutPutCache]特性標籤打在Action上,這樣,只有加緩存的Action纔會有緩存,其餘的Action是沒有的。

Outputcache特性經常使用的屬性參數

名稱 描述
AllowMultiple 獲取或設置一個值,該值指示是否可指定篩選器特性的多個實例。
CacheProfile 獲取或設置緩存配置文件名稱。
ChildActionCache 獲取或設置子操做緩存。
Duration 獲取或設置緩存持續時間(以秒爲單位)。
Location 獲取或設置位置。
NoStore 獲取或設置一個值,該值指示是否存儲緩存。
Order 獲取或者設置執行操做篩選器的順序。
SqlDependency 獲取或設置 SQL 依賴項。
TypeId (從Attribute繼承。)
VaryByContentEncoding 獲取或設置基於內容變化的編碼。
VaryByCustom 獲取或設置基於自定義項變化的值。
VaryByHeader 獲取或設置基於標頭變化的值。
VaryByParam 獲取或設置基於參數變化的值。

輸出緩存CacheProfile使用配置文件設置緩存

舉例其中的CacheProfile,這種方式便於統一配置,固然也能夠設置參數duration、location 、varybyparam等。咱們須要在system.web 節點下加入這些

`






其實做用和效果仍是同樣,無非就是方便點,統一的配置參數都直接寫webconfig文件裏面。其實也能夠Controller中寫。 配置好了以後咱們直接在控制器調用相應的名字的OutputCache特性標籤便可。 [OutputCache(CacheProfile= "TestConfigCache")] public ActionResult Index() { ViewBag.CurrentTime = DateTime.Now; return View(); } ` 更多的方式,須要下去再研究下。

ABP中使用ICacheManager進行緩存管理

ABP中有兩種cache的實現方式:MemroyCacheRedisCache,二者都繼承至ICache接口(準確說是CacheBase抽象類)。ABP核心模塊封裝了MemroyCache來實現ABP中的默認緩存功能。 Abp.RedisCache這個模塊封裝RedisCache來實現緩存(經過StackExchange.Redis這個類庫訪問redis)。

ABP給出了一個抽象緩存基類。並在內部使用了該抽象基類。使用 MemoryCache 來實現了該抽象基類。它可以被任何其它的緩存類來擴展。Abp.RedisCache 包就擴展了該緩存基類。 ABP對外提供了一個緩存接口ICacheMananger。咱們經過構造函數注入這個接口來獲取緩存。示例以下:

image.png

在這個示例中,咱們注入了 ICacheManager接口,s而且獲取了一個名稱爲ControllerCache的緩存。首先咱們先對ControllerCache進行清除,而後存入緩存,緩存的名字是大小寫敏感的,那就是"ControllerCache"和"CONTROLLERCACHE"取得的緩存內容是不一樣的。

注意:GetCache方法 千萬不要在你的構造函數中使用GetCache方法。若是類不是一個單例對象那麼該緩存可能會被dispose掉。

ICache

ICacheManager.GetCache方法返回了一個ICache對象。每個緩存都是基於名稱單例存在的。只有首次訪問時纔會被建立,之後你每次用相同的名稱去獲取的緩存都是相同的。因此咱們能夠在不一樣的類中使用相同的名稱來共享相同的緩存。

在示例代碼中,咱們簡單的使用了ICache.Get方法,它有兩個參數:

  • key : 要獲取的緩存項的惟一標識符
  • factory:若是根據給定的key獲取到的緩存項爲空,那麼factory將會建立一個標識符爲key的緩存,而且返回該緩存

ICache接口還有其它方法,如前面Clear(),Get(),GetOrDefaultSetRemoveClear。固然也有這些方法的異步(async)版本。以下圖,我就懶得寫了。

image.png

ITypedCache

ICache 接口用key(字符串類型)來獲取緩存value(object類型)。ITypedCacheICahe提供了一個 類型安全 的包裝;爲了使類型安全轉換(ICacheITypedCache),咱們能夠用擴展方法 AsTyped,而不須要寫其它強制類型轉換的代碼,以下所示: ITypedCache<int, Item> myCache = _cacheManager.GetCache("MyCache").AsTyped<int, Item>();

Configuration

緩存的過時時間默認是60分鐘。它是變化的。若是你在60分鐘內沒有使用該緩存,該緩存會被自動的移除。若是你想改變全部的緩存或者指定的緩存來的默認過時時間,你能夠這樣作,實現以下: //對全部緩存的配置 Configuration.Caching.ConfigureAll(cache => { cache.DefaultSlidingExpireTime = TimeSpan.FromHours(2); }); //對指定緩存的配置 Configuration.Caching.Configure("MyCache", cache => { cache.DefaultSlidingExpireTime = TimeSpan.FromHours(8); });

這段代碼你應該放在模塊(module)的 PreInitialize 方法中。如上所示:MyCache將會在8小時後過時,而其餘的緩存將在2小時後過時。

這些配置將會在首次建立緩存的時候生效。配置不只僅侷限於DefaultSlidingExpireTime,你能夠利用ICache接口中的屬性獲取方法來自由的配置而且初始化它們。

Entity Caching

ABP的緩存系統是以通用爲目的,它有一個 EntityCache 基類,若是你須要的話,這個基類能夠幫助你緩存實體。使用這個基類,咱們能夠經過ID取得實體,而且咱們經過ID來緩存實體,這樣之後就不須要頻繁的查詢數據庫去取得實體。假設咱們有個Person實體,像下面同樣: public class Person : Entity { public string Name { get; set; } public int Age { get; set; } }

而且,假設咱們經過該實體的Id,須要頻繁調用取得Person實體的Name。首先,咱們應該建立一個類來存儲 cache items: [AutoMapFrom(typeof(Person))] public class PersonCacheItem { public string Name { get; set; } }

咱們 不該該直接存儲實體到緩存中 由於緩存的時候須要序列化緩存對象而實體可能不能被序列化(尤爲是實體的導航屬性)。這就是爲何咱們定義了一個簡單的像DTO的類來存儲數據到緩存中。咱們添加了 AutoMapFrom 特性,這是由於咱們想使用 AutoMapper 來自動的轉換 Person 實體爲 PersonCacheItem 對象。若是咱們不使用 AutoMapper,那麼咱們應該重寫 EntityCache 類的 MapToCacheItem 方法手動轉換/映射它。

然而這不是必須的,咱們可能想定義一個接口爲緩存類: public interface IPersonCache : IEntityCache<PersonCacheItem> { } 最後,咱們能夠建立緩存類來緩存Person實體: public class PersonCache : EntityCache<Person, PersonCacheItem>, IPersonCache, ITransientDependency { public PersonCache(ICacheManager cacheManager, IRepository<Person> repository) : base(cacheManager, repository) { } }

這樣就OK了,咱們的person緩存已經準備好可使用了。緩存類可使瞬時(如同這個例子)或者是單例。這不是說緩存數據是瞬態的。在你的應用程序中它一直是全局緩存而且是線程安全的。

如今,不管在什麼地方咱們須要取得Person的Name,咱們能夠經過Person的Id從緩存中取得它。以下所示: public class MyPersonService : ITransientDependency { private readonly IPersonCache _personCache; public MyPersonService(IPersonCache personCache) { _personCache = personCache; } public string GetPersonNameById(int id) { return _personCache[id].Name; //alternative: _personCache.Get(id).Name; } } 咱們很容易的注入 IPersonCache 接口,經過該接口取得緩存項和Name屬性。

那麼EntityCache是怎麼工做的?

  • 在首次調用的時候咱們經過倉儲從數據庫中取得實體。那麼隨後的調用都是從緩存中取得。
  • 若是實體被更新或者刪除,它會自動的無效實體。所以,它會在下次調用的時候從新從數據庫中檢索數據。
  • 使用 IObjectMapper 接口來映射實體到緩存項。IObjectMapper 接口在 AutoMapper 中被實現。因此,若是你使用了自動映射,那麼就須要 AutoMapper模塊。你能夠重寫 MapToCacheItem 方法手動映射它到緩存項。
  • 使用緩存類的FullName做爲緩存的Name,你能夠經過傳入的緩存名到基類的構造函數來改變它。
  • 它是線程安全的。 若是你有更復雜的緩存需求,那麼你須要擴展 EntityCache 類或者建立你本身的解決方案。

Redis Cache 集成

Redis是什麼,Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。它能夠用做數據庫、緩存和消息中間件。它支持多種類型的數據結構,如字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)與範圍查詢、bitmaps、hyperloglogs和地理空間(geospatial)索引半徑查詢。 Redis 是徹底開源免費的,遵照BSD協議,是一個高性能的key-value數據庫。 Redis 與其餘 key - value 緩存產品有如下三個特色

  • Redis支持數據的持久化,能夠將內存中的數據保存在磁盤中,重啓的時候能夠再次加載進行使用。
  • Redis不只僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
  • Redis支持數據的備份,即master-slave模式的數據備份。 Redis 優點
  • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。
  • 原子 – Redis的全部操做都是原子性的,意思就是要麼成功執行要麼失敗徹底不執行。單個操做是原子性的。多個操做也支持事務,即原子性,經過MULTI和EXEC指令包起來。
  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過時等等特性。
  • 多實用工具 - Redis是一個多實用工具,可用於多種用例,如:緩存,消息隊列(Redis本地支持發佈/訂閱),應用程序中的任何短時間數據,例如,web應用程序中的會話,網頁命中計數等。

(1)首先,咱們前往github.com/dmajkic/red…下載安裝包,直接下一步下一步就能夠了。 而後打開安裝的地址就能夠看到以下的文件:

image.png
(2) 而後啓動Redis服務,咱們cmd到安裝目錄下,而後輸入命令 redis-server.exe redis.windows.conf 就會看到下面的畫面證實咱們啓動服務成功。
image.png
abp默認Cache Mananger是使用 in-memory來緩存。因此,這可能會成爲一個問題,若是有多個併發的Web服務運行在同一個應用中。在這種狀況下,你可能想要一個分佈式/中央緩存服務器。那麼,你可使用Redis來做爲你的緩存服務。 首先,你須要安裝 Abp.RedisCachenuget package 到你的項目中(你能夠安裝它到你的Web項目)。這裏我遇到一個錯誤。
image.png
開始的時候我搞了半天不知道爲何會出現這個莫名其妙的錯誤,後來才發現,原來我引入Abp.RedisCache版本和abp版本不一致。才致使的這個錯誤,好比你abp是3.1.1,那麼你的Abp.RedisCache最好也是對應的版本,最好的話把abp和Abp.RedisCache都升級到最新版本,就不會有錯誤了。 而後咱們看看Abp.Runtime.Caching.Redis;依賴項以及之間的關係。
image.png
而後在ABPCMSWebModule配置一下。
image.png
ABPCMSApplicationModule中引入。
image.png
Web.config中配置
image.png
你也能夠添加配置到appSettings來設置Redis數據庫的Id。如: <add key="Abp.Redis.Cache.DatabaseId" value="2"/> 在同一個服務器上使用不一樣的數據庫Id是很是有用的這能夠建立不一樣的Key Spaces(隔離緩存)。 UseRedis有一個重載方法,你能夠經過這個方法來傳入配置參數,這能夠覆蓋掉配置文件中的配置。關於Redis的其餘配置能夠查看 Redis文檔

在下面UserList打下斷點調試進去。

image.png
看到效果以下圖,證實咱們AbpRedisCache引入成功。
image.png
固然爲了更好的進行可視化操做,我建議使用跨平臺開源Redis DB管理工具(Redis Desktop Manager)地址: redisdesktop.com/download 下載下來直接下一步下一步安裝便可。
image.png
而後運行項目,而後咱們在看下Redis Desktop Manager工具,效果以下圖:
image.png
使用可視化工具很方便

  1. 新建鏈接,輸入redis主機host,端口號port,再起個生動形象,簡明達意的別名。
  2. 該工具支持根據篩選條件查詢key,add new key,reload等。
  3. 支持經常使用redis操做,針對目標key執行rename,delete,addrow,reload value操做。
  4. 命令控制檯操做 !你們感興趣能夠本身玩一下。 另外關於實體修改後自動更新緩存的實現遠離能夠參考 www.cnblogs.com/loyldg/p/us… 這個文章。

Github項目地址:github.com/Jimmey-Jian…

ABP+AdminLTE+Bootstrap Table權限管理系統一期 [Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS](https://github.com/Jimmey-Jiang/ABP-

相關文章
相關標籤/搜索