redis的常用公共方法(2)

之前已经写过一篇redis公共方法的使用(https://www.cnblogs.com/jhy55/p/7681626.html),可是发现在高并发的时候出现 Unknown reply on integer response: 43OK 这样子的错误

ServiceStack.Redis.RedisResponseException: Unknown reply on integer response: 43PONG, sPort: 59017, LastCommand: EXISTS EX:AnKey:Cmp6
at ServiceStack.Redis.RedisNativeClient.CreateResponseError(String error)
at ServiceStack.Redis.RedisNativeClient.ReadLong()
at ServiceStack.Redis.RedisNativeClient.SendExpectLong(Byte[][] cmdWithBinaryArgs)
at ServiceStack.Redis.RedisNativeClient.Exists(String key)
at Redis.Documentos.RedisBaseType.Exists(String key)

这个错误消息表示相同的Redis客户端实例正在多个线程之间共享

错误详细解释 https://stackoverflow.com/questions/36436212/unexpected-reply-on-high-volume-scenario-using-servicestack-redis

 

如果有不足的地方,请指正

 用到第三方dll NServiceKit.Redis ,可以在Nuget中应用

    public class RedisUtil
    {
        #region 字段
        /// <summary>
        /// Redis服务器地址
        /// </summary>
        private static string _host;

        /// <summary>
        /// 端口
        /// </summary>
        private static int _port;

        /// <summary>
        /// 密码
        /// </summary>
        private static string _password;

        /// <summary>
        /// 过期时间
        /// </summary>
        private static DateTime _timeout;



        #endregion

        #region 属性
        /// <summary>
        /// Redis服务器地址
        /// </summary>
        public static string Host
        {
            get { return _host = ConfigurationManager.AppSettings["RedisIp"]; }
        }

        /// <summary>
        /// 端口
        /// </summary>
        public static int Port
        {
            get { return _port = Int32.Parse(ConfigurationManager.AppSettings["RedisPort"]); }
        }
        /// <summary>
        /// 密码
        /// </summary>
        public static string Password
        {
            get { return _password = ConfigurationManager.AppSettings["RedisPassWord"]; }
        }

        public static bool IsLock
        {
            get { return Soholife.Common.CommonUtils.GetIntValue(ConfigurationManager.AppSettings["RedisIsLock"], 0) == 0 ? false : true; }
        }

        public static int TimeOutDay = Int32.Parse(ConfigurationManager.AppSettings["RedisTimeDayOut"]);



        /// <summary>
        /// 过期时间
        /// </summary>
        public static DateTime Timeout
        {
            get { return _timeout = DateTime.Now.AddDays(TimeOutDay); }
        }
        #endregion


        //private static object _locker = new object();

        static PooledRedisClientManager prcm = null;

        /// <summary>
        /// 无参构造
        /// </summary>
        static RedisUtil()
        {
            //ip:port前面加上@用来表示密码,比如password@ip:port
            string sFromstr = "{0}@{1}:{2}";
            prcm = CreateManager(new string[] { string.Format(sFromstr, Password, Host, Port) }, new string[] { string.Format(sFromstr, Password, Host, Port) }, ChangeDb);

        }

        /// <summary>
        ///  创建链接池管理对象  
        /// </summary> 
        public static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts, long initialDB)
        {
            prcm = new PooledRedisClientManager(readWriteHosts, readOnlyHosts,
              new RedisClientManagerConfig
              {
                  MaxWritePoolSize = readWriteHosts.Length * 50,
                  MaxReadPoolSize = readOnlyHosts.Length * 50,
                  AutoStart = true,
              }, initialDB, 50, 30);

            prcm.IdleTimeOutSecs = 30;

            return prcm;
        } 

       /// <summary>
        /// 变动的DB
        /// </summary>
        private static long ChangeDb { get { return Soholife.Common.CommonUtils.GetIntValue(ConfigurationManager.AppSettings["ChangeDb"]); } }



        /// <summary>
        /// 从Redis中读取日志记录列表
        /// </summary>
        /// <typeparam name="T">数据结构类型</typeparam>
        /// <param name="sKey">关键字</param>
        /// <returns></returns>
        public static List<T> ReaderEnqueueList<T>(string sKey)
        {
            using (var redis = prcm.GetClient() as RedisClient)
            {
                var OrderStepLogList = redis.As<T>();
                var fromList = OrderStepLogList.Lists[sKey];
                List<T> oList = OrderStepLogList.GetAllItemsFromList(fromList);
                if (oList != null)
                {
                    OrderStepLogList.RemoveAllFromList(fromList);
                }
                return oList;
            }
        }

        /// <summary>
        /// 加入具有数据结构的消息队列中
        /// </summary>
        /// <typeparam name="T">数据结构类型</typeparam>
        /// <param name="t">数据对象</param>
        /// <param name="sKey">关键字</param>
        public static void AddEnqueue<T>(T t, string sKey)
        {
            using (var redis = prcm.GetClient() as RedisClient)
            {
                var OrderStepLogList = redis.As<T>();
                //加入具有数据结构的消息队列中
                OrderStepLogList.EnqueueItemOnList(OrderStepLogList.Lists[sKey], t);
            }
        }


        #region 外部调用方法

       /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="key"></param>
        /// <param name="t"></param>
        /// <param name="timeOut">过期时间</param>
        /// <returns></returns>
        public static bool Set<T>(string key, T t)
        {
            if (IsLock) return false;

            using (var redis = prcm.GetClient() as RedisClient)
            {
                return redis.Set(key, t, Timeout);
            }
        }


        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="key"></param>
        /// <param name="t"></param>
        /// <param name="timeOut">过期时间</param>
        /// <returns></returns>
        public static bool Set<T>(string key, T t, DateTime time)
        {
            if (IsLock) return false;
            using (var redis = prcm.GetClient() as RedisClient)
            {
                return redis.Set(key, t, time);
            }
        }
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Get<T>(string key)
        {
            if (IsLock) return default(T);
            using (var redis = prcm.GetClient() as RedisClient)
            {
                if (redis.Exists(key) > 0)
                    return redis.Get<T>(key);
                else
                    return default(T);
            }
        }

        /// <summary>
        /// 判断是否存在某个key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool IsExist(string key)
        {
            if (IsLock) return false;
            using (var redis = prcm.GetClient() as RedisClient)
            {
                byte[] buffer = redis.Get(key);
                if (buffer.Length > 0)
                    return true;
                else
                    return false;
            }
        }

        /// <summary>
        /// 获取Value的byte的长度
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static int GetValueLength(string key)
        {
            if (IsLock) return 0;
            using (var redis = prcm.GetClient() as RedisClient)
            {
                return redis.Get(key).Length;
            }
        }

        /// <summary>
        /// 移除指定的Key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool Remove(string key)
        {
            if (IsLock) return false;

            using (var redis = prcm.GetClient() as RedisClient)
            {
                return redis.Remove(key);
            }
        }

        /// <summary>
        /// 累加(专用的哦)
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string Append(string sKey, string s)
        {
            byte[] t = Encoding.Default.GetBytes(s);
            t = Encoding.Default.GetBytes(Convert.ToBase64String(t) + "^");
            using (var redis = prcm.GetClient() as RedisClient)
            {
                return redis.Append(sKey, t).ToString();
            }
        }

        ///// <summary>
        ///// 获取所有的Keys
        ///// </summary>
        ///// <returns></returns>
        //public static List<string> GetAllKeys()
        //{
        //    return redis.GetAllKeys();
        //}

        #endregion

    }

 

posted @ 2018-06-27 10:24  母鸡轰  阅读(1443)  评论(0编辑  收藏  举报