Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
0
 public Error(
     RedisTargetInfo targetInfo,
     RedisCommandInfo commandInfo,
     RedisException exception)
 {
     TargetInfo  = targetInfo;
     CommandInfo = commandInfo;
     Exception   = exception;
 }
Esempio n. 4
0
 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;
        }
Esempio n. 6
0
        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();
 }
Esempio n. 8
0
        /// <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);
        }
Esempio n. 9
0
        /// <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));
        }
Esempio n. 11
0
        /// <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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        /// <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);
            }
Esempio n. 15
0
        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));
        }
Esempio n. 16
0
        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.
            }
        }
Esempio n. 17
0
        /// <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);
        }
Esempio n. 18
0
 private Exception ProcessException(Exception ex)
 {
     DisposeIfFatalError(ex);
     if (!(ex is RedisException))
         ex = new RedisException(ex.Message, ex);
     return ex;
 }
Esempio n. 19
0
 public RedisSentinelException(string message, RedisException innerException)
     : base(message, innerException)
 {
 }