Redis Fun使用
- 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" />
Redis Fun使用的更多相关文章
- 使用redis构建可靠分布式锁
关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...
- Ignite性能测试以及对redis的对比
测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...
- mac osx 安装redis扩展
1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...
- Redis/HBase/Tair比较
KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式 支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...
- Redis数据库
Redis是k-v型数据库的典范,设计思想及数据结构实现都值得学习. 1.数据类型 value支持五种数据类型:1.字符串(strings)2.字符串列表(lists)3.字符串集合(sets)4.有 ...
- redis 学习笔记(2)
redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...
- redis 学习笔记(1)
redis持久化 snapshot数据快照(rdb) 这是一种定时将redis内存中的数据写入磁盘文件的一种方案,这样保留这一时刻redis中的数据镜像,用于意外回滚.redis的snapshot的格 ...
- python+uwsgi导致redis无法长链接引起性能下降问题记录
今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...
- nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...
- windows+nginx+iis+redis+Task.MainForm构建分布式架构 之 (nginx+iis构建服务集群)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,由标题就能看出此内容不是一篇分享文章能说完的,所以我打算分几篇分享文章来讲解,一步一步实现分 ...
随机推荐
- 课后选做题:MyOD
目录 OD命令了解 MyOD实现 OD命令了解 作用:od命令用于输出文件的八进制.十六进制或其它格式编码的字节,通常用于显示或查看文件中不能直接显示在终端的字符.常见的文件为文本文件和二进制文件.此 ...
- [模板]ETT
解:splay维护括号序列,就是进子树一次出子树一次.树上每个点直接记录这两个点的编号. 建树的时候按照分配的编号建树. #include <bits/stdc++.h> typedef ...
- bs4抓取糗事百科
抓取糗事百科内容及评论,不包含图片信息.user-agent填入浏览器的即可.user-agent对应的value,360极速浏览器的话,可以在地址栏输入about:version,回车,用户代理后面 ...
- struts2 数据转换器
四.数据类型的转换(明白原理,实际开发中几乎不用) 1.开发中的情况: 实际开发中用户通过浏览器输入的数据都是String或者String[]. String/String[]————填充模型(set ...
- typedef typename的用法
我自己最后在这篇文章里理解:[C++]typedef typename什么意思? typedef typename A::a_type b_type; 其中typename是告诉编译器A::a_typ ...
- okhttp 内网可以有,但外网访问数据返不回来,代码一样
:1.问题点在于 下图红框里写成 text/html了,需要改成application/json,造成的问题有:unexpected end of stream 这个是406错误:加上日志之后okh ...
- 解决access 导出 excel 字段截断错误的问题
解决方法:这个问题通过从EXCEL中导入外部数据,也就是ACCESS数据可以解决. 1.选择导入数据 2.点击选择数据源 选择需要导入的access数据源
- 过滤富文本编辑器中的html元素和其他元素
https://blog.csdn.net/fjssharpsword/article/details/53467079 1.应用场景:从一份html文件中或从String(是html内容)中提取纯文 ...
- (BFS) leetcode 690. Employee Importance
690. Employee Importance Easy 377369FavoriteShare You are given a data structure of employee informa ...
- MySQL会发生死锁吗?
SHOW ENGINE INNODB STATUS;来查看死锁日志: SHOW PROCESSLIST;查看进程 MySQL的InnoDB引擎事务有4种隔离级别,主要是为了保证数据的一致性. Inno ...