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
以前咱們處理方式處理起來也很簡單<%@ OutputCache Duration="60" VaryByParam="none" %>
Duration 表示緩存的時間秒,必選,不然報錯。if (this.Cache["Keys"] == null) { this.Cache.Insert("Keys", List, null, DateTime.Now.AddHours(2), TimeSpan.Zero); }
這裏是檢查緩存中Keys是否存在,若是不存在,則寫入一個新的值List.還有其餘的一些使用方法。 web
上面兩種方式顯然不在如今使用範疇,也不在我想說的範疇以內。,年代貌似有點久遠,不用webform基本用不到。如今咱們更可能是的使用MVC。 咱們想說的是MVC輸出緩存。redis
輸出緩存: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是沒有的。
名稱 | 描述 |
---|---|
AllowMultiple | 獲取或設置一個值,該值指示是否可指定篩選器特性的多個實例。 |
CacheProfile | 獲取或設置緩存配置文件名稱。 |
ChildActionCache | 獲取或設置子操做緩存。 |
Duration | 獲取或設置緩存持續時間(以秒爲單位)。 |
Location | 獲取或設置位置。 |
NoStore | 獲取或設置一個值,該值指示是否存儲緩存。 |
Order | 獲取或者設置執行操做篩選器的順序。 |
SqlDependency | 獲取或設置 SQL 依賴項。 |
TypeId | (從Attribute繼承。) |
VaryByContentEncoding | 獲取或設置基於內容變化的編碼。 |
VaryByCustom | 獲取或設置基於自定義項變化的值。 |
VaryByHeader | 獲取或設置基於標頭變化的值。 |
VaryByParam | 獲取或設置基於參數變化的值。 |
舉例其中的CacheProfile,這種方式便於統一配置,固然也能夠設置參數duration、location 、varybyparam等。咱們須要在system.web 節點下加入這些
`
其實做用和效果仍是同樣,無非就是方便點,統一的配置參數都直接寫webconfig文件裏面。其實也能夠Controller中寫。 配置好了以後咱們直接在控制器調用相應的名字的
OutputCache特性標籤便可。
[OutputCache(CacheProfile= "TestConfigCache")] public ActionResult Index() { ViewBag.CurrentTime = DateTime.Now; return View(); } ` 更多的方式,須要下去再研究下。
ABP中有兩種cache的實現方式:MemroyCache
和RedisCache
,二者都繼承至ICache接口(準確說是CacheBase
抽象類)。ABP核心模塊封裝了MemroyCache
來實現ABP中的默認緩存功能。 Abp.RedisCache
這個模塊封裝RedisCache
來實現緩存(經過StackExchange.Redis
這個類庫訪問redis)。
ABP給出了一個抽象緩存基類。並在內部使用了該抽象基類。使用 MemoryCache 來實現了該抽象基類。它可以被任何其它的緩存類來擴展。Abp.RedisCache 包就擴展了該緩存基類。 ABP對外提供了一個緩存接口ICacheMananger。咱們經過構造函數注入這個接口來獲取緩存。示例以下:
在這個示例中,咱們注入了 ICacheManager接口,s而且獲取了一個名稱爲ControllerCache的緩存。首先咱們先對ControllerCache進行清除,而後存入緩存,緩存的名字是大小寫敏感的,那就是"ControllerCache"和"CONTROLLERCACHE"取得的緩存內容是不一樣的。
注意:GetCache方法 千萬不要在你的構造函數中使用GetCache方法。若是類不是一個單例對象那麼該緩存可能會被dispose掉。
ICacheManager.GetCache
方法返回了一個ICache
對象。每個緩存都是基於名稱單例存在的。只有首次訪問時纔會被建立,之後你每次用相同的名稱去獲取的緩存都是相同的。因此咱們能夠在不一樣的類中使用相同的名稱來共享相同的緩存。
在示例代碼中,咱們簡單的使用了ICache.Get
方法,它有兩個參數:
ICache接口還有其它方法,如前面Clear()
,Get()
,GetOrDefault
,Set
,Remove
和Clear
。固然也有這些方法的異步(async)版本。以下圖,我就懶得寫了。
ICache
接口用key(字符串類型)來獲取緩存value(object類型)。ITypedCache
爲ICahe
提供了一個 類型安全 的包裝;爲了使類型安全轉換(ICache
到ITypedCache
),咱們能夠用擴展方法 AsTyped
,而不須要寫其它強制類型轉換的代碼,以下所示: ITypedCache<int, Item> myCache = _cacheManager.GetCache("MyCache").AsTyped<int, Item>();
緩存的過時時間默認是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
接口中的屬性獲取方法來自由的配置而且初始化它們。
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是怎麼工做的?
Redis是什麼,Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。它能夠用做數據庫、緩存和消息中間件。它支持多種類型的數據結構,如字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)與範圍查詢、bitmaps、hyperloglogs和地理空間(geospatial)索引半徑查詢。 Redis 是徹底開源免費的,遵照BSD協議,是一個高性能的key-value數據庫。 Redis 與其餘 key - value 緩存產品有如下三個特色:
(1)首先,咱們前往github.com/dmajkic/red…下載安裝包,直接下一步下一步就能夠了。 而後打開安裝的地址就能夠看到以下的文件:
(2) 而後啓動Redis服務,咱們cmd到安裝目錄下,而後輸入命令redis-server.exe redis.windows.conf
就會看到下面的畫面證實咱們啓動服務成功。
abp默認Cache Mananger是使用
in-memory來緩存。因此,這可能會成爲一個問題,若是有多個併發的Web服務運行在同一個應用中。在這種狀況下,你可能想要一個分佈式/中央緩存服務器。那麼,你可使用Redis來做爲你的緩存服務。 首先,你須要安裝
Abp.RedisCachenuget package 到你的項目中(你能夠安裝它到你的Web項目)。這裏我遇到一個錯誤。
開始的時候我搞了半天不知道爲何會出現這個莫名其妙的錯誤,後來才發現,原來我引入Abp.RedisCache版本和abp版本不一致。才致使的這個錯誤,好比你abp是3.1.1,那麼你的Abp.RedisCache最好也是對應的版本,最好的話把abp和Abp.RedisCache都升級到最新版本,就不會有錯誤了。 而後咱們看看Abp.Runtime.Caching.Redis;依賴項以及之間的關係。
而後在ABPCMSWebModule配置一下。
ABPCMSApplicationModule中引入。
Web.config中配置
你也能夠添加配置到appSettings來設置Redis數據庫的Id。如:
<add key="Abp.Redis.Cache.DatabaseId" value="2"/>
在同一個服務器上使用不一樣的數據庫Id是很是有用的這能夠建立不一樣的Key Spaces(隔離緩存)。
UseRedis有一個重載方法,你能夠經過這個方法來傳入配置參數,這能夠覆蓋掉配置文件中的配置。關於Redis的其餘配置能夠查看
Redis文檔。
在下面UserList打下斷點調試進去。
看到效果以下圖,證實咱們AbpRedisCache引入成功。 固然爲了更好的進行可視化操做,我建議使用跨平臺開源Redis DB管理工具(Redis Desktop Manager)地址: redisdesktop.com/download 下載下來直接下一步下一步安裝便可。 而後運行項目,而後咱們在看下Redis Desktop Manager工具,效果以下圖: 使用可視化工具很方便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-