缓存工厂之Redis缓存

这几天没有按照计划分享技术博文,主要是去医院了,这里一想到在医院经历的种种,我真的有话要说;医院里的医务人员曾经被吹捧为美丽+和蔼+可亲的天使,在经受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     }

这里定义的方法没有太多的注释,更多的意思我想看方法名称就明白了,这个父类主要实现了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     }

这里,用到的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     }

这次分享的Redis缓存从搭建到使用希望给您们有帮助,还请多多支持点赞,谢谢。

时间: 2024-10-14 13:06:33

缓存工厂之Redis缓存的相关文章

Laravel之路——file缓存修改为redis缓存

1.Session: 修改.evn文件: SESSION_DRIVER:redis (如果还不行的话,修改config/session.php的driver) 2.缓存修改为redis 注意:使用 Laravel 的 Redis 缓存之前,你需要通过 Composer 安装 predis/predis 包(~1.0). 1.修改.evn文件中redis的配置信息

缓存机制总结(JVM内置缓存机制,MyBatis和Hibernate缓存机制,Redis缓存)

一.JVM内置缓存(值存放在JVM缓存中) 我们可以先了解一下Cookie,Session,和Cache Cookie:当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择都纪录下来.当下次你再光临同一个网站,WEB 服务器会先看看有没有它上次留下的 Cookie 资料,有的话,就会依据 Cookie里的内容来判断使用者,送出特定的网页内容给你.具体来说Cookie机制采用的是在客户端保持状态的方案(保存客户浏览器请求服务器页面

Redis 缓存失效机制

Redis缓存失效的故事要从EXPIRE这个命令说起,EXPIRE允许用户为某个key指定超时时间,当超过这个时间之后key对应的值会被清除,这篇文章主要在分析Redis源码的基础上站在Redis设计者的角度去思考Redis缓存失效的相关问题. Redis缓存失效机制 Redis缓存失效机制是为应对缓存应用的一种很常见的场景而设计的,讲个场景: 我们为了减轻后端数据库的压力,很开心的借助Redis服务把变化频率不是很高的数据从DB load出来放入了缓存,因此之后的一段时间内我们都可以直接从缓存

SpringBoot集成Redis分布式锁以及Redis缓存

https://blog.csdn.net/qq_26525215/article/details/79182687 集成Redis 首先在pom.xml中加入需要的redis依赖和缓存依赖 <!-- 引入redis依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifa

TP5中用redis缓存

在config.php配置文件下找到缓存设置,将原来的文件缓存修改为redis缓存,也可以改为多种类型的缓存: // +---------------------------------------------------------------------- // | 缓存设置 // +---------------------------------------------------------------------- /* 'cache' => [ // 驱动方式 'type' =>

Redis 缓存 + Spring 的集成示例(转载)

1. 依赖包安装 pom.xml 加入: <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.0.RELEASE</version> </dependency> <dependency> <groupId>redis

nginx+redis缓存微信的token数据

上一篇文章我们讲了如何在负载均衡的项目中使用redis来缓存session数据,戳这里. 我们在项目的进展过程中,不仅需要缓存session数据,有时候还需要缓存一些别的数据,比如说,微信的access_token. access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token.开发者需要进行妥善保存.access_token的存储至少要保留512个字符空间.access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的acce

Redis 缓存 + Spring 的集成示例(转)

<整合 spring 4(包括mvc.context.orm) + mybatis 3 示例>一文简要介绍了最新版本的 Spring MVC.IOC.MyBatis ORM 三者的整合以及声明式事务处理.现在我们需要把缓存也整合进来,缓存我们选用的是 Redis,本文将在该文示例基础上介绍 Redis 缓存 + Spring 的集成.关于 Redis 服务器的搭建请参考博客<Redhat5.8 环境下编译安装 Redis 并将其注册为系统服务>. 1. 依赖包安装 pom.xml

Redis 缓存 + Spring 的集成示例

1. 依赖包安装 pom.xml 加入: [html] view plain copy print? <!-- redis cache related.....start --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.0.RELEASE&