/// <summary> 定义并绑定队列 </summary> /// <param name="queue"></param> /// <param name="key"></param> /// <param name="option"></param> private void DeclareAndBindQueue(string queue, string key, RabbitMqSubscribeOption option) { var exchange = string.IsNullOrWhiteSpace(option.Exchange) ? _brokerName : option.Exchange; _consumerChannel.ExchangeDeclare(exchange, option.ExchangeType, option.Durable); if (option.EnableXDead) { _consumerChannel.DeclareWithDlx(queue, exchange, key, option); } }
/// <summary> 接收消息 </summary> /// <param name="queue">队列</param> /// <param name="ea"></param> /// <param name="option"></param> /// <returns></returns> private async Task ReceiveMessage(string queue, BasicDeliverEventArgs ea, RabbitMqSubscribeOption option) { try { await SubscriptionManager.ProcessEvent(queue, ea.Body.ToArray()); _consumerChannel.BasicAck(ea.DeliveryTag, false); } catch (Exception ex) { //非业务异常,可重新入队 if (ex.GetBaseException() is BusiException busi) { //拒收,不重新入列 _consumerChannel.BasicNack(ea.DeliveryTag, false, false); _logger.LogWarning($"{queue},busi:{busi.Message}"); RemoteLog(queue, ea.Body.ToArray(), busi); return; } _logger.LogError(ex, ex.Message); if (!option.EnableRetry) { _consumerChannel.BasicNack(ea.DeliveryTag, false, false); return; } var maxTime = option.Times.Length; var times = 0; if (ea.BasicProperties.Headers != null && ea.BasicProperties.Headers.TryGetValue(DelayTimesKey, out var t)) { times = t.CastTo(0); } if (times >= maxTime) { //拒收,不重新入列 _consumerChannel.BasicNack(ea.DeliveryTag, false, false); _logger.LogWarning($"{queue},retry times > {maxTime}"); return; } //延时入列 times++; var delay = option.Times[times - 1]; _consumerChannel.BasicAck(ea.DeliveryTag, false); if (!_connection.IsConnected) { _connection.TryConnect(); } using (var channel = _connection.CreateModel()) { var prop = _consumerChannel.CreateBasicProperties(); prop.DeliveryMode = 2; prop.Headers = prop.Headers ?? new Dictionary <string, object>(); prop.Headers.Add(DelayTimesKey, times); //绑定队列路由 channel.QueueBind(queue, _brokerName, queue); channel.DelayPublish(_brokerName, queue, ea.Body.ToArray(), delay, prop); } } }