protected IServer GetValidSentinelServer() { int connectFailCount = 0; int masterAddressFailCount = 0; RedisException lastEx = null; while (connectFailCount + masterAddressFailCount < _sentinelEndpoints.Count) { try { _currentSentinelServer = _currentSentinelServer ?? GetNextSentinelServer(); _currentSentinelServer.Ping(); var masterEndPoint = _currentSentinelServer.SentinelGetMasterAddressByName(_masterName); if (masterEndPoint != null) { return(_currentSentinelServer); } masterAddressFailCount++; //获取master地址失败 } catch (RedisException ex) { lastEx = ex; connectFailCount++; //连接失败 _currentSentinelServer = null; } } throw FormatSentinelGetMasterException(connectFailCount, masterAddressFailCount, lastEx); }
/// <summary>批量生产添加</summary> /// <param name="values">消息集合</param> /// <returns></returns> public Int32 Add(params T[] values) { using var span = Redis.Tracer?.NewSpan($"redismq:Add:{TraceName}", values); var args = new List <Object> { Key }; foreach (var item in values) { if (AttachTraceId) { args.Add(Redis.AttachTraceId(item)); } else { args.Add(item); } } // 返回插入后的LIST长度 var rs = Execute(rc => rc.Execute <Int32>("LPUSH", args.ToArray()), true); if (rs <= 0 && ThrowOnFailure) { var ex = new RedisException($"发布到队列[{Topic}]失败!"); span?.SetError(ex, null); throw ex; } return(rs); }
public Error( RedisTargetInfo targetInfo, RedisCommandInfo commandInfo, RedisException exception) { TargetInfo = targetInfo; CommandInfo = commandInfo; Exception = exception; }
private Exception ProcessException(Exception ex) { DisposeIfFatalError(ex); if (!(ex is RedisException)) { ex = new RedisException(ex.Message, ex); } return(ex); }
/// <summary> /// 生成连接错误 /// </summary> /// <returns></returns> private RedisException CreateConnectionError() { HadExceptions = true; var throwEx = new RedisException( string.Format("Unable to Connect: Port: {0}", this._config.Port), this._socketClient.LastSocketException); s_Logger.Error(throwEx.Message); throw throwEx; }
protected internal IDisposable NoneRedisSimpleError() { var old_isThrowRedisSimpleError = _isThrowRedisSimpleError; _isThrowRedisSimpleError = false; return(new TempDisposable(() => { _isThrowRedisSimpleError = old_isThrowRedisSimpleError; RedisSimpleError = null; })); }
/// <summary> /// Processing method of RedisException. /// </summary> /// <param name="ex">Instance RedisException.</param> public void ProcessingException(RedisException ex) { var swRedisExceptionLog = new StreamWriter("RedisExceptionLog.txt", true); swRedisExceptionLog.WriteLine("#########################################################################################"); swRedisExceptionLog.WriteLine($"RedisException DateTime: {DateTime.Now}\n"); swRedisExceptionLog.WriteLine($"RedisException Data: {ex.Data}\n"); swRedisExceptionLog.WriteLine($"RedisException HelpLink: {ex.HelpLink}\n"); swRedisExceptionLog.WriteLine($"RedisException HResult: {ex.HResult}\n"); swRedisExceptionLog.WriteLine($"RedisException InnerException: {ex.InnerException}\n"); swRedisExceptionLog.WriteLine($"RedisException Message: {ex.Message}\n"); swRedisExceptionLog.WriteLine($"RedisException Source: {ex.Source}\n"); swRedisExceptionLog.WriteLine($"RedisException StackTrace: {ex.StackTrace}\n"); swRedisExceptionLog.WriteLine($"RedisException TargetSite: {ex.TargetSite}\n"); swRedisExceptionLog.Close(); }
/// <summary>添加延迟消息</summary> /// <param name="value"></param> /// <param name="delay"></param> /// <returns></returns> public Int32 Add(T value, Int32 delay) { using var span = Redis.Tracer?.NewSpan($"redismq:AddDelay:{TraceName}", value); // 添加到有序集合的成员数量,不包括已经存在更新分数的成员 var rs = _sort.Add(value, DateTime.Now.ToInt() + delay); if (rs <= 0 && ThrowOnFailure) { var ex = new RedisException($"发布到队列[{Topic}]失败!"); span?.SetError(ex, null); throw ex; } return(rs); }
/// <summary>生产添加</summary> /// <param name="value">消息</param> /// <returns></returns> public Int32 Add(T value) { using var span = Redis.Tracer?.NewSpan($"redismq:Add:{TraceName}", value); var val = AttachTraceId ? Redis.AttachTraceId(value) : value; // 返回插入后的LIST长度 var rs = Execute(rc => rc.Execute <Int32>("LPUSH", Key, val), true); if (rs <= 0 && ThrowOnFailure) { var ex = new RedisException($"发布到队列[{Topic}]失败!"); span?.SetError(ex, null); throw ex; } return(rs); }
public void PutAsync_RetryTwiceOnRedisException() { RedisException redisException = (RedisException)FormatterServices.GetUninitializedObject(typeof(RedisException)); _distributedCache.SetupSequence(x => x.SetAsync(It.Is <string>(y => y == _key), It.IsAny <byte[]>(), It.IsAny <DistributedCacheEntryOptions>(), It.IsAny <CancellationToken>())) .Throws(redisException) .Throws(redisException) .Throws(redisException) .Throws(redisException); DistributedCacheWrapperWithCompression distributedCacheWrapperWithCompression = new DistributedCacheWrapperWithCompression(_distributedCache.Object); RedisException ex = Assert.ThrowsAsync <RedisException>(async() => { await distributedCacheWrapperWithCompression.PutAsync(_key, _testClass, _ttl, CancellationToken.None, true); }); _distributedCache.Verify(x => x.SetAsync(It.Is <string>(y => y == _key), It.IsAny <byte[]>(), It.IsAny <DistributedCacheEntryOptions>(), It.IsAny <CancellationToken>()), Times.Exactly(3)); }
/// <summary>批量生产</summary> /// <param name="values"></param> /// <returns></returns> public Int32 Add(params T[] values) { if (values == null || values.Length == 0) { return(0); } using var span = Redis.Tracer?.NewSpan($"redismq:AddDelay:{TraceName}", values); var rs = _sort.Add(values, DateTime.Now.ToInt() + Delay); if (rs <= 0 && ThrowOnFailure) { var ex = new RedisException($"发布到队列[{Topic}]失败!"); span?.SetError(ex, null); throw ex; } return(rs); }
private RedisSentinelWorker GetValidSentinelWorker() { if (this._isDisposed) { throw new ObjectDisposedException(this.GetType().Name); } if (this._worker != null) { lock (this._oLock) { return(this._worker); } } RedisException lastEx = null; while (this._worker == null && this.ShouldRetry()) { try { this._worker = this.GetNextSentinel(); this.GetRedisManager(); this._worker.BeginListeningForConfigurationChanges(); this._failures = 0; // reset return(this._worker); } catch (RedisException ex) { this.OnWorkerError?.Invoke(ex); lastEx = ex; this._worker = null; this._failures++; Interlocked.Increment(ref RedisState.TotalFailedSentinelWorkers); } } this._failures = 0; // reset Thread.Sleep(this.WaitBetweenFailedHosts); throw new RedisException("No Redis Sentinels were available", lastEx); }
/// <summary>批量生产添加</summary> /// <param name="values">消息集合</param> /// <returns>返回插入后的LIST长度</returns> public Int32 Add(params T[] values) { if (values == null || values.Length == 0) { return(0); } using var span = Redis.Tracer?.NewSpan($"redismq:AddReliable:{TraceName}", values); var args = new List <Object> { Key }; foreach (var item in values) { if (AttachTraceId) { args.Add(Redis.AttachTraceId(item)); } else { args.Add(item); } } // 返回插入后的LIST长度。Redis执行命令不会失败,因此正常插入不应该返回0,如果返回了0或者服务,可能是中间代理出了问题 var rs = Execute(rc => rc.Execute <Int32>("LPUSH", args.ToArray()), true); if (rs <= 0 && ThrowOnFailure) { var ex = new RedisException($"发布到队列[{Topic}]失败!"); span?.SetError(ex, null); throw ex; } return(rs); }
#pragma warning restore CS1998 #pragma warning restore CS1591 /// <summary> /// Gets an example RedisException /// </summary> /// <returns></returns> public static RedisException GetRedisException() { var ex = new RedisException("GetInt: Timeout performing GET prod-throttle-11.22.33.44-reqs, inst: 1, queue: 8, qu: 0, qs: 8, qc: 0, wr: 0, wq: 0, in: 0, ar: 0, clientName: API v2, serverEndpoint: Unspecified/redis01.servers.stackexchange.com:6379, keyHashSlot: 2576, IOCP: (Busy=0,Free=1000,Min=48,Max=1000), WORKER: (Busy=3,Free=32764,Min=48,Max=32767) (Please take a look at this article for some common client-side issues that can cause timeouts: http://stackexchange.github.io/StackExchange.Redis/Timeouts) with keys: throttle-11.22.33.44-reqs"); ex.Data["redis-command"] = "GET prod-throttle-11.22.33.44-reqs"; ex.Data["redis-server"] = "redis01.servers.stackexchange.com:6379"; ex.Data["Redis-Message"] = "GET prod-throttle-11.22.33.44-reqs"; ex.Data["Redis-Instantaneous"] = "1"; ex.Data["Redis-Queue-Length"] = "8"; ex.Data["Redis-Queue-Outstanding"] = "0"; ex.Data["Redis-Queue-Awaiting-Response"] = "0"; ex.Data["Redis-Queue-Completion-Outstanding"] = "0"; ex.Data["Redis-Active-Writers"] = "0"; ex.Data["Redis-Write-Queue"] = "0"; ex.Data["Redis-Inbound-Bytes"] = "0"; ex.Data["Redis-Active-Readers"] = "0"; ex.Data["Redis-Client-Name"] = "API v2"; ex.Data["Redis-Server-Endpoint"] = "Unspecified/redis01.servers.stackexchange.com:6379"; ex.Data["Redis-Key-HashSlot"] = "2576"; ex.Data["Redis-ThreadPool-IO-Completion"] = "(Busy=0,Free=1000,Min=48,Max=1000)"; ex.Data["Redis-ThreadPool-Workers"] = "(Busy=3,Free=32764,Min=48,Max=32767)"; ex.Data["Redis-Busy-Workers"] = "3"; return(ex); }
protected RedisSentinelException FormatSentinelGetMasterException(int connectFailCount, int masterAddressFailCount, RedisException innerException) { var errorMessage = string.Empty; if (masterAddressFailCount == 0) { errorMessage = "No Redis Sentinels were available"; } else if (connectFailCount == 0) { errorMessage = string.Format("Sentinels don't know the master name: {0}", _masterName); } else { errorMessage = "Can't find the master address"; } return(new RedisSentinelException(errorMessage, innerException)); }
public async Task ReadAsync(RedisPipelineItem redisItem) { // Everything is inline to prevent unncessary task allocations // this code is called A LOT await ReadResponseAsync().ConfigureAwait(false); if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); } var firstChar = ReadFirstChar(); if (firstChar == RedisProtocolContants.SimpleString) { if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); } var bytes = new List <byte>(); var response = (IList <byte>)CurrentResponse; var currentChar = response[CurrentPosition]; while (currentChar != RedisProtocolContants.LineFeed) { if (currentChar != RedisProtocolContants.CarriageReturn) { bytes.Add(currentChar); } CurrentPosition++; if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); response = CurrentResponse; } currentChar = response[CurrentPosition]; } CurrentPosition++; ProcessValue(redisItem, bytes.ToArray()); } else if (firstChar == RedisProtocolContants.Integer) { if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); } var bytes = new List <byte>(); var response = (IList <byte>)CurrentResponse; var currentChar = response[CurrentPosition]; while (currentChar != RedisProtocolContants.LineFeed) { if (currentChar != RedisProtocolContants.CarriageReturn) { bytes.Add(currentChar); } CurrentPosition++; if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); response = CurrentResponse; } currentChar = response[CurrentPosition]; } CurrentPosition++; ProcessValue(redisItem, bytes.ToArray()); } else if (firstChar == RedisProtocolContants.BulkString) { var length = await ReadLengthAsync().ConfigureAwait(false); if (length == -1) { ProcessValue(redisItem, null); return; } var bytes = new List <byte>(); var response = (IList <byte>)CurrentResponse; for (var i = 0; i < length; i++) { if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); response = CurrentResponse; } var currentChar = response[CurrentPosition]; bytes.Add(currentChar); CurrentPosition++; } for (var i = 0; i < 2; i++) { if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); } CurrentPosition++; } ProcessValue(redisItem, bytes?.ToArray()); } else if (firstChar == RedisProtocolContants.Array) { var value = await ReadArrayAsync().ConfigureAwait(false); redisItem.OnSuccess(value); } else if (firstChar == RedisProtocolContants.Error) { if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); } var bytes = new List <byte>(); var response = (IList <byte>)CurrentResponse; var currentChar = response[CurrentPosition]; while (currentChar != RedisProtocolContants.LineFeed) { if (currentChar != RedisProtocolContants.CarriageReturn) { bytes.Add(currentChar); } CurrentPosition++; if (CurrentPosition >= CurrentResponse.Count) { await ReadNextResponseAsync().ConfigureAwait(false); response = CurrentResponse; } currentChar = response[CurrentPosition]; } CurrentPosition++; var errorText = Encoding.UTF8.GetString(bytes.ToArray()); var exception = new RedisException(errorText); redisItem.OnError(exception); } else { var exception = new RedisException("Could not process Redis response."); throw exception; // restart the pipeline. } }
/// <summary>生产添加</summary> /// <param name="value">消息体</param> /// <param name="msgId">消息ID</param> /// <returns>返回消息ID</returns> public String Add(T value, String msgId = null) { if (value == null) { throw new ArgumentNullException(nameof(value)); } using var span = Redis.Tracer?.NewSpan($"redismq:AddStream:{TraceName}", value); // 自动修剪超长部分,每1000次生产,修剪一次 if (_count <= 0) { _count = Count; } Interlocked.Increment(ref _count); var args = new List <Object> { Key }; if (MaxLenngth > 0 && _count % 1000 == 0) { _count = Count + 1; args.Add("maxlen"); args.Add("~"); args.Add(MaxLenngth); } // *号表示服务器自动生成ID args.Add(msgId.IsNullOrEmpty() ? "*" : msgId); // 数组和复杂对象字典,分开处理 if (Type.GetTypeCode(value.GetType()) != TypeCode.Object) { //throw new ArgumentOutOfRangeException(nameof(value), "消息体必须是复杂对象!"); args.Add(PrimitiveKey); args.Add(value); } else if (value.GetType().IsArray) { foreach (var item in (value as Array)) { args.Add(item); } } else { // 在消息体内注入TraceId,用于构建调用链 var val = AttachTraceId ? Redis.AttachTraceId(value) : value; foreach (var item in val.ToDictionary()) { args.Add(item.Key); args.Add(item.Value); } } var rs = Execute(rc => rc.Execute <String>("XADD", args.ToArray()), true); if (rs.IsNullOrEmpty() && ThrowOnFailure) { var ex = new RedisException($"发布到队列[{Topic}]失败!"); span?.SetError(ex, null); throw ex; } return(rs); }
private Exception ProcessException(Exception ex) { DisposeIfFatalError(ex); if (!(ex is RedisException)) ex = new RedisException(ex.Message, ex); return ex; }
public RedisSentinelException(string message, RedisException innerException) : base(message, innerException) { }