using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Configuration;
using System.Reflection;
using System.Threading.Tasks;
using System.Text; namespace Lemon.Common
{
public static class RedisUtil
{
//缓存失效时长
private static TimeSpan _expiry = TimeSpan.FromMinutes();
private static object _locker = new Object();
private static ConnectionMultiplexer _instance = null; /// <summary>
/// 使用一个静态属性来返回已连接的实例,如下列中所示。这样,一旦 ConnectionMultiplexer 断开连接,便可以初始化新的连接实例。
/// </summary>
public static ConnectionMultiplexer Instance
{
get
{
if (_instance == null)
{
lock (_locker)
{
if (_instance == null || !_instance.IsConnected)
{
_instance = ConnectionMultiplexer.Connect(EnvironmentCache.ConnectionStrings["RedisConnection"]);
}
}
}
//注册如下事件
_instance.ConnectionFailed += MuxerConnectionFailed;
_instance.ConnectionRestored += MuxerConnectionRestored;
_instance.ErrorMessage += MuxerErrorMessage;
_instance.HashSlotMoved += MuxerHashSlotMoved;
_instance.InternalError += MuxerInternalError;
return _instance;
}
} static RedisUtil()
{
} /// <summary>
///
/// </summary>
/// <returns></returns>
public static IDatabase GetDatabase(int db)
{
return Instance.GetDatabase(db);
} /// <summary>
/// 异步获取缓存数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dbIndex">Redis数据库索引</param>
/// <param name="key">Redis键</param>
/// <param name="fun">从其他地方获取数据源,并缓存到Redis中</param>
/// <returns></returns>
public static async Task<T> GetAsync<T>(int dbIndex, string key, Func<T> fun)
{
var db = GetDatabase(dbIndex);
if (db.KeyExists(key))
{
return JsonConvert.DeserializeObject<T>(db.StringGet(key));
}
T data = default(T);
if (fun != null)
{
data = await Task.Run(() =>
{
return fun();
});
db.Set(key, data);
}
return data;
} /// <summary>
/// 同步获取缓存数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dbIndex">Redis数据库索引</param>
/// <param name="key">Redis键</param>
/// <param name="fun">从其他地方获取数据源,并缓存到Redis中</param>
/// <returns></returns>
public static T Get<T>(int dbIndex, string key, Func<T> fun)
{
var db = GetDatabase(dbIndex);
if (db.KeyExists(key))
{
return JsonConvert.DeserializeObject<T>(db.StringGet(key));
}
T data = default(T);
if (fun != null)
{
data = fun();
db.Set(key, data);
}
return data;
} /// <summary>
/// 设置缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public static void Set(this IDatabase db,string key, object value)
{
db.StringSet(key, JsonConvert.SerializeObject(value), _expiry);
} /// <summary>
/// 实现递增
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
//public static long Increment(string 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)
//{
// return GetDatabase().HashDecrement(key, value, flags: CommandFlags.FireAndForget);
//} /// <summary>
/// 发生错误时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
{
Logger.Error(e.Message);
}
/// <summary>
/// 重新建立连接之前的错误
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
Logger.Error(sender, e.Exception);
}
/// <summary>
/// 连接失败 , 如果重新连接成功你将不会收到这个通知
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
// LogHelper.WriteInfoLog("重新连接: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.WriteInfoLog("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)
{
Logger.Error(sender, e.Exception);
} //场景不一样,选择的模式便会不一样,大家可以按照自己系统架构情况合理选择长连接还是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>
///通过secretkey对应的平台id
/// </summary>
/// <param name="secretKey"></param>
/// <returns></returns>
public int GetChannel(string secretKey, string appKey)
{
string key = string.Format("{0}&{1}",secretKey,appKey);
int channelId = RedisUtil.Get<int>(, key, () =>
{
using (var context = new MediaDBContext())
{
return context.ChannelApps.Where(a => a.AppKey == appKey && a.Channel.SecretKey == secretKey && !a.IsDel)
.Select(c => c.ChannelId)
.FirstOrDefault();
}
});
return channelId;
}
 <add name="RedisConnection" connectionString="127.0.0.1,password=Lemon82211852" />

最新文章

  1. Planetary.js:帮助你构建超炫的互动球体效果
  2. [设计模式] javascript 之 建造者模式
  3. C# Socket 入门3 UPD(转)
  4. IntervalZero RTX 2014
  5. 基于.NET平台常用的框架和开源程序整理
  6. hdu 3308
  7. linux下实现两人、三人无序对话功能
  8. SecureCRT的安装与破解(过程很详细!!!)
  9. Vue-admin工作整理(十七):Mock模拟Ajax请求
  10. three.js的组合与合并,raycaster射线无法获取group
  11. Linux下修改Mysql的用户(root)的密码的俩种方法
  12. Nginx技术研究系列5-动态路由升级版
  13. python基础之面向对象的多继承以及MRO算法
  14. 【AMQ】之概述
  15. Mac iterm2 创建服务器列表
  16. sqlserver中numeric字段截取
  17. VMware下的Linux系统中Windows的共享目录,不支持创建软连接
  18. Python开发【项目】:RPC异步执行命令(RabbitMQ双向通信)
  19. Xcode 7提示App Transport Security has blocked a cleartext HTTP (http://) resource load的解决办法
  20. 跳跃表 https://61mon.com/index.php/archives/222/

热门文章

  1. Python基础教程2上的一处打印缺陷导致的代码不完整#1
  2. Java collection 容器
  3. CSS3 filter(滤镜)
  4. C# winfrom容器布局与工具栏&amp;&amp;右键菜单栏&amp;&amp;隐藏显示小图标的的简单事件
  5. [luogu4309][最长上升子序列]
  6. 关于Jedis是否线程安全的测试
  7. Oracle 常用的十大 DDL 对象
  8. ElasticSearch6.5.0 【Rejecting mapping update to [posts] as the final mapping would have more than 1 type】
  9. 高级组件——弹出式菜单JPopupMenu
  10. nginx buffered to a temporary 解决