1. 程式人生 > >ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統第十五節--快取小結與ABP框架專案中 Redis Cache的實現

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統第十五節--快取小結與ABP框架專案中 Redis Cache的實現

快取

為什麼要用快取

為什麼要用快取呢,說快取之前先說使用快取的優點。

  • 減少寄宿伺服器的往返呼叫(round-trips)。
  • 如果快取在客戶端或是代理,將減少對伺服器的請求,減少頻寬。
  • 減少對資料庫伺服器的往返呼叫(round-trips)。
  • 當內容快取在web伺服器,能夠減輕對資料庫的請求。
  • 減少網路頻寬。
  • 避免了重新生成可重用內容的時耗。
  • 提高效能
  • 因為快取減少了round-trips, network traffic(網路頻寬),並避免- 了生成可重用內容的時耗,所以對效能有巨大的提高。

傳統的快取方式

傳統的快取方式如下面這張圖
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.還有其他的一些使用方法。
image.png

上面兩種方式顯然不在現在使用範疇,也不在我想說的範疇之內。,年代貌似有點久遠,不用webform基本用不到。現在我們更多是的使用MVC。
我們想說的是MVC輸出快取。

MVC快取

輸出快取Outputcache ,分為Action輸出快取和Controller輸出快取。使用的場景包括某個頁面的資料更新不是很頻繁,不需要每次都從資料庫區查詢。快取起來從記憶體中讀取。

資料快取:是相對於全域性的。任何地方需要呼叫的時候都可以去呼叫。使用的場景包括許可權管理這種模組的。每個角色對於選單的訪問都是固定的,所以有必要將角色,許可權,選單這種資料做一個全域性的資料快取。修改時再做快取的更新。

輸出快取和資料快取區別:打個比方輸出快取就像是“區域性變數”,資料快取就像是全域性變數(只是個比喻)。

Controller輸出快取和 Action快取使用方式是一樣的,就是Controller 或Action上打[OutPutCache]特性標籤。但是他們之間又是有區別的。

一、控制器快取

Control快取的作用域是整個控制器,所以在這個控制器下的所有Action都會被快取起來。Control快取的粒度比較粗,應用也比較少些。
[OutputCache(Duration = 10)] public class HomeController : Controller { public ActionResult Index() { ViewBag.CurrentTime = DateTime.Now; return View(); } }

二、Action快取

將[OutPutCache]特性標籤打在Action上,這樣,只有加快取的Action才會有快取,其他的Action是沒有的。

Outputcache特性常用的屬性引數

輸出快取CacheProfile使用配置檔案設定快取

舉例其中的CacheProfile,這種方式便於統一配置,當然也可以設定引數duration、location 、varybyparam等。我們需要在system.web 節點下加入這些

<!---CacheProfile配置檔案中設定快取--> <caching> <outputCacheSettings> <outputCacheProfiles> <add name="TestConfigCache" duration="20" location="Any" enabled="true"/> </outputCacheProfiles> </outputCacheSettings> </caching> <!---CacheProfile配置檔案中設定快取end-->
其實作用和效果還是一樣,無非就是方便點,統一的配置引數都直接寫webconfig檔案裡面。其實也可以Controller中寫。
配置好了之後我們直接在控制器呼叫相應的名字的OutputCache特性標籤即可。
[OutputCache(CacheProfile= "TestConfigCache")] public ActionResult Index() { ViewBag.CurrentTime = DateTime.Now; return View(); }
更多的方式,需要下去再研究下。

ABP Redis Cache

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),直接下一步下一步就可以了。
然後開啟安裝的地址就可以看到如下的檔案:
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)地址:https://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操作。

相關推薦

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--快取小結ABP框架專案 Redis Cache實現

快取 為什麼要用快取 為什麼要用快取呢,說快取之前先說使用快取的優點。 減少寄宿伺服器的往返呼叫(round-trips)。 如果快取在客戶端或是代理,將減少對伺服器的請求,減少頻寬。 減少對資料庫伺服器的往返呼叫(round-trips)。 當內容快取在web伺服器,能夠減輕對資料庫的請求。 減少網路

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--後臺工作者HangFireABP框架Abp.Hangfire及擴充套件

HangFire與Quartz.NET相比主要是HangFire的內建提供整合化的控制檯,方便後臺檢視及監控,對於大家來說,比較方便。 HangFire是什麼 Hangfire是一個開源框架(.NET任務排程框架),可以幫助您建立,處理和管理您的後臺作業,處理你不希望放入請求處理管道的操作: 通知/通訊;

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--QuartzABP框架Abp.Quartz及擴充套件

Quartz簡介 Quartz.NET是一個開源的作業排程框架,是 OpenSymphony 的 Quartz API 的.NET移植,它用C#寫成,可用於winform和asp.net應用中。它提供了巨大的靈活性而不犧牲簡單性。你能夠用它來為執行一個作業而建立簡單的或複雜的排程。它有很多特徵,如:資料庫支

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--SignalRABP框架Abp.Web.SignalR及擴充套件

SignalR簡介 SignalR是什麼? ASP.NET SignalR 是為 ASP.NET 開發人員提供的一個庫,可以簡化開發人員將實時 Web 功能新增到應用程式的過程。實時 Web 功能是指這樣一種功能:當所連線的客戶端變得可用時伺服器程式碼可以立即向其推送內容,而不是讓伺服器等待客戶端請求新的資

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--小結,Bootstrap Table之角色管理以及module-zero角色管理

寫在前面的話           很多人說ABP不適合高併發大型,有一定的道理,但是我覺得還是可以的,就看架構師的能力了,我之前公司就是ABP絕對百萬資料級專案,是一個線上教育網站,涉及到平臺,學院,院系,班級,課程,學生等,一個平臺多少大學,一個大學多少院系,一個院系多少班級多少課程,其負責程度一

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統三節--RBAC模式及ABP許可權管理(附贈福利)

角色訪問控制(RBAC) 角色訪問控制(RBAC)應該是目前用得最多也是關注最多的許可權管理模型了。 許可權(Permission)與角色(Role)相關聯,使用者(User)通過成為適當角色的成員而得到這些角色的許可權。這就極大地簡化了許可權的管理。 RBAC引入了角色(Role)概念,目的應該是解耦了P

ABP module-zero +AdminLTE+Bootstrap Table+jQuery權限管理系統--小結,Bootstrap Table之角色管理

增刪 習慣 etc 根據 很好 這不 update 必須 virtual 返回總目錄:ABP+AdminLTE+Bootstrap Table權限管理系統一期 很多人說ABP不適合高並發大型,有一定的道理,但是我覺得還是可以的,就看架構師的能

ABP+AdminLTE+Bootstrap Table許可權管理系統--Bootstrap Table使用者管理列表以及Module Zero之使用者管理

   使用者實體       使用者實體代表應用的一個使用者,它派生自AbpUser類,如下所示: public class User : AbpUser<Tenant, User> { //add your own user properties here

ABP+AdminLTE+Bootstrap Table許可權管理系統--AdminLTE模板選單處理

 AdminLTE選單       上節我們把佈局頁,也有的臨時的選單,但是選單不是應該動態載入的麼?,所以我們這節來寫選單.首先我們看一下AdminLTE原始碼裡面的選單以及結構. <aside class="main-sidebar"> <!--

ABP+AdminLTE+Bootstrap Table許可權管理系統--AdminLTE引入及模板頁和佈局和選單

 AdminLTE    首先去官網下載包下來,然後引入專案.   然後我們在web層新增區域Admin以及Common,關於AdminLTE的地址我們放在Common路勁下面.   在Common下新增LayoutController控制器. Layout 這裡選單我們先不管,在後

ABP+AdminLTE+Bootstrap Table許可權管理系統--倉儲,服務,服務介面及依賴注入

AbpModule      在ABP框架中,倉儲,服務,這塊算是最為重要一塊之一了.ABP框架提供了建立和組裝模組的基礎,一個模組能夠依賴於另一個模組,一個程式集可看成一個模組, 一個模組可以通過一個類來定義這個模組,而給定義這個類要繼承自已經瘋轉好的AbpModule..net通過反射來獲取這些程

ABP+AdminLTE+Bootstrap Table許可權管理系統--登入邏輯及幾種abp封裝的Javascript函式庫

        簡介        經過前幾節,我們已經解決資料庫,模型,DTO,控制器和注入等問題.那麼再來看一下登入邏輯.這裡算是前面幾節的一個初次試水. 首先我們資料庫已經有的相應的資料. 新增Login方法        模型和DTO已經建好,所以我們直接在服務層新增Login方法就可

ABP+AdminLTE+Bootstrap Table許可權管理系統三節--abp分層體系,實體相關及ABP模組系統

ABP模組系統  說了這麼久,還沒有詳細說到abp框架,abp其實基於DDD(領域驅動設計)原則的細看分層如下: 再看我們專案解決方案如下: JCmsErp.Application,應用層:進行展現層與領域層之間的協調,協調業務物件來執行特定的應用程式的任務。它不包含業務邏輯,主要包

ABP+AdminLTE+Bootstrap Table許可權管理系統八節--ABP錯誤機制及AbpSession相關

((ClaimsPrincipal)Thread.CurrentPrincipal).Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);        需要獲取會話資訊則必須實現IAbpSession介面。雖然你

ABP+AdminLTE+Bootstrap Table許可權管理系統--abp控制器擴充套件及json封裝

 一,控制器AbpController    說完了Swagger ui 我們再來說一下abp對控制器的處理和json的封裝.    首先我們定義一個控制器,在新增控制器的時候,控制器會自動繼承自AbpController,AbpController

ABP+AdminLTE+Bootstrap Table許可權管理系統第一--使用ASP.NET Boilerplate模板建立解決方案

ABP+AdminLTE+Bootstrap Table許可權管理系統一期 Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS 前往部落格園總目錄

ABP+AdminLTE+Bootstrap Table許可權管理系統一期

 初衷    學而時習之,不亦說乎,溫顧溫知新,可以為師矣.           看懂遠不如動手去做,動手做才能發現很多自己不懂的問題,不斷的反思和總結,“樂於分享是一種境界的突破”。" 分享是很有意思,也是可以鍛鍊人的。 分享意味著自我的不斷淨化提升,不給自己後退的餘地。為什麼這麼說呢?因為:一,分

ABP+AdminLTE+Bootstrap Table許可權管理系統第二--在ABP的基礎做資料庫指令碼處理

      第一點,上一篇文章中我們講到codefirst中一些問題包括如圖,codefirst在每次執行命令的時候會生成新的類,後來會越來越多。 1,codefirst在執行的資料庫遷移過程中產生了很多檔案,對於強迫症的我而言特別不爽,這些其實是可以不用生成的。 2,在codefirst實際

[ABP開源專案]--vue+vuex+vue-router+EF的許可權管理系統

好久沒寫文字了,當然大家也不期待嘛,反正看程式碼就行了。 演示網站 首先說下這個專案吧。 如標題一樣是基於VUE+.NET開發的框架,也是群友一直吼吼吼要一個vue版本的ABP框架。 我們先來看看首頁吧: 還比較酷炫,提供下演示賬號 演示地址:http://vue.yo

專案集中許可權管理系統 採用cas +shiro+spring mvc+mbatis+bootstrap單點登入

流程架構圖: 這裡許可權系統也可以理解為cas client專案 系統效果圖: 業務場景:多專案統一認證登入,許可權統一管理,許可權系統管理使用者資料,其他業務系統只維護業務資料,使用者資料一律來自許可權系統 該功能目前經過半個多月的努力 在巨大壓力下終於完成了! 目前國內