Exemple #1
0
 private void FlowControlIfNecessary()
 {
     if (_flowControlThreshold > 0 && _connection.PendingMessageCount >= _flowControlThreshold)
     {
         var milliseconds = FlowControlUtil.CalculateFlowControlTimeMilliseconds(
             (int)_connection.PendingMessageCount,
             _flowControlThreshold,
             _setting.SendMessageFlowControlStepPercent,
             _setting.SendMessageFlowControlWaitMilliseconds);
         Thread.Sleep(milliseconds);
     }
 }
Exemple #2
0
        public void EnterConsumingQueue(ConsumeResult <Ignore, string> message)
        {
            TopicPartitionProcessQueue <Ignore, string> processQueue;

            if (_consumingQueues.TryGetValue(message.ToKeyString(), out processQueue))
            {
                processQueue.AddMessage(message);
            }
            else
            {
                processQueue = new TopicPartitionProcessQueue <Ignore, string>(message.Topic, message.Partition);
                processQueue.AddMessage(message);
                _consumingQueues.TryAdd(message.ToKeyString(), processQueue);
            }

            if (_isSequentialConsume)
            {
                _consumeWaitingQueue.Add(message);
            }
            else
            {
                Task.Factory.StartNew(async m =>
                {
                    await HandleMessageAsync(m);
                }, message);
            }

            var unconsumedMessageCount = processQueue.GetMessageCount();

            if (unconsumedMessageCount > _consumer.Setting.ConsumeFlowControlThreshold)
            {
                var delayMilliseconds = FlowControlUtil.CalculateFlowControlTimeMilliseconds
                                        (
                    unconsumedMessageCount,
                    _consumer.Setting.ConsumeFlowControlThreshold,
                    _consumer.Setting.ConsumeFlowControlStepPercent,
                    _consumer.Setting.ConsumeFlowControlStepWaitMilliseconds
                                        );

                _logger.InfoFormat($"{message.ToKeyString()} unconsumed message[{unconsumedMessageCount}], consume too slow, need to wait {delayMilliseconds}ms.");
                Thread.Sleep(delayMilliseconds);
            }
        }
Exemple #3
0
        private void PullMessage(PullRequest pullRequest)
        {
            try
            {
                if (_stoped)
                {
                    return;
                }
                if (pullRequest.ProcessQueue.IsDropped)
                {
                    return;
                }

                var messageCount         = pullRequest.ProcessQueue.GetMessageCount();
                var flowControlThreshold = Setting.PullMessageFlowControlThreshold;

                if (flowControlThreshold > 0 && messageCount >= flowControlThreshold)
                {
                    var milliseconds = FlowControlUtil.CalculateFlowControlTimeMilliseconds(
                        messageCount,
                        flowControlThreshold,
                        Setting.PullMessageFlowControlStepPercent,
                        Setting.PullMessageFlowControlStepWaitMilliseconds);
                    Task.Factory.StartDelayedTask(milliseconds, () => SchedulePullRequest(pullRequest));
                    return;
                }

                var request = new PullMessageRequest
                {
                    ConsumerId                     = GetConsumerId(),
                    ConsumerGroup                  = GroupName,
                    MessageQueue                   = pullRequest.MessageQueue,
                    Tags                           = string.Join("|", pullRequest.Tags),
                    QueueOffset                    = pullRequest.NextConsumeOffset,
                    PullMessageBatchSize           = Setting.PullMessageBatchSize,
                    SuspendPullRequestMilliseconds = Setting.SuspendPullRequestMilliseconds,
                    ConsumeFromWhere               = Setting.ConsumeFromWhere
                };
                var data            = SerializePullMessageRequest(request);
                var remotingRequest = new RemotingRequest((int)RequestCode.PullMessage, data);

                pullRequest.PullStartTime = DateTime.Now;
                _remotingClient.InvokeAsync(remotingRequest, Setting.PullRequestTimeoutMilliseconds).ContinueWith(pullTask =>
                {
                    try
                    {
                        if (_stoped)
                        {
                            return;
                        }
                        if (pullRequest.ProcessQueue.IsDropped)
                        {
                            return;
                        }

                        if (pullTask.Exception != null)
                        {
                            _logger.Error(string.Format("Pull message failed, pullRequest:{0}", pullRequest), pullTask.Exception);
                            SchedulePullRequest(pullRequest);
                            return;
                        }

                        ProcessPullResponse(pullRequest, pullTask.Result);
                    }
                    catch (Exception ex)
                    {
                        if (_stoped)
                        {
                            return;
                        }
                        if (pullRequest.ProcessQueue.IsDropped)
                        {
                            return;
                        }
                        if (_remotingClient.IsConnected)
                        {
                            string remotingResponseBodyLength;
                            if (pullTask.Result != null)
                            {
                                remotingResponseBodyLength = pullTask.Result.Body.Length.ToString();
                            }
                            else
                            {
                                remotingResponseBodyLength = "pull message result is null.";
                            }
                            _logger.Error(string.Format("Process pull result has exception, pullRequest:{0}, remotingResponseBodyLength:{1}", pullRequest, remotingResponseBodyLength), ex);
                        }
                        SchedulePullRequest(pullRequest);
                    }
                });
            }
            catch (Exception ex)
            {
                if (_stoped)
                {
                    return;
                }
                if (pullRequest.ProcessQueue.IsDropped)
                {
                    return;
                }

                if (_remotingClient.IsConnected)
                {
                    _logger.Error(string.Format("PullMessage has exception, pullRequest:{0}", pullRequest), ex);
                }
                SchedulePullRequest(pullRequest);
            }
        }
        private void PullMessage(PullRequest pullRequest)
        {
            var brokerConnection = _clientService.GetBrokerConnection(pullRequest.MessageQueue.BrokerName);

            if (brokerConnection == null)
            {
                Task.Factory.StartDelayedTask(5 * 1000, () => SchedulePullRequest(pullRequest));
                _logger.ErrorFormat("Pull message failed as the target broker connection not found, pullRequest:{0}", pullRequest);
                return;
            }
            var remotingClient = brokerConnection.RemotingClient;

            try
            {
                if (_consumer.Stopped)
                {
                    return;
                }
                if (pullRequest.IsDropped)
                {
                    return;
                }

                var messageCount         = 0;
                var flowControlThreshold = 0;

                if (_consumer.Setting.AutoPull)
                {
                    messageCount         = pullRequest.ProcessQueue.GetMessageCount();
                    flowControlThreshold = _consumer.Setting.PullMessageFlowControlThreshold;
                }
                else
                {
                    messageCount         = _pulledMessageQueue.Count;
                    flowControlThreshold = _consumer.Setting.ManualPullLocalMessageQueueMaxSize;
                }

                if (messageCount > flowControlThreshold)
                {
                    var milliseconds = FlowControlUtil.CalculateFlowControlTimeMilliseconds(
                        messageCount,
                        flowControlThreshold,
                        _consumer.Setting.PullMessageFlowControlStepPercent,
                        _consumer.Setting.PullMessageFlowControlStepWaitMilliseconds);
                    Task.Factory.StartDelayedTask(milliseconds, () => SchedulePullRequest(pullRequest));
                    return;
                }

                var request = new PullMessageRequest
                {
                    ConsumerId                     = _clientId,
                    ConsumerGroup                  = _consumer.GroupName,
                    MessageQueue                   = pullRequest.MessageQueue,
                    Tags                           = string.Join("|", pullRequest.Tags),
                    QueueOffset                    = pullRequest.NextConsumeOffset,
                    PullMessageBatchSize           = _consumer.Setting.PullMessageBatchSize,
                    SuspendPullRequestMilliseconds = _consumer.Setting.SuspendPullRequestMilliseconds,
                    ConsumeFromWhere               = _consumer.Setting.ConsumeFromWhere
                };
                var data            = SerializePullMessageRequest(request);
                var remotingRequest = new RemotingRequest((int)BrokerRequestCode.PullMessage, data);

                pullRequest.PullStartTime = DateTime.Now;
                remotingClient.InvokeAsync(remotingRequest, _consumer.Setting.PullRequestTimeoutMilliseconds).ContinueWith(pullTask =>
                {
                    try
                    {
                        if (_consumer.Stopped)
                        {
                            return;
                        }
                        if (pullRequest.IsDropped)
                        {
                            return;
                        }

                        if (pullTask.Exception != null)
                        {
                            _logger.Error(string.Format("Pull message failed, pullRequest:{0}", pullRequest), pullTask.Exception);
                            SchedulePullRequest(pullRequest);
                            return;
                        }

                        ProcessPullResponse(pullRequest, pullTask.Result, pulledMessages =>
                        {
                            var filterMessages    = pulledMessages.Where(x => IsQueueMessageMatchTag(x, pullRequest.Tags));
                            var consumingMessages = filterMessages.Select(x => new ConsumingMessage(x, pullRequest)).ToList();

                            if (_consumer.Setting.AutoPull)
                            {
                                pullRequest.ProcessQueue.AddMessages(consumingMessages);
                                foreach (var consumingMessage in consumingMessages)
                                {
                                    if (_consumer.Setting.MessageHandleMode == MessageHandleMode.Sequential)
                                    {
                                        _consumingMessageQueue.Add(consumingMessage);
                                    }
                                    else
                                    {
                                        Task.Factory.StartNew(HandleMessage, consumingMessage);
                                    }
                                }
                            }
                            else
                            {
                                foreach (var consumingMessage in consumingMessages)
                                {
                                    _pulledMessageQueue.Add(consumingMessage.Message);
                                }
                            }
                        });
                    }
                    catch (Exception ex)
                    {
                        if (_consumer.Stopped)
                        {
                            return;
                        }
                        if (pullRequest.IsDropped)
                        {
                            return;
                        }
                        if (remotingClient.IsConnected)
                        {
                            string remotingResponseBodyLength;
                            if (pullTask.Result != null)
                            {
                                remotingResponseBodyLength = pullTask.Result.Body.Length.ToString();
                            }
                            else
                            {
                                remotingResponseBodyLength = "pull message result is null.";
                            }
                            _logger.Error(string.Format("Process pull result has exception, pullRequest:{0}, remotingResponseBodyLength:{1}", pullRequest, remotingResponseBodyLength), ex);
                        }
                        SchedulePullRequest(pullRequest);
                    }
                });
            }
            catch (Exception ex)
            {
                if (_consumer.Stopped)
                {
                    return;
                }
                if (pullRequest.IsDropped)
                {
                    return;
                }

                if (remotingClient.IsConnected)
                {
                    _logger.Error(string.Format("PullMessage has exception, pullRequest:{0}", pullRequest), ex);
                }
                SchedulePullRequest(pullRequest);
            }
        }