之前已经写过一篇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客户端实例正在多个线程之间共享
如果有不足的地方,请指正
用到第三方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 }