Ejemplo n.º 1
0
 /// <summary>
 /// 发送消息
 /// </summary>
 public async Task <bool> PublishAsync(List <Models.EventLogEntry> Events, CancellationToken cancellationToken = default(CancellationToken))
 {
     using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP"))
     {
         tracer.SetComponent(_compomentName);
         return(await Enqueue(Mapping(Events), true, cancellationToken));
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// 发送消息
        /// </summary>
        public async Task PublishNonConfirmAsync(List <Models.EventLogEntry> Events, CancellationToken cancellationToken)
        {
            using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP"))
            {
                tracer.SetComponent(_compomentName);

                Enqueue(Mapping(Events), cancellationToken);
            }
        }
 public async Task Test()
 {
     using (Hummingbird.Extensions.Tracing.Tracer tracer = new Hummingbird.Extensions.Tracing.Tracer("Test"))
     {
         tracer.SetTag("tag1", "value1");
         tracer.SetError();
         tracer.Log("key1", "value1");
     }
 }
        public async Task <HttpResponseMessage> DeleteAsync(string uri, string authorizationToken = null, string authorizationMethod = "Bearer", IDictionary <string, string> dictionary = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            uri = await ResolveUri(uri);

            var origin = GetOriginFromUri(uri);

            return(await HttpInvoker(origin, async (context, ctx) =>
            {
                using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("HTTP DELETE"))
                {
                    tracer.SetComponent(_compomentName);
                    tracer.SetTag("http.url", uri);
                    tracer.SetTag("http.method", "DELETE");

                    var requestMessage = new HttpRequestMessage(HttpMethod.Delete, uri);

                    SetAuthorizationHeader(requestMessage);

                    if (authorizationToken != null)
                    {
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
                    }

                    if (dictionary != null)
                    {
                        foreach (var key in dictionary.Keys)
                        {
                            requestMessage.Headers.Add(key, dictionary[key]);
                        }
                    }

                    var response = await _client.SendAsync(requestMessage, ctx);

                    #region LOG:记录返回
                    var responseContent = await response.Content.ReadAsStringAsync();
                    tracer.SetTag("http.status_code", (int)response.StatusCode);

                    if (dictionary != null && dictionary.ContainsKey("x-masking") && (dictionary["x-masking"] == "all" || dictionary["x-masking"] == "response"))
                    {
                        //日志脱敏不记录
                    }
                    else
                    {
                        _logger.LogInformation("Http Request Executed :{responseContent}", responseContent);
                    }
                    #endregion

                    if (response.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        throw new HttpRequestException(response.ReasonPhrase);
                    }

                    return response;
                }
            }, cancellationToken));
        }
Ejemplo n.º 5
0
        private void Enqueue(List <EventMessage> Events, CancellationToken cancellationToken)
        {
            var persistentConnection = _senderLoadBlancer.Lease();

            try
            {
                var channel = persistentConnection.GetProducer();
                var groups  = Events.GroupBy(a => a.RouteKey).Select(a => a.Key);

                foreach (var topic in groups)
                {
                    var messages  = new List <Message <string, string> >();
                    var curEvents = Events.Where(a => a.RouteKey == topic).ToArray();
                    for (var eventIndex = 0; eventIndex < curEvents.Count(); eventIndex++)
                    {
                        using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Publish"))
                        {
                            tracer.SetComponent(_compomentName);
                            tracer.SetTag("x-eventId", curEvents[eventIndex].EventId);
                            tracer.SetTag("x-messageId", curEvents[eventIndex].MessageId);
                            tracer.SetTag("x-traceId", curEvents[eventIndex].TraceId);
                            _logger.LogInformation(curEvents[eventIndex].Body);

                            var message = new Message <string, string>();
                            message.Key       = curEvents[eventIndex].MessageId;
                            message.Timestamp = curEvents[eventIndex].Timestamp;
                            message.Value     = curEvents[eventIndex].Body;
                            message.Headers   = new Headers();

                            foreach (var key in curEvents[eventIndex].Headers.Keys)
                            {
                                message.Headers.Add(new Header(key, UTF8Encoding.UTF8.GetBytes(curEvents[eventIndex].Headers[key] as string)));
                            }


                            messages.Add(message);
                        }
                    }

                    channel.ProduceBatch(topic, messages, TimeSpan.FromMilliseconds(_senderConfirmTimeoutMillseconds), TimeSpan.FromMilliseconds(_senderConfirmFlushTimeoutMillseconds), cancellationToken);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                throw ex;
            }
        }
Ejemplo n.º 6
0
        private async Task <HttpResponseMessage> DoPostPutAsync <T>(HttpMethod method, string uri, T item, string authorizationToken = null, AuthorizationTypeEnum authorizationType = AuthorizationTypeEnum.Bearer, IDictionary <string, string> dictionary = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (method != HttpMethod.Post && method != HttpMethod.Put)
            {
                throw new ArgumentException("Value must be either post or put.", nameof(method));
            }

            uri = await ResolveUri(uri);

            var origin = GetOriginFromUri(uri);

            return(await HttpInvokerAsync(origin, async (context, ctx) =>
            {
                using (var tracer = new Hummingbird.Extensions.Tracing.Tracer($"HTTP {method.Method.ToUpper()}"))
                {
                    tracer.SetComponent(_compomentName);
                    tracer.SetTag("http.url", uri);
                    tracer.SetTag("http.method", method.Method.ToUpper());

                    var requestMessage = new HttpRequestMessage(method, uri);
                    var requestContent = JsonConvert.SerializeObject(item);

                    #region LOG:记录请求
                    if (dictionary != null && dictionary.ContainsKey("x-masking") && (dictionary["x-masking"] == "all" || dictionary["x-masking"] == "request"))
                    {
                        //日志脱敏
                    }
                    else
                    {
                        _logger.LogInformation("Http Request Executing:{requestContent}", requestContent);
                    }
                    #endregion

                    SetAuthorizationHeader(requestMessage);

                    requestMessage.Content = new StringContent(requestContent, System.Text.Encoding.UTF8, "application/json");

                    if (authorizationToken != null)
                    {
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue(authorizationMethod, authorizationToken);
                    }

                    if (dictionary != null)
                    {
                        foreach (var key in dictionary.Keys)
                        {
                            requestMessage.Headers.Add(key, dictionary[key]);
                        }
                    }

                    var response = await _client.SendAsync(requestMessage, ctx);
                    var responseContent = await response.Content.ReadAsStringAsync();

                    #region LOG:记录返回
                    tracer.SetTag("http.status_code", (int)response.StatusCode);

                    if (dictionary != null && dictionary.ContainsKey("x-masking") && (dictionary["x-masking"] == "all" || dictionary["x-masking"] == "response"))
                    {
                        //日志脱敏不记录
                    }
                    else
                    {
                        _logger.LogInformation("Http Request Executed:{responseContent}", responseContent);
                    }
                    #endregion

                    if (response.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        throw new HttpRequestException(response.ReasonPhrase);
                    }

                    return response;
                }
            }, cancellationToken));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 订阅消息(同一类消息可以重复订阅)
        /// 作者:郭明
        /// 日期:2017年4月3日
        /// </summary>
        /// <typeparam name="TD"></typeparam>
        /// <typeparam name="TH"></typeparam>
        /// <param name="QueueName"></param>
        /// <param name="EventTypeName"></param>
        /// <param name="BatchSize"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public IEventBus RegisterBatch <TD, TH>(string QueueName, string EventTypeName = "", int BatchSize = 50, CancellationToken cancellationToken = default(CancellationToken))
            where TD : class
            where TH : IEventBatchHandler <TD>
        {
            var persistentConnection = _receiveLoadBlancer.Lease();
            var queueName            = string.IsNullOrEmpty(QueueName) ? typeof(TH).FullName : QueueName;
            var routeKey             = string.IsNullOrEmpty(EventTypeName) ? typeof(TD).FullName : EventTypeName;
            var eventAction          = _lifetimeScope.GetService(typeof(TH)) as IEventBatchHandler <TD>;

            if (eventAction == null)
            {
                eventAction = System.Activator.CreateInstance(typeof(TH)) as IEventBatchHandler <TD>;
            }

            System.Threading.Tasks.Task.Run(async() =>
            {
                IConsumer <string, string> consumer = null;

                try
                {
                    consumer = persistentConnection.GetConsumer();
                    consumer.Subscribe(routeKey);

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            var handlerSuccess   = false;
                            var handlerException = default(Exception);
                            var eas      = consumer.ConsumeBatch(TimeSpan.FromMilliseconds(100), BatchSize, cancellationToken).ToArray();
                            var Messages = new EventResponse[eas.Count()];

                            if (Messages.Length > 0)
                            {
                                _logger.LogInformation($"customer {consumer.Name} got {Messages.Length} messages on subject {routeKey}.");
                            }
                            else
                            {
                                _logger.LogInformation($"customer {consumer.Name} did not get the message of topic {routeKey}.");
                                await System.Threading.Tasks.Task.Delay(50);
                                continue;
                            }

                            try
                            {
                                #region 批量格式化消息
                                for (int j = 0; j < eas.Length; j++)
                                {
                                    var ea = eas[j];

                                    // 消息队列空
                                    if (ea.IsPartitionEOF)
                                    {
                                        _logger.LogDebug("Reached end of topic {consumeResult.Topic}, partition {consumeResult.Partition}, offset {consumeResult.Offset}.");

                                        continue;
                                    }

                                    var EventId   = -1L;
                                    var MessageId = ea.Key;
                                    var TraceId   = MessageId;

                                    using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Received", TraceId))
                                    {
                                        #region 获取EventId & TraceId
                                        if (ea.Headers != null && ea.Headers.Count > 0)
                                        {
                                            try
                                            {
                                                long.TryParse(System.Text.Encoding.UTF8.GetString(ea.Headers.GetLastBytes("x-eventId")), out EventId);
                                            }
                                            catch
                                            { }

                                            try
                                            {
                                                TraceId = System.Text.Encoding.UTF8.GetString(ea.Headers.GetLastBytes("x-traceId"));
                                            }
                                            catch
                                            {
                                            }
                                        }
                                        #endregion

                                        tracer.SetComponent(_compomentName);
                                        tracer.SetTag("queueName", queueName);
                                        tracer.SetTag("x-messageId", MessageId);
                                        tracer.SetTag("x-eventId", EventId);
                                        tracer.SetTag("x-traceId", TraceId);

                                        Messages[j] = new EventResponse()
                                        {
                                            EventId    = EventId,
                                            MessageId  = MessageId,
                                            TraceId    = TraceId,
                                            Headers    = new Dictionary <string, object>(),
                                            Body       = default(TD),
                                            QueueName  = queueName,
                                            RouteKey   = routeKey,
                                            BodySource = ea.Value
                                        };

                                        try
                                        {
                                            #region 设置Body
                                            Messages[j].Body = JsonConvert.DeserializeObject <TD>(Messages[j].BodySource);
                                            #endregion

                                            #region 设置header
                                            foreach (var key in ea.Headers)
                                            {
                                                Messages[j].Headers.Add(key.Key, Encoding.UTF8.GetString(key.GetValueBytes()));
                                            }

                                            if (!Messages[j].Headers.ContainsKey("x-topic"))
                                            {
                                                Messages[j].Headers.Add("x-topic", routeKey);
                                            }
                                            if (!Messages[j].Headers.ContainsKey("x-messageId"))
                                            {
                                                Messages[j].Headers.Add("x-messageId", MessageId);
                                            }
                                            if (!Messages[j].Headers.ContainsKey("x-eventId"))
                                            {
                                                Messages[j].Headers.Add("x-eventId", EventId);
                                            }
                                            if (!Messages[j].Headers.ContainsKey("x-traceId"))
                                            {
                                                Messages[j].Headers.Add("x-traceId", TraceId);
                                            }
                                            #endregion

                                            _logger.LogDebug(Messages[j].BodySource);
                                        }
                                        catch (Exception ex)
                                        {
                                            _logger.LogError(ex, ex.Message);
                                        }
                                    }
                                }
                                #endregion

                                #region 批量处理消息

                                if (Messages != null && Messages.Any())
                                {
                                    using (var executeTracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Execute"))
                                    {
                                        executeTracer.SetComponent(_compomentName);
                                        executeTracer.SetTag("queueName", queueName);

                                        handlerSuccess = await _receiverPolicy.ExecuteAsync(async(handlerCancellationToken) =>
                                        {
                                            return(await eventAction.Handle(Messages.Select(a => (TD)a.Body).ToArray(), Messages.Select(a => (Dictionary <string, object>)a.Headers).ToArray(), handlerCancellationToken));
                                        }, cancellationToken);

                                        if (handlerSuccess)
                                        {
                                            #region 消息处理成功
                                            if (_subscribeAckHandler != null && Messages.Length > 0)
                                            {
                                                _subscribeAckHandler(Messages);
                                            }

                                            foreach (var group in eas.GroupBy(a => a.Partition))
                                            {
                                                consumer.StoreOffset(group.LastOrDefault());
                                            }

                                            #endregion
                                        }
                                        else
                                        {
                                            executeTracer.SetError();
                                        }
                                    }
                                }
                                #endregion
                            }
                            catch (Exception ex)
                            {
                                handlerException = ex;
                                _logger.LogError(ex, ex.Message);
                            }
                            finally
                            {
                                if (!handlerSuccess)
                                {
                                    //重新入队,默认:是
                                    var requeue = true;

                                    try
                                    {
                                        //执行回调,等待业务层的处理结果
                                        if (_subscribeNackHandler != null && Messages != null && Messages.Any())
                                        {
                                            requeue = await _subscribeNackHandler((Messages, handlerException));
                                        }
                                    }
                                    catch (Exception innterEx)
                                    {
                                        _logger.LogError(innterEx, innterEx.Message);
                                    }

                                    if (!requeue)
                                    {
                                        foreach (var group in eas.GroupBy(a => a.Partition))
                                        {
                                            consumer.StoreOffset(group.LastOrDefault());
                                        }
                                    }
                                    else
                                    {
                                        if (eas.Length > 0)
                                        {
                                            foreach (var group in eas.GroupBy(a => a.Partition))
                                            {
                                                consumer.Seek(group.FirstOrDefault().TopicPartitionOffset);

                                                Console.WriteLine($"kafk offset seek,topic={routeKey}                       partation={group.FirstOrDefault().TopicPartition.Partition}offset={group.FirstOrDefault().TopicPartitionOffset.Offset.Value}");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, ex.Message);

                    if (consumer != null)
                    {
                        consumer.Close();
                    }
                }
            });


            return(this);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 订阅消息(同一类消息可以重复订阅)
        /// 作者:郭明
        /// 日期:2017年4月3日
        /// </summary>
        /// <typeparam name="TD"></typeparam>
        /// <typeparam name="TH"></typeparam>
        /// <param name="QueueName">消息类型名称</param>
        /// <param name="EventTypeName">消息类型名称</param>
        /// <returns></returns>
        public IEventBus Register <TD, TH>(string QueueName, string EventTypeName = "", CancellationToken cancellationToken = default(CancellationToken))
            where TD : class
            where TH : IEventHandler <TD>
        {
            var persistentConnection = _receiveLoadBlancer.Lease();
            var queueName            = string.IsNullOrEmpty(QueueName) ? typeof(TH).FullName : QueueName;
            var routeKey             = string.IsNullOrEmpty(EventTypeName) ? typeof(TD).FullName : EventTypeName;
            var eventAction          = _lifetimeScope.GetService(typeof(TH)) as IEventHandler <TD>;

            if (eventAction == null)
            {
                eventAction = System.Activator.CreateInstance(typeof(TH)) as IEventHandler <TD>;
            }


            System.Threading.Tasks.Task.Run(async() =>
            {
                IConsumer <string, string> consumer = null;

                try
                {
                    consumer = persistentConnection.GetConsumer();
                    consumer.Subscribe(routeKey);
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            var ea = consumer.Consume(cancellationToken);

                            // 消息队列空
                            if (ea != null && ea.IsPartitionEOF)
                            {
                                _logger.LogDebug("Reached end of topic {consumeResult.Topic}, partition {consumeResult.Partition}, offset {consumeResult.Offset}.");

                                continue;
                            }
                            else
                            {
                                _logger.LogInformation($"Consumed message '{ea.Value}' at: '{ea.TopicPartitionOffset}'.");
                            }

                            var EventId   = -1L;
                            var MessageId = ea.Key;
                            var TraceId   = MessageId;

                            using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Received", TraceId))
                            {
                                #region 获取EventId 和 TracerId
                                if (ea.Headers != null)
                                {
                                    try
                                    {
                                        long.TryParse(System.Text.Encoding.UTF8.GetString(ea.Headers.GetLastBytes("x-eventId")), out EventId);
                                    }
                                    catch
                                    { }


                                    try
                                    {
                                        TraceId = System.Text.Encoding.UTF8.GetString(ea.Headers.GetLastBytes("x-traceId"));
                                    }
                                    catch
                                    {
                                    }
                                }
                                #endregion

                                tracer.SetComponent(_compomentName);
                                tracer.SetTag("queueName", queueName);
                                tracer.SetTag("x-messageId", MessageId);
                                tracer.SetTag("x-eventId", EventId);
                                tracer.SetTag("x-traceId", TraceId);

                                try
                                {
                                    var eventResponse = new EventResponse()
                                    {
                                        EventId    = EventId,
                                        MessageId  = MessageId,
                                        TraceId    = TraceId,
                                        Headers    = new Dictionary <string, object>(),
                                        Body       = default(TD),
                                        QueueName  = queueName,
                                        RouteKey   = routeKey,
                                        BodySource = ea.Value
                                    };


                                    #region 格式化消息
                                    try
                                    {
                                        #region 设置body
                                        eventResponse.Body = JsonConvert.DeserializeObject <TD>(eventResponse.BodySource);
                                        #endregion

                                        #region 设置header
                                        foreach (var key in ea.Headers)
                                        {
                                            eventResponse.Headers.Add(key.Key, Encoding.UTF8.GetString(key.GetValueBytes()));
                                        }

                                        if (!eventResponse.Headers.ContainsKey("x-topic"))
                                        {
                                            eventResponse.Headers.Add("x-topic", routeKey);
                                        }
                                        if (!eventResponse.Headers.ContainsKey("x-messageId"))
                                        {
                                            eventResponse.Headers.Add("x-messageId", MessageId);
                                        }
                                        if (!eventResponse.Headers.ContainsKey("x-eventId"))
                                        {
                                            eventResponse.Headers.Add("x-eventId", EventId);
                                        }
                                        if (!eventResponse.Headers.ContainsKey("x-traceId"))
                                        {
                                            eventResponse.Headers.Add("x-traceId", TraceId);
                                        }
                                        #endregion

                                        _logger.LogDebug(eventResponse.BodySource);
                                    }
                                    catch (Exception ex)
                                    {
                                        _logger.LogError(ex, ex.Message);
                                    }
                                    #endregion

                                    #region 处理消息
                                    using (var tracerExecuteAsync = new Hummingbird.Extensions.Tracing.Tracer("AMQP Execute"))
                                    {
                                        var handlerSuccess   = false;
                                        var handlerException = default(Exception);

                                        tracerExecuteAsync.SetComponent(_compomentName);
                                        tracerExecuteAsync.SetTag("queueName", queueName);
                                        tracerExecuteAsync.SetTag("x-messageId", MessageId);
                                        tracerExecuteAsync.SetTag("x-eventId", EventId);
                                        tracerExecuteAsync.SetTag("x-traceId", TraceId);

                                        try
                                        {
                                            handlerSuccess = await _receiverPolicy.ExecuteAsync(async(handlerCancellationToken) =>
                                            {
                                                return(await eventAction.Handle(eventResponse.Body, (Dictionary <string, object>)eventResponse.Headers, handlerCancellationToken));
                                            }, CancellationToken.None);

                                            if (handlerSuccess)
                                            {
                                                if (_subscribeAckHandler != null)
                                                {
                                                    _subscribeAckHandler(new EventResponse[] { eventResponse });
                                                }

                                                consumer.StoreOffset(ea);
                                                _logger.LogInformation($"kafk offset store,topic={routeKey} partation={ea.TopicPartition.Partition}offset={ea.TopicPartitionOffset.Offset.Value}");


                                                //   consumer.Commit(ea);
                                                //   Console.WriteLine($"kafk offset commit,topic={routeKey} partation={ea.TopicPartition.Partition}offset={ea.TopicPartitionOffset.Offset.Value}");
                                            }
                                            else
                                            {
                                                tracerExecuteAsync.SetError();
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            tracerExecuteAsync.SetError();
                                            handlerException = ex;
                                            _logger.LogError(ex, ex.Message);
                                        }
                                        finally
                                        {
                                            if (!handlerSuccess)
                                            {
                                                //重新入队,默认:是
                                                var requeue = true;

                                                try
                                                {
                                                    //执行回调,等待业务层的处理结果
                                                    if (_subscribeNackHandler != null)
                                                    {
                                                        requeue = await _subscribeNackHandler((new EventResponse[] { eventResponse }, handlerException));
                                                    }
                                                }
                                                catch (Exception innterEx)
                                                {
                                                    _logger.LogError(innterEx, innterEx.Message);
                                                }

                                                if (!requeue)
                                                {
                                                    consumer.StoreOffset(ea);
                                                    _logger.LogInformation($"kafk offset store,topic={routeKey} partation={ea.TopicPartition.Partition}offset={ea.TopicPartitionOffset.Offset.Value}");


                                                    //   consumer.Commit(ea);
                                                    //    Console.WriteLine($"kafk offset commit,topic={routeKey} partation={ea.TopicPartition.Partition}offset={ea.TopicPartitionOffset.Offset.Value}");
                                                }
                                                else
                                                {
                                                    consumer.Seek(ea.TopicPartitionOffset); //重新入队重试

                                                    _logger.LogInformation($"kafk offset seek,topic={routeKey} partation={ea.TopicPartition.Partition}offset={ea.TopicPartitionOffset.Offset.Value}");
                                                }
                                            }
                                        }
                                    }
                                    #endregion
                                }
                                catch (Exception ex)
                                {
                                    tracer.SetError();
                                    _logger.LogError(ex.Message, ex);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, ex.Message);

                    if (consumer != null)
                    {
                        consumer.Close();
                    }
                }
            });

            return(this);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 订阅消息(同一类消息可以重复订阅)
        /// 作者:郭明
        /// 日期:2017年4月3日
        /// </summary>
        /// <typeparam name="TD"></typeparam>
        /// <typeparam name="TH"></typeparam>
        /// <param name="EventTypeName">消息类型名称</param>
        /// <returns></returns>
        public IEventBus RegisterBatch <TD, TH>(string QueueName, string EventTypeName = "", int BatchSize = 50, CancellationToken cancellationToken = default(CancellationToken))
            where TD : class
            where TH : IEventBatchHandler <TD>
        {
            var queueName   = string.IsNullOrEmpty(QueueName) ? typeof(TH).FullName : QueueName;
            var routeKey    = string.IsNullOrEmpty(EventTypeName) ? typeof(TD).FullName : EventTypeName;
            var eventAction = _lifetimeScope.GetService(typeof(TH)) as IEventBatchHandler <TD>;

            if (eventAction == null)
            {
                eventAction = System.Activator.CreateInstance(typeof(TH)) as IEventBatchHandler <TD>;
            }
            var persistentConnection = _receiverLoadBlancer.Lease();

            if (!persistentConnection.IsConnected)
            {
                persistentConnection.TryConnect();
            }

            for (int parallelism = 0; parallelism < _reveiverMaxDegreeOfParallelism; parallelism++)
            {
                try
                {
                    var _channel = persistentConnection.GetConsumer();


                    //direct fanout topic
                    _channel.ExchangeDeclare(_exchange, _exchangeType, true, false, null);
                    //在MQ上定义一个持久化队列,如果名称相同不会重复创建
                    _channel.QueueDeclare(queueName, true, false, false, null);
                    //绑定交换器和队列
                    _channel.QueueBind(queueName, _exchange, routeKey);
                    _channel.QueueBind(queueName, _exchange, queueName);
                    //输入1,那如果接收一个消息,但是没有应答,则客户端不会收到下一个消息
                    _channel.BasicQos(0, (ushort)BatchSize, false);

                    Task.Run(async() =>
                    {
                        while (true)
                        {
                            cancellationToken.ThrowIfCancellationRequested();

                            try
                            {
                                var batchPool            = new List <(string MessageId, BasicGetResult ea)>();
                                var batchLastDeliveryTag = 0UL;

                                #region batch Pull
                                for (var i = 0; i < BatchSize; i++)
                                {
                                    var ea = _channel.BasicGet(queueName, false);

                                    if (ea != null)
                                    {
                                        var MessageId = ea.BasicProperties.MessageId;

                                        if (string.IsNullOrEmpty(MessageId))
                                        {
                                            batchPool.Add((Guid.NewGuid().ToString("N"), ea));
                                        }
                                        else
                                        {
                                            batchPool.Add((ea.BasicProperties.MessageId, ea));
                                        }

                                        batchLastDeliveryTag = ea.DeliveryTag;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                #endregion

                                //队列不为空
                                if (batchPool.Count > 0)
                                {
                                    using (var receiveTracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Received"))
                                    {
                                        var basicGetResults  = batchPool.Select(a => a.ea).ToArray();
                                        var Messages         = new EventResponse[basicGetResults.Length];
                                        var handlerSuccess   = false;
                                        var handlerException = default(Exception);

                                        try
                                        {
                                            for (int i = 0; i < basicGetResults.Length; i++)
                                            {
                                                var ea        = basicGetResults[i];
                                                var MessageId = string.IsNullOrEmpty(ea.BasicProperties.MessageId) ? Guid.NewGuid().ToString("N") : ea.BasicProperties.MessageId;
                                                var TraceId   = MessageId;
                                                var EventId   = -1L;

                                                if (ea.BasicProperties.Headers != null)
                                                {
                                                    #region 获取 eventId
                                                    if (ea.BasicProperties.Headers.ContainsKey("x-eventId"))
                                                    {
                                                        try
                                                        {
                                                            if (!long.TryParse(System.Text.Encoding.UTF8.GetString(ea.BasicProperties.Headers["x-eventId"] as byte[]), out EventId))
                                                            {
                                                                //
                                                            }
                                                        }
                                                        catch (Exception ex)
                                                        {
                                                            _logger.LogError(ex, ex.Message);
                                                        }
                                                    }
                                                    #endregion

                                                    #region 获取 traceid
                                                    if (!ea.BasicProperties.Headers.ContainsKey("x-traceId"))
                                                    {
                                                        try
                                                        {
                                                            TraceId = System.Text.Encoding.UTF8.GetString(ea.BasicProperties.Headers["traceId"] as byte[]);
                                                        }
                                                        catch (Exception ex)
                                                        {
                                                            _logger.LogError(ex, ex.Message);
                                                        }
                                                    }
                                                    #endregion
                                                }

                                                using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP BasicGet"))
                                                {
                                                    tracer.SetComponent(_compomentName);
                                                    tracer.SetTag("queueName", queueName);
                                                    tracer.SetTag("x-messageId", MessageId);
                                                    tracer.SetTag("x-eventId", EventId);
                                                    tracer.SetTag("x-traceId", TraceId);

                                                    Messages[i] = new EventResponse()
                                                    {
                                                        EventId    = EventId,
                                                        MessageId  = MessageId,
                                                        TraceId    = TraceId,
                                                        Headers    = ea.BasicProperties.Headers ?? new Dictionary <string, object>(),
                                                        RouteKey   = routeKey,
                                                        QueueName  = queueName,
                                                        BodySource = Encoding.UTF8.GetString(ea.Body),
                                                        Body       = default(TD),
                                                    };

                                                    #region 设置 header
                                                    if (!Messages[i].Headers.ContainsKey("x-exchange"))
                                                    {
                                                        Messages[i].Headers.Add("x-exchange", _exchange);
                                                    }

                                                    if (!Messages[i].Headers.ContainsKey("x-exchange-type"))
                                                    {
                                                        Messages[i].Headers.Add("x-exchange-type", _exchangeType);
                                                    }
                                                    #endregion

                                                    #region 设置body
                                                    try
                                                    {
                                                        Messages[i].Body = JsonConvert.DeserializeObject <TD>(Messages[i].BodySource);
                                                        _logger.LogInformation(Messages[i].BodySource);
                                                    }
                                                    catch (Exception ex)
                                                    {
                                                        tracer.SetError();
                                                        _logger.LogError(ex, ex.Message);
                                                    }
                                                    #endregion
                                                }
                                            }


                                            if (Messages != null && Messages.Any())
                                            {
                                                using (var executeTracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Execute"))
                                                {
                                                    executeTracer.SetComponent(_compomentName);

                                                    handlerSuccess = await _receiverPolicy.ExecuteAsync(async(handlerCancellationToken) =>
                                                    {
                                                        return(await eventAction.Handle(Messages.Select(a => (TD)a.Body).ToArray(), Messages.Select(a => (Dictionary <string, object>)a.Headers).ToArray(), handlerCancellationToken));
                                                    }, cancellationToken);

                                                    if (handlerSuccess)
                                                    {
                                                        #region 消息处理成功
                                                        if (_subscribeAckHandler != null && Messages.Length > 0)
                                                        {
                                                            _subscribeAckHandler(Messages);
                                                        }

                                                        //确认消息被处理
                                                        _channel.BasicAck(batchLastDeliveryTag, true);

                                                        #endregion
                                                    }
                                                    else
                                                    {
                                                        executeTracer.SetError();
                                                    }
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            _logger.LogError(ex, ex.Message);
                                            receiveTracer.SetError();
                                            handlerException = ex;
                                        }
                                        finally
                                        {
                                            if (!handlerSuccess)
                                            {
                                                #region 消息处理失败
                                                var requeue = true;
                                                try
                                                {
                                                    if (_subscribeNackHandler != null && Messages.Length > 0)
                                                    {
                                                        requeue = await _subscribeNackHandler((Messages, handlerException));
                                                    }
                                                }
                                                catch (Exception innterEx)
                                                {
                                                    _logger.LogError(innterEx.Message, innterEx);
                                                }

                                                _channel.BasicNack(batchLastDeliveryTag, true, requeue);

                                                #endregion
                                            }
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError(ex.Message, ex);
                            }

                            System.Threading.Thread.Sleep(1);
                        }
                    });
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, ex.Message);
                }
            }

            return(this);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// 订阅消息(同一类消息可以重复订阅)
        /// 作者:郭明
        /// 日期:2017年4月3日
        /// </summary>
        /// <typeparam name="TD"></typeparam>
        /// <typeparam name="TH"></typeparam>
        /// <param name="QueueName">消息类型名称</param>
        /// <param name="EventTypeName">消息类型名称</param>
        /// <returns></returns>
        public IEventBus Register <TD, TH>(string QueueName, string EventTypeName = "", CancellationToken cancellationToken = default(CancellationToken))
            where TD : class
            where TH : IEventHandler <TD>
        {
            var queueName   = string.IsNullOrEmpty(QueueName) ? typeof(TH).FullName : QueueName;
            var routeKey    = string.IsNullOrEmpty(EventTypeName) ? typeof(TD).FullName : EventTypeName;
            var eventAction = _lifetimeScope.GetService(typeof(TH)) as IEventHandler <TD>;

            if (eventAction == null)
            {
                eventAction = System.Activator.CreateInstance(typeof(TH)) as IEventHandler <TD>;
            }
            var persistentConnection = _receiverLoadBlancer.Lease();

            if (!persistentConnection.IsConnected)
            {
                persistentConnection.TryConnect();
            }

            for (int i = 0; i < _reveiverMaxDegreeOfParallelism; i++)
            {
                System.Threading.Tasks.Task.Run(() =>
                {
                    try
                    {
                        var _channel = persistentConnection.GetConsumer();

                        //direct fanout topic
                        _channel.ExchangeDeclare(_exchange, _exchangeType, true, false, null);

                        //在MQ上定义一个持久化队列,如果名称相同不会重复创建
                        _channel.QueueDeclare(queueName, true, false, false, null);
                        //绑定交换器和队列
                        _channel.QueueBind(queueName, _exchange, routeKey);
                        //绑定交换器和队列
                        _channel.QueueBind(queueName, _exchange, queueName);
                        //输入1,那如果接收一个消息,但是没有应答,则客户端不会收到下一个消息
                        _channel.BasicQos(0, _preFetch, false);
                        //在队列上定义一个消费者a
                        EventingBasicConsumer consumer = new EventingBasicConsumer(_channel);

                        consumer.Received += async(ch, ea) =>
                        {
                            using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Received"))
                            {
                                try
                                {
                                    #region Ensure IsConnected
                                    if (!persistentConnection.IsConnected)
                                    {
                                        persistentConnection.TryConnect();
                                    }
                                    #endregion

                                    var EventId   = -1L;
                                    var MessageId = string.IsNullOrEmpty(ea.BasicProperties.MessageId) ? Guid.NewGuid().ToString("N") : ea.BasicProperties.MessageId;
                                    var TraceId   = MessageId;

                                    #region 获取 eventId
                                    if (ea.BasicProperties.Headers != null && ea.BasicProperties.Headers.ContainsKey("x-eventId"))
                                    {
                                        try
                                        {
                                            long.TryParse(System.Text.Encoding.UTF8.GetString(ea.BasicProperties.Headers["x-eventId"] as byte[]), out EventId);
                                        }
                                        catch (Exception ex)
                                        {
                                            _logger.LogError(ex, ex.Message);
                                        }
                                    }
                                    #endregion

                                    #region 获取 eventId

                                    if (ea.BasicProperties.Headers != null && ea.BasicProperties.Headers.ContainsKey("x-traceId"))
                                    {
                                        try
                                        {
                                            TraceId = System.Text.Encoding.UTF8.GetString(ea.BasicProperties.Headers["x-traceId"] as byte[]);
                                        }
                                        catch (Exception ex)
                                        {
                                            _logger.LogError(ex, ex.Message);
                                        }
                                    }
                                    #endregion

                                    tracer.SetComponent(_compomentName);
                                    tracer.SetTag("queueName", queueName);
                                    tracer.SetTag("x-messageId", MessageId);
                                    tracer.SetTag("x-traceId", TraceId);
                                    tracer.SetTag("x-eventId", EventId);

                                    var eventResponse = new EventResponse()
                                    {
                                        EventId    = EventId,
                                        MessageId  = MessageId,
                                        TraceId    = TraceId,
                                        Headers    = ea.BasicProperties.Headers ?? new Dictionary <string, object>(),
                                        QueueName  = queueName,
                                        RouteKey   = routeKey,
                                        BodySource = Encoding.UTF8.GetString(ea.Body),
                                        Body       = default(TD),
                                    };

                                    try
                                    {
                                        #region 设置body
                                        eventResponse.Body = JsonConvert.DeserializeObject <TD>(eventResponse.BodySource);
                                        #endregion

                                        #region 设置header
                                        if (!eventResponse.Headers.ContainsKey("x-exchange"))
                                        {
                                            eventResponse.Headers.Add("x-exchange", _exchange);
                                        }

                                        if (!eventResponse.Headers.ContainsKey("x-exchange-type"))
                                        {
                                            eventResponse.Headers.Add("x-exchange-type", _exchangeType);
                                        }
                                        #endregion

                                        _logger.LogInformation(eventResponse.BodySource);
                                    }
                                    catch (Exception ex)
                                    {
                                        _logger.LogError(ex, ex.Message);
                                    }

                                    #region AMQP ExecuteAsync
                                    using (var tracerExecuteAsync = new Hummingbird.Extensions.Tracing.Tracer("AMQP Execute"))
                                    {
                                        var handlerSuccess   = false;
                                        var handlerException = default(Exception);

                                        try
                                        {
                                            handlerSuccess = await _receiverPolicy.ExecuteAsync(async(handlerCancellationToken) =>
                                            {
                                                return(await eventAction.Handle(eventResponse.Body, (Dictionary <string, object>)eventResponse.Headers, handlerCancellationToken));
                                            }, cancellationToken);

                                            if (handlerSuccess)
                                            {
                                                if (_subscribeAckHandler != null)
                                                {
                                                    _subscribeAckHandler(new EventResponse[] { eventResponse });
                                                }

                                                //确认消息
                                                _channel.BasicAck(ea.DeliveryTag, false);
                                            }
                                            else
                                            {
                                                tracerExecuteAsync.SetError();
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            _logger.LogError(ex, ex.Message);
                                            tracerExecuteAsync.SetError();
                                            handlerException = ex;
                                        }
                                        finally
                                        {
                                            if (!handlerSuccess)
                                            {
                                                //重新入队,默认:是
                                                var requeue = true;

                                                try
                                                {
                                                    //执行回调,等待业务层的处理结果
                                                    if (_subscribeNackHandler != null)
                                                    {
                                                        requeue = await _subscribeNackHandler((new EventResponse[] { eventResponse }, handlerException));
                                                    }
                                                }
                                                catch (Exception innterEx)
                                                {
                                                    _logger.LogError(innterEx, innterEx.Message);
                                                }

                                                //确认消息
                                                _channel.BasicReject(ea.DeliveryTag, requeue);
                                            }
                                        }
                                    }
                                    #endregion
                                }
                                catch (Exception ex)
                                {
                                    tracer.SetError();
                                    _logger.LogError(ex.Message, ex);
                                }
                            }
                        };

                        consumer.Unregistered += (ch, ea) =>
                        {
                            _logger.LogDebug($"MQ:{queueName} Consumer_Unregistered");
                        };

                        consumer.Registered += (ch, ea) =>
                        {
                            _logger.LogDebug($"MQ:{queueName} Consumer_Registered");
                        };

                        consumer.Shutdown += (ch, ea) =>
                        {
                            _logger.LogDebug($"MQ:{queueName} Consumer_Shutdown.{ea.ReplyText}");
                        };

                        consumer.ConsumerCancelled += (object sender, ConsumerEventArgs e) =>
                        {
                            _logger.LogDebug($"MQ:{queueName} ConsumerCancelled");
                        };

                        //消费队列,并设置应答模式为程序主动应答
                        _channel.BasicConsume(queueName, false, consumer);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, ex.Message);
                    }
                });
            }

            return(this);
        }
Ejemplo n.º 11
0
        private async Task <bool> Enqueue(List <EventMessage> Events, bool confirm, CancellationToken cancellationToken = default(CancellationToken))
        {
            var persistentConnection = _senderLoadBlancer.Lease();

            try
            {
                if (!persistentConnection.IsConnected)
                {
                    persistentConnection.TryConnect();
                }

                var channel = persistentConnection.GetProducer();

                // 提交走批量通道
                var batchPublish = channel.CreateBasicPublishBatch();

                for (var eventIndex = 0; eventIndex < Events.Count; eventIndex++)
                {
                    await _senderRetryPolicy.ExecuteAsync((ct) =>
                    {
                        var MessageId = Events[eventIndex].MessageId;
                        var json      = Events[eventIndex].Body;
                        var routeKey  = Events[eventIndex].RouteKey;
                        byte[] bytes  = Encoding.UTF8.GetBytes(json);
                        //设置消息持久化
                        IBasicProperties properties     = channel.CreateBasicProperties();
                        properties.DeliveryMode         = 2;
                        properties.MessageId            = MessageId;
                        properties.Headers              = new Dictionary <string, Object>();
                        properties.Headers["x-eventId"] = Events[eventIndex].EventId;
                        properties.Headers["x-traceId"] = Events[eventIndex].TraceId;
                        using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Publish"))
                        {
                            tracer.SetComponent(_compomentName);
                            tracer.SetTag("x-messageId", MessageId);
                            tracer.SetTag("x-eventId", Events[eventIndex].EventId);
                            tracer.SetTag("x-traceId", Events[eventIndex].TraceId);
                            _logger.LogInformation(json);

                            foreach (var key in Events[eventIndex].Headers.Keys)
                            {
                                if (!properties.Headers.ContainsKey(key))
                                {
                                    properties.Headers.Add(key, Events[eventIndex].Headers[key]);
                                }
                            }

                            if (Events[eventIndex].Headers.ContainsKey("x-first-death-queue"))
                            {
                                //延时队列或者直接写死信的情况
                                var newQueue = Events[eventIndex].Headers["x-first-death-queue"].ToString();

                                //创建一个队列
                                channel.QueueDeclare(
                                    queue: newQueue,
                                    durable: true,
                                    exclusive: false,
                                    autoDelete: false,
                                    arguments: Events[eventIndex].Headers);

                                batchPublish.Add(
                                    exchange: "",
                                    mandatory: true,
                                    routingKey: newQueue,
                                    properties: properties,
                                    body: bytes);
                            }
                            else
                            {
                                //发送到正常队列
                                batchPublish.Add(
                                    exchange: _exchange,
                                    mandatory: true,
                                    routingKey: routeKey,
                                    properties: properties,
                                    body: bytes);
                            }
                        }

                        return(Task.FromResult(true));
                    }, cancellationToken);
                }

                //批量提交
                batchPublish.Publish();

                if (confirm)
                {
                    return(channel.WaitForConfirms(TimeSpan.FromMilliseconds(_senderConfirmTimeoutMillseconds)));
                }
                else
                {
                    return(true);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                throw ex;
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// 订阅消息(同一类消息可以重复订阅)
        /// 作者:郭明
        /// 日期:2017年4月3日
        /// </summary>
        /// <typeparam name="TD"></typeparam>
        /// <typeparam name="TH"></typeparam>
        /// <param name="EventTypeName">消息类型名称</param>
        /// <returns></returns>
        public IEventBus RegisterBatch <TD, TH>(string QueueName, string EventTypeName = "", int BatchSize = 50, CancellationToken cancellationToken = default(CancellationToken))
            where TD : class
            where TH : IEventBatchHandler <TD>
        {
            var persistentConnection = _receiveLoadBlancer.Lease();
            var queueName            = string.IsNullOrEmpty(QueueName) ? typeof(TH).FullName : QueueName;
            var routeKey             = string.IsNullOrEmpty(EventTypeName) ? typeof(TD).FullName : EventTypeName;
            var eventAction          = _lifetimeScope.GetService(typeof(TH)) as IEventBatchHandler <TD>;

            if (eventAction == null)
            {
                eventAction = System.Activator.CreateInstance(typeof(TH)) as IEventBatchHandler <TD>;
            }

            for (int i = 0; i < _reveiverMaxDegreeOfParallelism; i++)
            {
                System.Threading.Tasks.Task.Run(async() =>
                {
                    try
                    {
                        var consumer = persistentConnection.GetConsumer();
                        consumer.Subscribe(routeKey);

                        while (true)
                        {
                            var handlerSuccess   = false;
                            var handlerException = default(Exception);
                            var eas      = consumer.ConsumeBatch(TimeSpan.FromSeconds(5), BatchSize, cancellationToken);
                            var Messages = new EventResponse[eas.Count()];

                            try
                            {
                                foreach (var ea in eas)
                                {
                                    // 消息队列空
                                    if (ea.IsPartitionEOF)
                                    {
                                        _logger.LogDebug("Reached end of topic {consumeResult.Topic}, partition {consumeResult.Partition}, offset {consumeResult.Offset}.");

                                        continue;
                                    }

                                    var EventId   = -1L;
                                    var MessageId = ea.Key;
                                    var TraceId   = MessageId;

                                    using (var tracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Received", TraceId))
                                    {
                                        #region 消息Header处理
                                        if (ea.Headers != null)
                                        {
                                            try
                                            {
                                                long.TryParse(System.Text.Encoding.UTF8.GetString(ea.Headers.GetLastBytes("x-eventId")), out EventId);
                                            }
                                            catch
                                            { }


                                            try
                                            {
                                                TraceId = System.Text.Encoding.UTF8.GetString(ea.Headers.GetLastBytes("x-traceId"));
                                            }
                                            catch
                                            {
                                            }
                                        }
                                        #endregion

                                        #region AMQP Received
                                        try
                                        {
                                            tracer.SetComponent(_compomentName);
                                            tracer.SetTag("queueName", queueName);
                                            tracer.SetTag("x-messageId", MessageId);
                                            tracer.SetTag("x-eventId", EventId);
                                            tracer.SetTag("x-traceId", TraceId);

                                            var eventResponse = new EventResponse()
                                            {
                                                EventId    = EventId,
                                                MessageId  = MessageId,
                                                TraceId    = TraceId,
                                                Headers    = new Dictionary <string, object>(),
                                                Body       = default(TD),
                                                QueueName  = queueName,
                                                RouteKey   = routeKey,
                                                BodySource = ea.Value
                                            };


                                            try
                                            {
                                                foreach (var key in ea.Headers)
                                                {
                                                    eventResponse.Headers.Add(key.Key, Encoding.UTF8.GetString(key.GetValueBytes()));
                                                }

                                                eventResponse.Body = JsonConvert.DeserializeObject <TD>(eventResponse.BodySource);
                                                _logger.LogInformation(eventResponse.BodySource);
                                            }
                                            catch (Exception ex)
                                            {
                                                _logger.LogError(ex, ex.Message);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            tracer.SetError();
                                            _logger.LogError(ex.Message, ex);
                                        }
                                        #endregion
                                    }
                                }

                                if (Messages != null && Messages.Any())
                                {
                                    using (var executeTracer = new Hummingbird.Extensions.Tracing.Tracer("AMQP Execute"))
                                    {
                                        executeTracer.SetComponent(_compomentName);

                                        handlerSuccess = await _receiverPolicy.ExecuteAsync(async(handlerCancellationToken) =>
                                        {
                                            return(await eventAction.Handle(Messages.Select(a => (TD)a.Body).ToArray(), Messages.Select(a => (Dictionary <string, object>)a.Headers).ToArray(), handlerCancellationToken));
                                        }, cancellationToken);

                                        if (handlerSuccess)
                                        {
                                            #region 消息处理成功
                                            if (_subscribeAckHandler != null && Messages.Length > 0)
                                            {
                                                _subscribeAckHandler(Messages);
                                            }

                                            consumer.Commit();

                                            #endregion
                                        }
                                        else
                                        {
                                            executeTracer.SetError();
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError(ex, ex.Message);
                            }
                            finally
                            {
                                if (!handlerSuccess)
                                {
                                    //重新入队,默认:是
                                    var requeue = true;

                                    try
                                    {
                                        //执行回调,等待业务层的处理结果
                                        if (_subscribeNackHandler != null)
                                        {
                                            requeue = await _subscribeNackHandler((Messages, handlerException));
                                        }
                                    }
                                    catch (Exception innterEx)
                                    {
                                        _logger.LogError(innterEx, innterEx.Message);
                                    }

                                    if (!requeue)
                                    {
                                        consumer.Commit();
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, ex.Message);
                    }
                });
            }

            return(this);
        }