Redis 安装 & 配置
本测试环境将在 CentOS 7 x64 上安装最新版本的 Redis。
1. 运行以下命令安装 Redis
如果 CentOS 上提示 wget 命令未找到,则先安装 net-tools。
2. Redis 配置文件
1)开启守护程序
修改 daemonize 节点为 yes。
2)运行外部 IP 访问
配置 bind 节点为 0.0.0.0
本次示例只使用 Redis 的缓存 所以配置暂时只修改这两处即可。
3. 设置 Redis 开机自动启动
1)在 Redis 的源码包中找到 utils 目录
2) 将 redis_init_script 文件复制到 /etc/init.d 目录下并重命名为 redisd
3) 打开 redisd 修改部分配置。
- 1 #!/bin/sh
- 2 # chkconfig: 2345 90 10
- 3 # Simple Redis init.d script conceived to work on Linux systems
- 4 # as it does use of the /proc filesystem.
- 5
- 6 REDISPORT=6379
- 7 EXEC=/usr/local/bin/redis-server
- 8 CLIEXEC=/usr/local/bin/redis-cli
- 9
- 10 PIDFILE=/var/run/redis_${REDISPORT}.pid
- 11 CONF="/etc/redis/redis_${REDISPORT}.conf"
其中第二行 # chkconfig: 2345 90 10 需要另行添加。
- REDISPORT Redis 运行端口号;
- EXEC Redis 服务器命令文件路径(根据实际情况修改);
- CLIEXEC Redis 客户端命令文件路径(亦根据实际情况修改);
- CONF Redis 配置文件。
4)设置开机启动 & 启动、停止服务
主:如果外部机器还访问不到 Redis 服务器,请将 6379 端口号加防火墙例外即可。
代码实现:
Common 包 接口定义 & 分布式缓存实例获取和配置
- - IDistributedCache 接口
- 1 using System;
- 2
- 3 namespace Wlitsoft.Framework.Common.Core
- 4 {
- 5 /// <summary>
- 6 /// 分布式缓存接口。
- 7 /// </summary>
- 8 public interface IDistributedCache
- 9 {
- 10 /// <summary>
- 11 /// 获取缓存。
- 12 /// </summary>
- 13 /// <typeparam name="T">缓存类型。</typeparam>
- 14 /// <param name="key">缓存键值。</param>
- 15 /// <returns>获取到的缓存。</returns>
- 16 T Get(string key);
- 17
- 18 /// <summary>
- 19 /// 设置缓存。
- 20 /// </summary>
- 21 /// <typeparam name="T">缓存类型。</typeparam>
- 22 /// <param name="key">缓存键值。</param>
- 23 /// <param name="value">要缓存的对象。</param>
- 24 void Set(string key, T value);
- 25
- 26 /// <summary>
- 27 /// 设置缓存。
- 28 /// </summary>
- 29 /// <typeparam name="T">缓存类型。</typeparam>
- 30 /// <param name="key">缓存键值。</param>
- 31 /// <param name="value">要缓存的对象。</param>
- 32 /// <param name="expiredTime">过期时间。</param>
- 33 void Set(string key, T value, TimeSpan expiredTime);
- 34
- 35 /// <summary>
- 36 /// 判断指定键值的缓存是否存在。
- 37 /// </summary>
- 38 /// <param name="key">缓存键值。</param>
- 39 /// <returns>一个布尔值,表示缓存是否存在。</returns>
- 40 bool Exists(string key);
- 41
- 42 /// <summary>
- 43 /// 移除指定键值的缓存。
- 44 /// </summary>
- 45 /// <param name="key">缓存键值。</param>
- 46 bool Remove(string key);
- 47
- 48 /// <summary>
- 49 /// 获取 Hash 表中的缓存。
- 50 /// </summary>
- 51 /// <typeparam name="T">缓存类型。</typeparam>
- 52 /// <param name="key">缓存键值。</param>
- 53 /// <param name="hashField">要获取的 hash 字段。</param>
- 54 /// <returns>获取到的缓存。</returns>
- 55 T GetHash(string key, string hashField);
- 56
- 57 /// <summary>
- 58 /// 设置 缓存到 Hash 表。
- 59 /// </summary>
- 60 /// <typeparam name="T">缓存类型。</typeparam>
- 61 /// <param name="key">缓存键值。</param>
- 62 /// <param name="hashField">要设置的 hash 字段。</param>
- 63 /// <param name="hashValue">要设置的 hash 值。</param>
- 64 void SetHash(string key, string hashField, T hashValue);
- 65
- 66 /// <summary>
- 67 /// 判断指定键值的 Hash 缓存是否存在。
- 68 /// </summary>
- 69 /// <param name="key">缓存键值。</param>
- 70 /// <param name="hashField">hash 字段。</param>
- 71 /// <returns>一个布尔值,表示缓存是否存在。</returns>
- 72 bool ExistsHash(string key, string hashField);
- 73
- 74 /// <summary>
- 75 /// 删除 hash 表中的指定字段的缓存。
- 76 /// </summary>
- 77 /// <param name="key">缓存键值。</param>
- 78 /// <param name="hashField">hash 字段。</param>
- 79 /// <returns>一个布尔值,表示缓存是否删除成功。</returns>
- 80 bool DeleteHash(string key, string hashField);
- 81 }
- 82 }
- App 类
- 1 /// <summary>
- 2 /// 获取分布式缓存。
- 3 /// </summary>
- 4 public static IDistributedCache DistributedCache {
- get;
- internal set;
- }
- AppBuilder 类
- 1 namespace Wlitsoft.Framework.Common
- 2 {
- 3 /// <summary>
- 4 /// 应用 构造。
- 5 /// </summary>
- 6 public class AppBuilder
- 7 {
- 8 #region 添加序列化者
- 9
- 10 /// <summary>
- 11 /// 添加序列化者。
- 12 /// </summary>
- 13 /// <param name="type">序列化类型。</param>
- 14 /// <param name="serializer">序列化者接口。</param>
- 15 public void AddSerializer(SerializeType type, ISerializer serializer)
- 16 {
- 17 #region 参数校验
- 18
- 19 if (serializer == null)
- 20 throw new ObjectNullException(nameof(serializer));
- 21
- 22 #endregion
- 23
- 24 App.SerializerService.SetSerializer(type, serializer);
- 25 }
- 26
- 27 #endregion
- 28
- 29 #region 添加日志记录者
- 30
- 31 /// <summary>
- 32 /// 添加日志记录者。
- 33 /// </summary>
- 34 /// <param name="name">日志记录者名称。</param>
- 35 /// <param name="logger">日志接口。</param>
- 36 public void AddLogger(string name, ILog logger)
- 37 {
- 38 #region 参数校验
- 39
- 40 if (string.IsNullOrEmpty(name))
- 41 throw new StringNullOrEmptyException(nameof(name));
- 42
- 43 if (logger == null)
- 44 throw new ObjectNullException(nameof(logger));
- 45
- 46 #endregion
- 47
- 48 App.LoggerService.SetLogger(name, logger);
- 49 }
- 50
- 51 #endregion
- 52
- 53 #region 设置分布式缓存
- 54
- 55 /// <summary>
- 56 /// 设置分布式缓存。
- 57 /// </summary>
- 58 /// <param name="cache">分布式缓存实例。</param>
- 59 /// <returns></returns>
- 60 public AppBuilder SetDistributedCache(IDistributedCache cache)
- 61 {
- 62 #region 参数校验
- 63
- 64 if (cache == null)
- 65 throw new ObjectNullException(nameof(cache));
- 66
- 67 #endregion
- 68
- 69 App.DistributedCache = cache;
- 70 return this;
- 71 }
- 72
- 73 #endregion
- 74 }
- 75 }
分布式缓存 Redis 实现
- RedisCache 类
- 1 using System;
- 2 using System.Linq;
- 3 using System.Threading;
- 4 using StackExchange.Redis;
- 5 using Wlitsoft.Framework.Common.Core;
- 6 using Wlitsoft.Framework.Common.Extension;
- 7 using Wlitsoft.Framework.Common.Exception;
- 8
- 9 namespace Wlitsoft.Framework.Caching.Redis
- 10 {
- 11 /// <summary>
- 12 /// Redis 缓存。
- 13 /// </summary>
- 14 public class RedisCache : IDistributedCache
- 15 {
- 16 #region 私有属性
- 17
- 18 //redis 连接实例。
- 19 private volatile ConnectionMultiplexer _connection;
- 20
- 21 //redis 缓存数据库实例。
- 22 private IDatabase _database;
- 23
- 24 //连接实例锁。
- 25 private readonly SemaphoreSlim _connectionLock = new SemaphoreSlim(1, 1);
- 26
- 27 //Redis 配置。
- 28 internal static RedisCacheConfiguration RedisCacheConfiguration;
- 29
- 30 #endregion
- 31
- 32 #region IDistributedCache 成员
- 33
- 34 /// <summary>
- 35 /// 获取缓存。
- 36 /// </summary>
- 37 /// <typeparam name="T">缓存类型。</typeparam>
- 38 /// <param name="key">缓存键值。</param>
- 39 /// <returns>获取到的缓存。</returns>
- 40 public T Get(string key)
- 41 {
- 42 #region 参数校验
- 43
- 44 if (string.IsNullOrEmpty(key))
- 45 throw new StringNullOrEmptyException(nameof(key));
- 46
- 47 #endregion
- 48
- 49 this.Connect();
- 50 string result = this._database.StringGet(key);
- 51 if (string.IsNullOrEmpty(result))
- 52 return default(T);
- 53 return result.ToJsonObject();
- 54 }
- 55
- 56 /// <summary>
- 57 /// 设置缓存。
- 58 /// </summary>
- 59 /// <typeparam name="T">缓存类型。</typeparam>
- 60 /// <param name="key">缓存键值。</param>
- 61 /// <param name="value">要缓存的对象。</param>
- 62 public void Set(string key, T value)
- 63 {
- 64 #region 参数校验
- 65
- 66 if (string.IsNullOrEmpty(key))
- 67 throw new StringNullOrEmptyException(nameof(key));
- 68
- 69 if (value == null)
- 70 throw new ObjectNullException(nameof(value));
- 71
- 72 #endregion
- 73
- 74 this.Connect();
- 75 this._database.StringSet(key, value.ToJsonString());
- 76 }
- 77
- 78 /// <summary>
- 79 /// 设置缓存。
- 80 /// </summary>
- 81 /// <typeparam name="T">缓存类型。</typeparam>
- 82 /// <param name="key">缓存键值。</param>
- 83 /// <param name="value">要缓存的对象。</param>
- 84 /// <param name="expiredTime">过期时间。</param>
- 85 public void Set(string key, T value, TimeSpan expiredTime)
- 86 {
- 87 #region 参数校验
- 88
- 89 if (string.IsNullOrEmpty(key))
- 90 throw new StringNullOrEmptyException(nameof(key));
- 91
- 92 if (value == null)
- 93 throw new ObjectNullException(nameof(value));
- 94
- 95 #endregion
- 96
- 97 this.Connect();
- 98 this._database.StringSet(key, value.ToJsonString(), expiredTime);
- 99 }
- 100
- 101 /// <summary>
- 102 /// 判断指定键值的缓存是否存在。
- 103 /// </summary>
- 104 /// <param name="key">缓存键值。</param>
- 105 /// <returns>一个布尔值,表示缓存是否存在。</returns>
- 106 public bool Exists(string key)
- 107 {
- 108 #region 参数校验
- 109
- 110 if (string.IsNullOrEmpty(key))
- 111 throw new StringNullOrEmptyException(nameof(key));
- 112
- 113 #endregion
- 114
- 115 this.Connect();
- 116 return this._database.KeyExists(key);
- 117 }
- 118
- 119 /// <summary>
- 120 /// 移除指定键值的缓存。
- 121 /// </summary>
- 122 /// <param name="key">缓存键值。</param>
- 123 public bool Remove(string key)
- 124 {
- 125 #region 参数校验
- 126
- 127 if (string.IsNullOrEmpty(key))
- 128 throw new StringNullOrEmptyException(nameof(key));
- 129
- 130 #endregion
- 131
- 132 this.Connect();
- 133 return this._database.KeyDelete(key);
- 134 }
- 135
- 136 /// <summary>
- 137 /// 获取 Hash 表中的缓存。
- 138 /// </summary>
- 139 /// <typeparam name="T">缓存类型。</typeparam>
- 140 /// <param name="key">缓存键值。</param>
- 141 /// <param name="hashField">要获取的 hash 字段。</param>
- 142 /// <returns>获取到的缓存。</returns>
- 143 public T GetHash(string key, string hashField)
- 144 {
- 145 #region 参数校验
- 146
- 147 if (string.IsNullOrEmpty(key))
- 148 throw new StringNullOrEmptyException(nameof(key));
- 149
- 150 if (string.IsNullOrEmpty(hashField))
- 151 throw new StringNullOrEmptyException(nameof(hashField));
- 152
- 153 #endregion
- 154
- 155 this.Connect();
- 156 string value = this._database.HashGet(key, hashField);
- 157 if (string.IsNullOrEmpty(value))
- 158 return default(T);
- 159 return value.ToJsonObject();
- 160 }
- 161
- 162 /// <summary>
- 163 /// 设置 缓存到 Hash 表。
- 164 /// </summary>
- 165 /// <typeparam name="T">缓存类型。</typeparam>
- 166 /// <param name="key">缓存键值。</param>
- 167 /// <param name="hashField">要设置的 hash 字段。</param>
- 168 /// <param name="hashValue">要设置的 hash 值。</param>
- 169 public void SetHash(string key, string hashField, T hashValue)
- 170 {
- 171 #region 参数校验
- 172
- 173 if (string.IsNullOrEmpty(key))
- 174 throw new StringNullOrEmptyException(nameof(key));
- 175
- 176 if (string.IsNullOrEmpty(hashField))
- 177 throw new StringNullOrEmptyException(nameof(hashField));
- 178
- 179 if (hashValue == null)
- 180 throw new ObjectNullException(nameof(hashValue));
- 181
- 182 #endregion
- 183
- 184 this.Connect();
- 185 this._database.HashSet(key, hashField, hashValue.ToJsonString());
- 186 }
- 187
- 188 /// <summary>
- 189 /// 判断指定键值的 Hash 缓存是否存在。
- 190 /// </summary>
- 191 /// <param name="key">缓存键值。</param>
- 192 /// <param name="hashField">hash 字段。</param>
- 193 /// <returns>一个布尔值,表示缓存是否存在。</returns>
- 194 public bool ExistsHash(string key, string hashField)
- 195 {
- 196 #region 参数校验
- 197
- 198 if (string.IsNullOrEmpty(key))
- 199 throw new StringNullOrEmptyException(nameof(key));
- 200
- 201 if (string.IsNullOrEmpty(hashField))
- 202 throw new StringNullOrEmptyException(nameof(hashField));
- 203
- 204 #endregion
- 205
- 206 this.Connect();
- 207 return this._database.HashExists(key, hashField);
- 208 }
- 209
- 210 /// <summary>
- 211 /// 删除 hash 表中的指定字段的缓存。
- 212 /// </summary>
- 213 /// <param name="key">缓存键值。</param>
- 214 /// <param name="hashField">hash 字段。</param>
- 215 /// <returns>一个布尔值,表示缓存是否删除成功。</returns>
- 216 public bool DeleteHash(string key, string hashField)
- 217 {
- 218 #region 参数校验
- 219
- 220 if (string.IsNullOrEmpty(key))
- 221 throw new StringNullOrEmptyException(nameof(key));
- 222
- 223 if (string.IsNullOrEmpty(hashField))
- 224 throw new StringNullOrEmptyException(nameof(hashField));
- 225
- 226 #endregion
- 227
- 228 this.Connect();
- 229 return this._database.HashDelete(key, hashField);
- 230 }
- 231
- 232 #endregion
- 233
- 234 #region 私有方法
- 235
- 236 /// <summary>
- 237 /// 连接。
- 238 /// </summary>
- 239 private void Connect()
- 240 {
- 241 if (this._connection != null)
- 242 return;
- 243
- 244 this._connectionLock.Wait();
- 245 try
- 246 {
- 247 if (this._connection == null)
- 248 {
- 249 this._connection = ConnectionMultiplexer.Connect(this.GetConfigurationOptions());
- 250 this._database = this._connection.GetDatabase();
- 251 }
- 252 }
- 253 finally
- 254 {
- 255 this._connectionLock.Release();
- 256 }
- 257 }
- 258
- 259 private ConfigurationOptions GetConfigurationOptions()
- 260 {
- 261 #region 校验
- 262
- 263 if (RedisCacheConfiguration == null)
- 264 throw new ObjectNullException(nameof(RedisCacheConfiguration));
- 265
- 266 if (!RedisCacheConfiguration.HostAndPoints.Any())
- 267 throw new Exception("RedisCahce 的 HostAndPoints 不能为空");
- 268
- 269 #endregion
- 270
- 271 ConfigurationOptions options = new ConfigurationOptions();
- 272
- 273 foreach (string item in RedisCacheConfiguration.HostAndPoints)
- 274 options.EndPoints.Add(item);
- 275
- 276 options.ConnectRetry = RedisCacheConfiguration.ConnectRetry;
- 277 options.ConnectTimeout = RedisCacheConfiguration.ConnectTimeout;
- 278
- 279 return options;
- 280 }
- 281
- 282 #endregion
- 283
- 284 #region 析构函数
- 285
- 286 /// <summary>
- 287 /// 析构 <see cref="RedisCache"/> 类型的对象。
- 288 /// </summary>
- 289 ~RedisCache()
- 290 {
- 291 _connection?.Close();
- 292 }
- 293
- 294 #endregion
- 295 }
- 296 }
来源: