private void FlowControlIfNecessary() { if (_flowControlThreshold > 0 && _connection.PendingMessageCount >= _flowControlThreshold) { var milliseconds = FlowControlUtil.CalculateFlowControlTimeMilliseconds( (int)_connection.PendingMessageCount, _flowControlThreshold, _setting.SendMessageFlowControlStepPercent, _setting.SendMessageFlowControlWaitMilliseconds); Thread.Sleep(milliseconds); } }
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); } }
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); } }