緩存工廠之Redis緩存

来源:http://www.cnblogs.com/wangrudong003/archive/2016/08/18/5785116.html
-Advertisement-
Play Games

這幾天沒有按照計劃分享技術博文,主要是去醫院了,這裡一想到在醫院經歷的種種,我真的有話要說;醫院里的醫務人員曾經被吹捧為美麗+和藹+可親的天使,在經受5天左右相互接觸後不得不讓感慨;遇見的有些人員在掛號隊伍猶如長龍的時候坐在收費視窗玩手機,理由是自己是換班的差幾分鐘才上班呢;遇見態度極其惡劣的主任醫 ...


這幾天沒有按照計劃分享技術博文,主要是去醫院了,這裡一想到在醫院經歷的種種,我真的有話要說;醫院里的醫務人員曾經被吹捧為美麗+和藹+可親的天使,在經受5天左右相互接觸後不得不讓感慨;遇見的有些人員在掛號隊伍猶如長龍的時候坐在收費視窗玩手機,理由是自己是換班的差幾分鐘才上班呢;遇見態度極其惡劣的主任醫師,做咨詢幾個問題聲音馬上提高並言語中攜帶諷刺話語;還有其他幾個遇見哈哈這裡就不多說了,可能是某些醫務人員覺得多您個不少,我有的是客源,所以個別是這種態度吧,還是市醫院真不知道怎麼混進去的。

 

以上是個人的看法,下麵來正式分享今天的文章吧:

。搭建Redis服務端,並用客戶端連接

。封裝緩存父類,定義Get,Set等常用方法

。定義RedisCache緩存類,執行Redis的Get,Set方法

。構造出緩存工廠調用方法

 

下麵一步一個腳印的來分享:

。搭建Redis服務端,並用客戶端連接

首先,咋們去這個地址下載安裝文件https://github.com/dmajkic/redis/downloads,我這裡的版本是:redis-2.4.5-win32-win64裡面有32位和64位的執行文件,我這裡伺服器是64位的下麵給出截圖和用到部分程式的說明:

現在,咋們直接可以用滑鼠雙擊redis-server.exe這個應用程式,這樣就打開了redis服務窗體(您也可以下載一個windows服務承載器,把redis服務運行在windows的服務中,就不用擔心每次關閉redis服務黑色窗體後無法訪問redis了),運行起來是這樣:

有紅色框的信息就表示成功了,這裡redis服務監聽的埠預設是6379,要修改埠或者更多的配置信息請找到redis.conf配置文件,具體配置信息介紹可以來這裡http://www.shouce.ren/api/view/a/6231

再來,打開客戶端連接服務端,咋們退到64bit文件夾的目錄中,滑鼠移到64bit文件夾上並且安裝Shift鍵,同時點擊滑鼠的右鍵,選中"在此處打開命令視窗"這樣快速進入到了該文件夾的cmd命令視窗中(當然不同的操作系統不同,這裡演示的是windows的操作;還有其他進入的方式這裡不做介紹,因為個人感覺這是最快的);然後,在命令視窗中錄入redis-cli.exe -h localhost -p 6379回車來訪問服務端,效果圖:

再來看下服務端窗體截圖:

沒錯這樣客戶端就連接上服務端了,可以簡單在客戶端執行下set,get命令:

如果是客戶端要訪問遠程的redis服務端,只需要把localhost換成可訪問的ip就行瞭如果還需要密碼等更多配置請去上面的那個地址鏈接;

 

。封裝緩存父類,定義Get,Set等常用方法

先來,上父類的代碼:

 1 public class BaseCache : IDisposable
 2     {
 3         protected string def_ip = string.Empty;
 4         protected int def_port = 0;
 5         protected string def_password = string.Empty;
 6 
 7         public BaseCache()
 8         {
 9 
10         }
11 
12         public virtual void InitCache(string ip = "", int port = 0, string password = "")
13         {
14 
15         }
16 
17         public virtual bool SetCache<T>(string key, T t, int timeOutMinute = 10) where T : class,new()
18         {
19 
20             return false;
21         }
22 
23         public virtual T GetCache<T>(string key) where T : class,new()
24         {
25 
26             return default(T);
27         }
28 
29         public virtual bool Remove(string key)
30         {
31 
32             return false;
33         }
34 
35         public virtual bool FlushAll()
36         {
37 
38             return false;
39         }
40 
41         public virtual bool Any(string key)
42         {
43 
44             return false;
45         }
46 
47         public virtual void Dispose(bool isfalse)
48         {
49 
50             if (isfalse)
51             {
52 
53 
54             }
55         }
56 
57         //手動釋放
58         public void Dispose()
59         {
60 
61             this.Dispose(true);
62             //不自動釋放
63             GC.SuppressFinalize(this);
64         }
65     }
View Code

這裡定義的方法沒有太多的註釋,更多的意思我想看方法名稱就明白了,這個父類主要實現了IDisposable,實現的Dispose()中主要用來釋放資源並且自定義了一個 public virtual void Dispose(bool isfalse)方法,這裡面有一句是GC.SuppressFinalize(this);按照官網介紹的意思是阻塞自動釋放資源,其他的沒有什麼了,繼續看下麵的

 

。定義RedisCache緩存類,執行Redis的Get,Set方法

首先,咋們分別定義類RedisCache,MemcachedCache(這裡暫未實現對memcache緩存的操作),並且繼承BaseCache,重寫Set,Get方法如下代碼:

  1 /// <summary>
  2     /// Redis緩存
  3     /// </summary>
  4     public class RedisCache : BaseCache
  5     {
  6         public RedisClient redis = null;
  7 
  8         public RedisCache()
  9         {
 10 
 11             //這裡去讀取預設配置文件數據
 12             def_ip = "172.0.0.1";
 13             def_port = 6379;
 14             def_password = "";
 15         }
 16 
 17         #region Redis緩存
 18 
 19         public override void InitCache(string ip = "", int port = 0, string password = "")
 20         {
 21 
 22             if (redis == null)
 23             {
 24                 ip = string.IsNullOrEmpty(ip) ? def_ip : ip;
 25                 port = port == 0 ? def_port : port;
 26                 password = string.IsNullOrEmpty(password) ? def_password : password;
 27 
 28                 redis = new RedisClient(ip, port, password);
 29             }
 30         }
 31 
 32         public override bool SetCache<T>(string key, T t, int timeOutMinute = 10)
 33         {
 34 
 35             var isfalse = false;
 36 
 37             try
 38             {
 39                 if (string.IsNullOrEmpty(key)) { return isfalse; }
 40 
 41                 InitCache();
 42                 isfalse = redis.Set<T>(key, t, TimeSpan.FromMinutes(timeOutMinute));
 43             }
 44             catch (Exception ex)
 45             {
 46             }
 47             finally { this.Dispose(); }
 48             return isfalse;
 49         }
 50 
 51         public override T GetCache<T>(string key)
 52         {
 53             var t = default(T);
 54             try
 55             {
 56                 if (string.IsNullOrEmpty(key)) { return t; }
 57 
 58                 InitCache();
 59                 t = redis.Get<T>(key);
 60             }
 61             catch (Exception ex)
 62             {
 63             }
 64             finally { this.Dispose(); }
 65             return t;
 66         }
 67 
 68         public override bool Remove(string key)
 69         {
 70             var isfalse = false;
 71             try
 72             {
 73                 if (string.IsNullOrEmpty(key)) { return isfalse; }
 74 
 75                 InitCache();
 76                 isfalse = redis.Remove(key);
 77             }
 78             catch (Exception ex)
 79             {
 80             }
 81             finally { this.Dispose(); }
 82             return isfalse;
 83         }
 84 
 85         public override void Dispose(bool isfalse)
 86         {
 87 
 88             if (isfalse && redis != null)
 89             {
 90 
 91                 redis.Dispose();
 92                 redis = null;
 93             }
 94         }
 95 
 96         #endregion
 97     }
 98 
 99 
100     /// <summary>
101     /// Memcached緩存
102     /// </summary>
103     public class MemcachedCache : BaseCache
104     {
105 
106 
107     }
View Code

這裡,用到的RedisClient類是來自nuget包引用的,這裡nuget包是:

然後,來看下重寫的InitCache方法,這裡面有一些ip,port(埠),password(密碼)參數,這裡直接寫入在cs文件中沒有從配置文件讀取,大家可以擴展下;這些參數通過RedisClient構造函數傳遞給底層Socket訪問需要的信息,下麵簡單展示下RedisClient幾個的構造函數:

1         public RedisClient();
2         public RedisClient(RedisEndpoint config);
3         public RedisClient(string host);
4         public RedisClient(Uri uri);
5         public RedisClient(string host, int port);
6         public RedisClient(string host, int port, string password = null, long db = 0);

至於Get,Set方法最終都是使用RedisClient對象訪問的,個人覺得需要註意的是Set方法裡面的過期時間參數,目前還沒有試驗這種情況的效果:

?通過這幾種方法設置過期時間後,快到過期時間的時候如果此時有使用這個緩存key那麼過期時間是否會往後自動增加過期時間有效期,這裡暫時沒有試驗(這裡是由於前面項目中的.net core框架中的memecache緩存都有這種設置,想來redis應該也有吧)

這裡,需要重寫下public override void Dispose(bool isfalse)方法,因為調用完RedisClient後需要釋放,我們通過Dispose統一來手動釋放,而不是直接在調用的時候使用using()

 

。構造出緩存工廠調用方法

接下來,咋們需要定義一個緩存工廠,因為上面剛纔定義了一個RedisCache和MemcachedCache明顯這裡會有多個不同緩存的方法調用,所用咋們來定義個工廠模式來調用對應的緩存;這裡的工廠模式沒有使用直接顯示創建new RedisCache(),new MemcachedCache()對象的方法,而是使用了反射的原理,創建對應的緩存對象;

先來,定義個枚舉,枚舉裡面的聲明的名字要和咋們緩存類的名稱相同,代碼如下:

1 public enum CacheType
2     {
3         RedisCache,
4 
5         MemcachedCache
6     }

再來,定義個工廠來CacheRepository(緩存工廠),並且定義方法Current如下代碼:

1 public static BaseCache Current(CacheType cacheType = CacheType.RedisCache)
2         {
3             var nspace = typeof(BaseCache);
4             var fullName = nspace.FullName;
5             var nowspace = fullName.Substring(0, fullName.LastIndexOf('.') + 1);
6 
7             return Assembly.GetExecutingAssembly().CreateInstance(nowspace + cacheType.ToString(), true) as BaseCache;
8         }

*:通過傳遞枚舉參數,來確定反射CreateInstance()方法需要用到的typeName參數,從而來定義需要訪問的那個緩存對象,這裡要註意的是加上了一個命名空間nowspace,因為緩存類可能和工廠類不是同一個命名空間,但是通常會和緩存基類是同命名空間所以在方法最開始的時候截取獲取了緩存類需要的命名空間(這裡看自身項目來定吧);

*:Assembly.GetExecutingAssembly()這個是用來獲取當前應用程式集的路徑,這裡就避免了咋們使用Assembly.Load()方法還需要傳遞程式集的路徑地址了

好了滿上上面要求後,咋們可以在測試頁面調用代碼如:CacheRepository.Current(CacheType.RedisCache).SetCache<MoFlightSearchResponse>(keyData, value);就如此簡單,咋們使用redis-cli.exe客戶端來看下緩存起來的數據:

怎麼樣,您們的是什麼效果呢,下麵給出整體代碼:

  1  public enum CacheType
  2     {
  3         RedisCache,
  4 
  5         MemcachedCache
  6     }
  7 
  8     public class CacheRepository
  9     {
 10 
 11         public static BaseCache Current(CacheType cacheType = CacheType.RedisCache)
 12         {
 13             var nspace = typeof(BaseCache);
 14             var fullName = nspace.FullName;
 15             var nowspace = fullName.Substring(0, fullName.LastIndexOf('.') + 1);
 16         
 17             return Assembly.GetExecutingAssembly().CreateInstance(nowspace + cacheType.ToString(), true) as BaseCache;
 18         }
 19     }
 20 
 21     public class BaseCache : IDisposable
 22     {
 23         protected string def_ip = string.Empty;
 24         protected int def_port = 0;
 25         protected string def_password = string.Empty;
 26 
 27         public BaseCache()
 28         {
 29 
 30         }
 31 
 32         public virtual void InitCache(string ip = "", int port = 0, string password = "")
 33         {
 34 
 35         }
 36 
 37         public virtual bool SetCache<T>(string key, T t, int timeOutMinute = 10) where T : class,new()
 38         {
 39 
 40             return false;
 41         }
 42 
 43         public virtual T GetCache<T>(string key) where T : class,new()
 44         {
 45 
 46             return default(T);
 47         }
 48 
 49         public virtual bool Remove(string key)
 50         {
 51 
 52             return false;
 53         }
 54 
 55         public virtual bool FlushAll()
 56         {
 57 
 58             return false;
 59         }
 60 
 61         public virtual bool Any(string key)
 62         {
 63 
 64             return false;
 65         }
 66 
 67         public virtual void Dispose(bool isfalse)
 68         {
 69 
 70             if (isfalse)
 71             {
 72 
 73 
 74             }
 75         }
 76 
 77         //手動釋放
 78         public void Dispose()
 79         {
 80 
 81             this.Dispose(true);
 82             //不自動釋放
 83             GC.SuppressFinalize(this);
 84         }
 85     }
 86 
 87     /// <summary>
 88     /// Redis緩存
 89     /// </summary>
 90     public class RedisCache : BaseCache
 91     {
 92         public RedisClient redis = null;
 93 
 94         public RedisCache()
 95         {
 96 
 97             //這裡去讀取預設配置文件數據
 98             def_ip = "172.16.2.56";
 99             def_port = 6379;
100             def_password = "";
101         }
102 
103         #region Redis緩存
104 
105         public override void InitCache(string ip = "", int port = 0, string password = "")
106         {
107 
108             if (redis == null)
109             {
110                 ip = string.IsNullOrEmpty(ip) ? def_ip : ip;
111                 port = port == 0 ? def_port : port;
112                 password = string.IsNullOrEmpty(password) ? def_password : password;
113 
114                 redis = new RedisClient(ip, port, password);
115             }
116         }
117 
118         public override bool SetCache<T>(string key, T t, int timeOutMinute = 10)
119         {
120 
121             var isfalse = false;
122 
123             try
124             {
125                 if (string.IsNullOrEmpty(key)) { return isfalse; }
126 
127                 InitCache();
128                 isfalse = redis.Set<T>(key, t, TimeSpan.FromMinutes(timeOutMinute));
129             }
130             catch (Exception ex)
131             {
132             }
133             finally { this.Dispose(); }
134             return isfalse;
135         }
136 
137         public override T GetCache<T>(string key)
138         {
139             var t = default(T);
140             try
141             {
142                 if (string.IsNullOrEmpty(key)) { return t; }
143 
144                 InitCache();
145                 t = redis.Get<T>(key);
146             }
147             catch (Exception ex)
148             {
149             }
150             finally { this.Dispose(); }
151             return t;
152         }
153 
154         public override bool Remove(string key)
155         {
156             var isfalse = false;
157             try
158             {
159                 if (string.IsNullOrEmpty(key)) { return isfalse; }
160 
161                 InitCache();
162                 isfalse = redis.Remove(key);
163             }
164             catch (Exception ex)
165             {
166             }
167             finally { this.Dispose(); }
168             return isfalse;
169         }
170 
171         public override void Dispose(bool isfalse)
172         {
173 
174             if (isfalse && redis != null)
175             {
176 
177                 redis.Dispose();
178                 redis = null;
179             }
180         }
181 
182         #endregion
183     }
184 
185 
186     /// <summary>
187     /// Memcached緩存
188     /// </summary>
189     public class MemcachedCache : BaseCache
190     {
191 
192 
193     }
View Code

這次分享的Redis緩存從搭建到使用希望給您們有幫助,還請多多支持點贊,謝謝。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在看u-boot、osekOS的啟動代碼,其中涉及到lds文件,通過參考其他網友的文章,希望對lds文件有個明晰的認識,為了鞏固及加深影響,特將相關博客內容重寫一遍。 原始文章: http://linux.chinaunix.net/techdoc/beginner/2009/08/12/112 ...
  • 編程環境搭建: 因為ubuntu 12.04的內核版本已經是3.x,而目前一些講解內核驅動的書都是2.6.x。 嵌入式開發的版本一般都是基於3.14移植的,因為嵌入式是跑在開發板上的,所以開發驅動沒有問題。但是教材的例子一般都是基於PC機的2.6.x版本,雖然內核內部介面相對穩定,但是我也不太清楚。... ...
  • 源代碼如下: typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; // WORD TypeOffset[1]; } IMAGE_BASE_RELOCATION; typedef IMAGE_... ...
  • 查看文件內容 1.cat 命令 作用:查看文件內容 語法:cat 文件名 2. more 命令 作用:分頁查看文件內容 語法:more 文件名 例:more /etc/passwd 按下回車刷新一行,按下空格刷新一屏 退出:按q健 3.less 命令 作用:分頁查看文件內容 語法:less 文件名 ...
  • 1、LINQ是什麼? LINQ是Language Integrated Query的縮寫,即“語言集成查詢”的意思。LINQ的提出就是為了提供一種跨越各種數據源的統一的查詢方式,它主要包含4個組件--Linq to Objects、Linq to XML、Linq to DataSet和Linq t ...
  • 說明: 原文作者賢新 原文地址:http://www.cnblogs.com/chenxinblogs/p/4852813.html ViewData和ViewBag主要用於將數據從控制器中傳遞到視圖中去,ViewData本身就是一個字典。以KeyValue的形式存取值。ViewData的Value ...
  • 本文版權,歸博客園和作者吳雙共同所有。轉載和爬蟲請註明博客園蝸牛Redis系列文章地址 http://www.cnblogs.com/tdws/tag/NoSql/ Redis數據類型之集合(Set)。 單個集合中最多允許存儲2的三十二次方減1個元素。內部使用hash table散列表實現。 SAD ...
  • 在 ASP.NET Core 中,有多種途徑可以對應用程式狀態進行管理,取決於檢索狀態的時機和方式。本文簡要介紹幾種可選的方式,並著重介紹為 ASP.NET Core 應用程式安裝並配置會話狀態支持。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...