RedisHelper Redis帮助类
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks; namespace WindowsFormsApplication1
{
public static class RedisHelper
{
private static string Constr = ""; private static object _locker = new Object();
private static ConnectionMultiplexer _instance = null; /// <summary>
/// 使用一个静态属性来返回已连接的实例,如下列中所示。这样,一旦 ConnectionMultiplexer 断开连接,便可以初始化新的连接实例。
/// </summary>
public static ConnectionMultiplexer Instance
{
get
{
if (Constr.Length == )
{
throw new Exception("连接字符串未设置!");
}
if (_instance == null)
{
lock (_locker)
{
if (_instance == null || !_instance.IsConnected)
{
_instance = ConnectionMultiplexer.Connect(Constr);
}
}
}
//注册如下事件
_instance.ConnectionFailed += MuxerConnectionFailed;
_instance.ConnectionRestored += MuxerConnectionRestored;
_instance.ErrorMessage += MuxerErrorMessage;
_instance.ConfigurationChanged += MuxerConfigurationChanged;
_instance.HashSlotMoved += MuxerHashSlotMoved;
_instance.InternalError += MuxerInternalError;
return _instance;
}
} static RedisHelper()
{
} public static void SetCon(string config)
{
Constr = config;
} /// <summary>
///
/// </summary>
/// <returns></returns>
public static IDatabase GetDatabase()
{
return Instance.GetDatabase();
} /// <summary>
/// 这里的 MergeKey 用来拼接 Key 的前缀,具体不同的业务模块使用不同的前缀。
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private static string MergeKey(string key)
{
return key;
//return BaseSystemInfo.SystemCode + key;
} /// <summary>
/// 根据key获取缓存对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public static T Get<T>(string key)
{
key = MergeKey(key);
return Deserialize<T>(GetDatabase().StringGet(key));
} /// <summary>
/// 根据key获取缓存对象
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static object Get(string key)
{
key = MergeKey(key);
return Deserialize<object>(GetDatabase().StringGet(key));
} /// <summary>
/// 设置缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expireMinutes"></param>
public static void Set(string key, object value, int expireMinutes = )
{
key = MergeKey(key);
if (expireMinutes > )
{
GetDatabase().StringSet(key, Serialize(value), TimeSpan.FromMinutes(expireMinutes));
}
else
{
GetDatabase().StringSet(key, Serialize(value));
} } /// <summary>
/// 判断在缓存中是否存在该key的缓存数据
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static bool Exists(string key)
{
key = MergeKey(key);
return GetDatabase().KeyExists(key); //可直接调用
} /// <summary>
/// 移除指定key的缓存
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static bool Remove(string key)
{
key = MergeKey(key);
return GetDatabase().KeyDelete(key);
} /// <summary>
/// 异步设置
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public static async Task SetAsync(string key, object value)
{
key = MergeKey(key);
await GetDatabase().StringSetAsync(key, Serialize(value));
} /// <summary>
/// 根据key获取缓存对象
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static async Task<object> GetAsync(string key)
{
key = MergeKey(key);
object value = await GetDatabase().StringGetAsync(key);
return value;
} /// <summary>
/// 实现递增
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static long Increment(string key)
{
key = MergeKey(key);
//三种命令模式
//Sync,同步模式会直接阻塞调用者,但是显然不会阻塞其他线程。
//Async,异步模式直接走的是Task模型。
//Fire - and - Forget,就是发送命令,然后完全不关心最终什么时候完成命令操作。
//即发即弃:通过配置 CommandFlags 来实现即发即弃功能,在该实例中该方法会立即返回,如果是string则返回null 如果是int则返回0.这个操作将会继续在后台运行,一个典型的用法页面计数器的实现:
return GetDatabase().StringIncrement(key, flags: CommandFlags.FireAndForget);
} /// <summary>
/// 实现递减
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public static long Decrement(string key, string value)
{
key = MergeKey(key);
return GetDatabase().HashDecrement(key, value, flags: CommandFlags.FireAndForget);
} /// <summary>
/// 序列化对象
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
private static byte[] Serialize(object o)
{
if (o == null)
{
return null;
}
BinaryFormatter binaryFormatter = new BinaryFormatter();
using (MemoryStream memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, o);
byte[] objectDataAsStream = memoryStream.ToArray();
return objectDataAsStream;
}
} /// <summary>
/// 反序列化对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream"></param>
/// <returns></returns>
private static T Deserialize<T>(byte[] stream)
{
if (stream == null)
{
return default(T);
}
BinaryFormatter binaryFormatter = new BinaryFormatter();
using (MemoryStream memoryStream = new MemoryStream(stream))
{
T result = (T)binaryFormatter.Deserialize(memoryStream);
return result;
}
} /// <summary>
/// 配置更改时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
{
//LogHelper.SafeLogMessage("Configuration changed: " + e.EndPoint);
} /// <summary>
/// 发生错误时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
{
//LogHelper.SafeLogMessage("ErrorMessage: " + e.Message);
} /// <summary>
/// 重新建立连接之前的错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
//LogHelper.SafeLogMessage("ConnectionRestored: " + e.EndPoint);
} /// <summary>
/// 连接失败 , 如果重新连接成功你将不会收到这个通知
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
//LogHelper.SafeLogMessage("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType +(e.Exception == null ? "" : (", " + e.Exception.Message)));
} /// <summary>
/// 更改集群
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
{
//LogHelper.SafeLogMessage("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
} /// <summary>
/// redis类库错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
{
//LogHelper.SafeLogMessage("InternalError:Message" + e.Exception.Message);
} //场景不一样,选择的模式便会不一样,大家可以按照自己系统架构情况合理选择长连接还是Lazy。
//建立连接后,通过调用ConnectionMultiplexer.GetDatabase 方法返回对 Redis Cache 数据库的引用。从 GetDatabase 方法返回的对象是一个轻量级直通对象,不需要进行存储。 /// <summary>
/// 使用的是Lazy,在真正需要连接时创建连接。
/// 延迟加载技术
/// 微软azure中的配置 连接模板
/// </summary>
//private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
//{
// //var options = ConfigurationOptions.Parse(constr);
// ////options.ClientName = GetAppName(); // only known at runtime
// //options.AllowAdmin = true;
// //return ConnectionMultiplexer.Connect(options);
// ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect(Coonstr);
// muxer.ConnectionFailed += MuxerConnectionFailed;
// muxer.ConnectionRestored += MuxerConnectionRestored;
// muxer.ErrorMessage += MuxerErrorMessage;
// muxer.ConfigurationChanged += MuxerConfigurationChanged;
// muxer.HashSlotMoved += MuxerHashSlotMoved;
// muxer.InternalError += MuxerInternalError;
// return muxer;
//}); #region 当作消息代理中间件使用 一般使用更专业的消息队列来处理这种业务场景 /// <summary>
/// 当作消息代理中间件使用
/// 消息组建中,重要的概念便是生产者,消费者,消息中间件。
/// </summary>
/// <param name="channel"></param>
/// <param name="message"></param>
/// <returns></returns>
public static long Publish(string channel, string message)
{
ISubscriber sub = Instance.GetSubscriber();
//return sub.Publish("messages", "hello");
return sub.Publish(channel, message);
} /// <summary>
/// 在消费者端得到该消息并输出
/// </summary>
/// <param name="channelFrom"></param>
/// <returns></returns>
public static void Subscribe(string channelFrom)
{
ISubscriber sub = Instance.GetSubscriber();
sub.Subscribe(channelFrom, (channel, message) =>
{
Console.WriteLine((string)message);
});
} #endregion /// <summary>
/// GetServer方法会接收一个EndPoint类或者一个唯一标识一台服务器的键值对
/// 有时候需要为单个服务器指定特定的命令
/// 使用IServer可以使用所有的shell命令,比如:
/// DateTime lastSave = server.LastSave();
/// ClientInfo[] clients = server.ClientList();
/// 如果报错在连接字符串后加 ,allowAdmin=true;
/// </summary>
/// <returns></returns>
public static IServer GetServer(string host, int port)
{
IServer server = Instance.GetServer(host, port);
return server;
} /// <summary>
/// 获取全部终结点
/// </summary>
/// <returns></returns>
public static EndPoint[] GetEndPoints()
{
EndPoint[] endpoints = Instance.GetEndPoints();
return endpoints;
}
}
RedisHelper Redis帮助类的更多相关文章
- Java的redis 操作类-优化通用版本
java操作redis多节点处理方式;http://blog.itpub.net/29254281/viewspace-1188644/首先maven引入依赖包 <dependency> ...
- .net core下Redis帮助类
0.引入.net core环境下Redis的NuGet包,StackExchange.Redis,现目前最新的2.0.519. 帮助类Code: using System; using Syste ...
- c#--Redis帮助类
最近一直在忙公司的一下项目,也没有太多时间写,所以就分享出所用redis帮助类 using Newtonsoft.Json; using StackExchange.Redis; using Syst ...
- StackExchange.Redis帮助类解决方案RedisRepository封装(基础配置)
本文版权归博客园和作者吴双本人共同所有,转载和爬虫,请注明原文地址.http://www.cnblogs.com/tdws/p/5815735.html 写在前面 这不是教程,分享而已,也欢迎园友们多 ...
- php的redis 操作类,适用于单台或多台、多组redis服务器操作
redis 操作类,包括单台或多台.多组redis服务器操作,适用于业务复杂.高性能要求的 php web 应用. redis.php: <?php /* redis 操作类,适用于单台或多台. ...
- Redis操作Hash工具类封装,Redis工具类封装
Redis操作Hash工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>> ...
- Redis操作字符串工具类封装,Redis工具类封装
Redis操作字符串工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>>& ...
- 自己封装的C#操作redis公共类
关于C#操作redis公共类,网上有很多版本,每个版本我都看了,发觉还是不够完美,都存在一个问题,只能操作单一的缓存数据库 redis指令支持上,这里可以自己去扩展,下面分享下我近期封装的一个redi ...
- 设计模式之PHP项目应用——单例模式设计Memcache和Redis操作类
1 单例模式简单介绍 单例模式是一种经常使用的软件设计模式. 在它的核心结构中仅仅包括一个被称为单例类的特殊类. 通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问.从而方便对实例个 ...
随机推荐
- 【Spring Boot】Spring Boot之自定义拦截器
一.拦截器的作用 将通用的代码抽取出来,达到复用的效果.比如可以用来做日志记录.登录判断.权限校验等等 二.如何实现自定义拦截器 1)创建自定义拦截器类并实现HandlerInterceptor类 / ...
- logstash multiple piplines 配置方式
当logstash有很多个input类型需要处理时.为了更方便的管理,我们需要使用一个.conf(input->filter->output)配置文件来对应一个pipeline. pipl ...
- CVE-2019-5475:Nexus2 yum插件RCE漏洞复现
0x00 前言 如果有想一起做漏洞复现的小伙伴,欢迎加入我们,公众号内点击联系作者即可 提示:由于某些原因,公众号内部分工具即将移除,如果有需要的请尽快保存 0x01 漏洞概述 最近hackerone ...
- python为什么要使用闭包
为什么要使用闭包 闭包避免了使用全局变量,此外,闭包允许将函数与其所操作的某些数据(环境)关连起来.这一点与面向对象编程是非常类似的,在面对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个 ...
- PHP中的分支及循环语句
这次实践的都是PHP7的语法. 感觉是以前的5差别不是那么大,只是希望越来越快吧. <?php $looking = isset($_GET['title']) || isset($_GET[' ...
- 由Catalan数所引出的
百度一番: 历史 ·1758年,Johann Segner 给出了欧拉问题的递推关系: ·1838年,研究热潮: –GabrielLame给出完整证明和简洁表达式: –EugèneCharlesCat ...
- CodeForces - 95E: Lucky Country (多重背包)
pro:给定N个点,M条边,现在你要给一些连通块加边,使得至少存在一个连通块的大小是由4和7组成的数字.问至少加边数量. sol: 看似一个很难的题目. 首先不要想太难了,还是应该想能不能用背包做. ...
- dimensionality reduction动机---visualization(将数据可视化帮助我们更好地理解数据)
如果我们能更好地理解我们的数据,这样会对我们开发高效的机器学习算法有作用,将数据可视化(将数据画出来能更好地理解数据)出来将会对我们理解我们的数据起到很大的帮助. 高维数据如何进行显示 GDP: gr ...
- pycharm激活2018(终极解决办法)
1.将“0.0.0.0 account.jetbrains.com”中的内容添加到hosts文件中,hosts路径为:C:\Windows\System32\drivers\etc 2.打开http: ...
- vue组件通信方式(多种方案)
一.Props传递数据 components |-Grandson1.vue //孙子1 |-Grandson2.vue //孙子2 |-Parent.vue //父亲 |-Grandson1.vue ...