Пример #1
0
        public static void QueueStatsLogs(QueueStats q)
        {
            if (q == null)
            {
                return;
            }

#if DEBUGs
            var qMsg = string.Format(@"队列名称:{0},队列项数:{1},消费线程:{2},当前消费:{3},成功:{4},失败:{5},下次消费时间:{6},本次消费耗费时间:{7},出错时间:{8},消费发生错误的次数:{9},错误消息:{10}"
                                     , q.QueueName, q.CurrentQueueCount, q.ConsumerThreadName, q.CurrentBeenConsumedCount, q.FailConsumedCount, q.SuccessConsumedCount
                                     , q.NextConsumerTime, q.ConsumerUseTime, q.ErrorTime, q.ConsumerErrorItemCount, q.ErrorMessage);
            Console.WriteLine(qMsg);
#else
            try
            {
                ThreadPool.QueueUserWorkItem(e =>
                {
                    QueueStats queueStats = e as QueueStats;
                    if (queueStats != null)
                    {
                        var qMsg = string.Format(@"队列名称:{0},队列项数:{1},消费线程:{2},当前消费:{3},成功:{4},失败:{5},下次消费时间:{6},本次消费耗费时间:{7}毫秒,服务端出错时间:{8},服务端错误的次数:{9},,服务端错误消息:{10},客户端Error:{11},客户端错误时间:{12}"
                                                 , q.QueueName, q.CurrentQueueCount, q.ConsumerThreadName, q.CurrentBeenConsumedCount, q.SuccessConsumedCount, q.FailConsumedCount
                                                 , q.NextConsumerTime, q.ConsumerUseTime, q.ErrorTime, q.ConsumerErrorItemCount, q.ErrorMessage, q.ClientErrorMessage, q.ClientErrorTime);
                        try
                        {
                            Write(qMsg);
                        }
                        catch (Exception ex)
                        {
#if DEBUGs
                            Console.WriteLine(ex.Message);
#endif
                        }
                    }
                }, q);
            }
            catch
            {
            }
#endif
        }
        private void Consumer()
        {
            while (BQStatus == Status.RunIng)
            {
                _consumerStats = true;
                var _consumerTime      = _queueSettings.ConsumerTime;
                var _consumerItemCount = _queueSettings.ConsumerItemCount;

                //记录一次消费的状态
                var _currentQueueStats = new QueueStats();
                _currentQueueStats.QueueName          = _queueSettings.QueueName;
                _currentQueueStats.ConsumerThreadName = Thread.CurrentThread.Name;

                var _listConsumerItem = new List <Object>(_consumerItemCount);
                try
                {
                    var _queueCount = _queue.Count;

                    _currentQueueStats.CurrentQueueCount = _queueCount;
                    lock (_queue)
                    {
                        //批量消费策略
                        if (_queueCount > 0)
                        {
                            if (_queueCount >= _consumerItemCount)
                            {
                                for (var i = 0; i < _consumerItemCount; i++)
                                {
                                    var v = _queue.Dequeue();
                                    if (v != null)
                                    {
                                        _listConsumerItem.Add(v);
                                    }
                                }
                            }
                            else
                            {
                                //TODO:生产不足策略:等待数据到来,或消费掉不足的所有数据
#if DEBUG
                                YmatouLoggingService.Debug("生产数据不足:{0},{1},{2}", _queueSettings.QueueName, _consumerItemCount, _queueCount);
#endif
                                for (var i = 0; i < _queueCount; i++)
                                {
                                    var v = _queue.Dequeue();
                                    if (v != null)
                                    {
                                        _listConsumerItem.Add(v);
                                    }
                                }
                            }
                        }
                    }
                    if (_listConsumerItem.Count > 0)
                    {
                        //单个消费
                        //var item = _queue.Dequeue();
                        try
                        {
                            //监控
                            var _watch = Stopwatch.StartNew();
                            //客户端消费数据
                            try
                            {
                                YmatouLoggingService.Debug("进行一次消费 {0}-> {1} 项", _queueSettings.QueueName, _listConsumerItem.Count);
                                _queueSettings.ConsumerAction(_listConsumerItem);
                            }
                            catch (QueueException ce)
                            {
                                _currentQueueStats.ClientErrorMessage = ce.Message;
                                _currentQueueStats.ClientErrorTime    = DateTime.Now;
                                YmatouLoggingService.Debug("客户端消费错误:{0},{1},{2}", _queueSettings.QueueName, ce.Message, ce.StackTrace);
                            }
                            catch (Exception e)
                            {
                                _currentQueueStats.ClientErrorMessage = e.Message;
                                _currentQueueStats.ClientErrorTime    = DateTime.Now;
                                YmatouLoggingService.Debug("客户端消费错误:{0},{1},{2}", _queueSettings.QueueName, e.Message, e.StackTrace);
                            }
                            _currentQueueStats.ConsumerUseTime = _watch.ElapsedMilliseconds;
                            _watch.Stop();

                            //一次消费完成,状态跟踪
                            //统计总共消费
                            //Interlocked.Add(ref _beenConsumedCount, _listConsumerItem.Count);
                            var _listQv = _listConsumerItem.ConvertAll <QueueValue <T> >(e => { return(e as QueueValue <T>); });
                            if (_listQv.Count > 0)
                            {
                                _currentQueueStats.SuccessConsumedCount = _listQv.Count(e => e != null && e.ConsumerResult == QueueItemConsumerStats.Ok);

                                _currentQueueStats.FailConsumedCount        = _listQv.Count(e => e != null && e.ConsumerResult != QueueItemConsumerStats.Ok);
                                _currentQueueStats.CurrentBeenConsumedCount = _listConsumerItem.Count;
                                //一次消费完成,对消费失败的数据再处理
                                if (_queueSettings.ConsumerFS != ConsumerFailStrategy.ClientHandleFail)
                                {
                                    if (_queueSettings.ConsumerFS == ConsumerFailStrategy.Delet)
                                    {
                                    }
                                    else if (_queueSettings.ConsumerFS == ConsumerFailStrategy.PersistenceEnqueue)
                                    {
                                    }
                                    else
                                    {
                                        var _listFailItem = _listQv.Where(e => e != null && e.ConsumerResult != QueueItemConsumerStats.Ok && e.ConsumerCount <= _consumerFailCount);
                                        foreach (var item in _listFailItem)
                                        {
                                            var _errorCount = item.ConsumerCount;
                                            Interlocked.Add(ref _errorCount, 1);
                                            item.ConsumerCount = _errorCount;
                                            if (item.ConsumerCount < _consumerFailCount)
                                            {
                                                _queue.Enqueue(item);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        catch (QueueException e)
                        {
#if !DEBUG
                            QueueLogs.ErrorFormat("队列服务错误,{0},{1},{2}", _queueSettings.QueueName, e.Message, e.StackTrace);
#endif
                            _currentQueueStats.ErrorTime    = DateTime.Now;
                            _currentQueueStats.ErrorMessage = e.Message;
                            Interlocked.Add(ref _errorCount, 1);
                            _currentQueueStats.ConsumerErrorItemCount = _errorCount;
                            var _listQv = _listConsumerItem.ConvertAll <QueueValue <T> >(_ => { return(_ as QueueValue <T>); });
                            foreach (var item in _listQv)
                            {
                                _queue.Enqueue(item);
                            }
                        }
                    }
                }
                catch (QueueException ex)
                {
#if !DEBUG
                    QueueLogs.ErrorFormat("客户端消费错误2:{0},{1},{2}", _queueSettings.QueueName, ex.Message, ex.StackTrace);
#endif
                    _currentQueueStats.ErrorMessage += "" + ex.Message;
                    _currentQueueStats.ErrorTime     = DateTime.Now;
                }
                finally
                {
                    _currentQueueStats.NextConsumerTime = DateTime.Now.Add(_consumerTime);
#if DEBUGs
                    BlockingBoundedQueueStatsHelp.QueueStatsLogs(_currentQueueStats);
#endif

                    Thread.Sleep(_consumerTime);
                }
            }
        }