zoukankan      html  css  js  c++  java
  • 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(30);
            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>(0, 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" />
  • 相关阅读:
    跳出iframe
    leetcode 225. Implement Stack using Queues
    leetcode 206. Reverse Linked List
    leetcode 205. Isomorphic Strings
    leetcode 203. Remove Linked List Elements
    leetcode 198. House Robber
    leetcode 190. Reverse Bits
    leetcode leetcode 783. Minimum Distance Between BST Nodes
    leetcode 202. Happy Number
    leetcode 389. Find the Difference
  • 原文地址:https://www.cnblogs.com/zoro-zero/p/5603714.html
Copyright © 2011-2022 走看看