private async Task TimeoutTaskProcess(SubscriberTopicInfo subscriberTopicInfo, StreamPendingMessageInfo item) { var streamName = subscriberTopicInfo.Topic; var groupName = subscriberTopicInfo.GroupName; var tempList = await _database.StreamRangeAsync(streamName, item.MessageId, item.MessageId, 1); if (tempList == null || tempList[0].Id != item.MessageId) { return; } var currentItem = tempList[0]; JobData jobData = null; try { jobData = JobData.ToJobData(currentItem.Values); } catch (Exception ex) { _logger.LogError(ex, $"redis解析任务数据报错{streamName},{groupName}"); } if (jobData == null || jobData.ErrorCount >= RetryCount) { _logger.LogError($"任务重启重试[任务超时或服务]{RetryCount}次依然失败,streamName:{streamName},groupName:{groupName},ErrorCount:{jobData.ErrorCount}"); await _database.StreamAcknowledgeAsync(streamName, groupName, currentItem.Id); return; } _logger.LogError($"任务重新执行[任务超时或服务重启]streamName:{streamName},groupName:{groupName},ErrorCount:{jobData.ErrorCount}"); jobData.ErrorCount++; jobData.ErrorGroup = groupName; var trans = _database.CreateTransaction(); #pragma warning disable CS4014 _database.StreamAddAsync(streamName, jobData.ToNameValueEntries(), messageId: null, maxLength: _options.StreamMaxLength, useApproximateMaxLength: true); _database.StreamAcknowledgeAsync(streamName, groupName, currentItem.Id); #pragma warning restore CS4014 await trans.ExecuteAsync(); }
private async Task <long> ProcessPel(SubscriberTopicInfo subscriberTopicInfo) { //https://blog.csdn.net/weixin_39166924/article/details/104381231 //每个消费者一个pel var streamName = subscriberTopicInfo.Topic; var groupName = subscriberTopicInfo.GroupName; long waitTime = 0; while (true) { //读取该消费组中所有消费者的pel消息,这里有个问题:消费者一次拉去100条数据时,这100条数据需要消费很长时间时,这里就认为超时了明显不妥。 var pelList = await _database.StreamPendingMessagesAsync(streamName, groupName, BatchCount, RedisValue.Null);//StreamPendingMessageInfo if (pelList.Length == 0) { break; } //pelList = pelList.OrderBy(x=>x.MessageId).ToArray(); //本身应该是正序的 foreach (var item in pelList) { if (_isStart == false) { return(waitTime); //及时关闭 } if (item.IdleTimeInMilliseconds >= ExecuteTimeoutMilliseconds) //处理时间超过120秒的认为当前消息处理时没有得到确认,可能是某个消费者关闭时未确认的消息,这里重新消费 { await TimeoutTaskProcess(subscriberTopicInfo, item); } //else if (item.IdleTimeInMilliseconds < ExecuteTimeoutMilliseconds / 3) //一个优化,小于三分之一时间时 就停止该pel处理,后面的数据肯定更小 //{ // return; //} else { waitTime = ExecuteTimeoutMilliseconds - item.IdleTimeInMilliseconds; return(waitTime); } } } return(waitTime); }