Beispiel #1
0
        public IConsumer GetConsumer(string queueName)
        {
            if (string.IsNullOrWhiteSpace(queueName))
            {
                throw new ArgumentNullException(nameof(queueName));
            }

            var channel = CurrentConnection.CreateModel();

            return(new Consumer(channel, queueName));
        }
Beispiel #2
0
        public IPublisher GetPublisher(string exchangeName)
        {
            if (string.IsNullOrWhiteSpace(exchangeName))
            {
                throw new ArgumentNullException(nameof(exchangeName));
            }

            var channel = CurrentConnection.CreateModel();

            return(new Publisher(channel, exchangeName));
        }
Beispiel #3
0
        public void DeclareExchange(string exchangeName, string exchangeType)
        {
            if (string.IsNullOrWhiteSpace(exchangeName))
            {
                throw new ArgumentNullException(nameof(exchangeName));
            }

            using (var channel = CurrentConnection.CreateModel())
            {
                channel.ExchangeDeclare(exchangeName.ToLowerInvariant(), exchangeType, this.Durable);
            }
        }
Beispiel #4
0
 public RabbitMQConnectionFactory(IConnectionFactory connectionFactory)
 {
     _connectionFactory = connectionFactory;
     _lazyConnection    = new Lazy <IConnection>(
         () => _connectionFactory.CreateConnection(),
         LazyThreadSafetyMode.ExecutionAndPublication
         );
     _lazyChannel = new Lazy <IModel>(
         () => CurrentConnection.CreateModel(),
         LazyThreadSafetyMode.ExecutionAndPublication
         );
 }
Beispiel #5
0
        public void DeclareQueue(string queueName, Dictionary <string, object> queueArgs)
        {
            if (string.IsNullOrWhiteSpace(queueName))
            {
                throw new ArgumentNullException(nameof(queueName));
            }
            if (queueArgs == null)
            {
                throw new ArgumentNullException(nameof(queueArgs));
            }

            using (var channel = CurrentConnection.CreateModel())
            {
                channel.QueueDeclare(queueName.ToLowerInvariant(), this.Durable, false, this.AutoDeleteQueue, queueArgs);
            }
        }
        /// <summary>
        /// 异步方式启动Channel,
        /// todo: 1.需要考虑Connection出现问题如何处理, 2. Connection不稳定会怎么样
        /// </summary>
        /// <returns></returns>
        private async Task StartChannel()
        {
            var rabbitmqConnectRetryPolicy = Policy
                                             .Handle <BrokerUnreachableException>()
                                             .WaitAndRetryForeverAsync((retryAttempt) =>
            {
                return(TimeSpan.FromSeconds(5));
            }, (exception, retryAttempt, timespan) =>
            {
                _logger.LogError($"连接RabbitMq[{ConnectionSetting.HostName}{ConnectionSetting.VHost}]失败, {timespan.TotalSeconds}秒后进行第{retryAttempt}次重试");
            });

            await rabbitmqConnectRetryPolicy.ExecuteAsync(async cancellationToke =>
            {
                _logger.LogWarning("尝试连接RabbitMQ");
                CurrentConnection = GetConnectionFac().CreateConnection($"miaoapi-{SessionName}_ClientPool-{Environment.MachineName}");

                CurrentConnection.RecoverySucceeded += (s, e) =>
                {
                    _logger.LogWarning($"RabbitMQ连接已恢复");
                };
                CurrentConnection.ConnectionRecoveryError += (s, e) =>
                {
                    _logger.LogWarning($"RabbitMQ连接尝试恢复错误, {e.Exception.FullMessage()}");
                };
                CurrentConnection.ConnectionShutdown += (s, e) =>
                {
                    _logger.LogWarning($"RabbitMQ连接已断开, {e.ReplyCode} {e.ReplyText}");
                };
                _logger.LogWarning("RabbitMQ连接成功");

                var CurrentConsumerChannel = CurrentConnection.CreateModel();
                BindCurrentQueueToExchange(CurrentConsumerChannel);

                var currentConsumer                = new EventingBasicConsumer(CurrentConsumerChannel);
                currentConsumer.Received          += ConsumerReceiveHandler;
                currentConsumer.Shutdown          += (s, e) => { _logger.LogWarning($"RabbitMQ Consumer Channel Shutdown Event"); };
                currentConsumer.ConsumerCancelled += (s, e) => { _logger.LogWarning($"RabbitMQ Consumer Channel ConsumerCancelled Event"); };
                currentConsumer.Registered        += (s, e) => { _logger.LogWarning($"RabbitMQ Consumer Channel Registered Event"); };
                currentConsumer.Unregistered      += (s, e) => { _logger.LogWarning($"RabbitMQ Consumer Channel Unregistered Event "); };
                CurrentConsumerChannel.BasicQos(0, PrefetchCount, false);
                CurrentConsumerChannel.BasicConsume(queue: QueueName, autoAck: false, consumer: currentConsumer);

                await Task.CompletedTask;
            }, CancellationToken);
        }
Beispiel #7
0
        public void CancelBinding(string exchangeName, string queueName, string routingKey)
        {
            if (string.IsNullOrWhiteSpace(exchangeName))
            {
                throw new ArgumentNullException(nameof(exchangeName));
            }
            if (string.IsNullOrWhiteSpace(queueName))
            {
                throw new ArgumentNullException(nameof(queueName));
            }
            if (string.IsNullOrWhiteSpace(routingKey))
            {
                throw new ArgumentNullException(nameof(routingKey));
            }

            using (var channel = CurrentConnection.CreateModel())
            {
                channel.QueueUnbind(queueName.ToLowerInvariant(), exchangeName.ToLowerInvariant(), routingKey.ToLowerInvariant());
            }
        }
Beispiel #8
0
        public void DeclareBinding(string exchangeName, string queueName, string routingKey, Dictionary <string, object> headerBindings)
        {
            if (string.IsNullOrWhiteSpace(exchangeName))
            {
                throw new ArgumentNullException(nameof(exchangeName));
            }
            if (string.IsNullOrWhiteSpace(queueName))
            {
                throw new ArgumentNullException(nameof(queueName));
            }
            if (string.IsNullOrWhiteSpace(routingKey))
            {
                throw new ArgumentNullException(nameof(routingKey));
            }

            using (var channel = CurrentConnection.CreateModel())
            {
                channel.QueueBind(queueName.ToLowerInvariant(), exchangeName.ToLowerInvariant(), routingKey.ToLowerInvariant(), headerBindings);
            }
        }
        private async Task FlushErrorData()
        {
            DateTime lastNotifyTime = DateTime.Now.AddMinutes(-1);
            //消费错误消息,2秒检查一次
            var sleepTimespan = TimeSpan.FromMilliseconds(2000);

            while (true)
            {
                if (_unsentErrorMessages.Count > 0)
                {
                    var isDisconnected = !CurrentConnection?.IsOpen ?? true;

                    if (isDisconnected && (lastNotifyTime - DateTime.Now).TotalSeconds >= 30)
                    {
                        lastNotifyTime = DateTime.Now;
                        _logger.LogWarning($"RabbitMq 连接状态为 未开启");

                        ErrorMessageBufferCheckAndClean();
                    }
                }

                List <Tuple <byte[], IBasicProperties, string> > batchPublishBuffer = new List <Tuple <byte[], IBasicProperties, string> >();
                while (_unsentErrorMessages.Count > 0 && CurrentConnection != null && CurrentConnection.IsOpen)
                {
                    if (!_unsentErrorMessages.TryDequeue(out var tuple))
                    {
                        continue;
                    }

                    batchPublishBuffer.Add(tuple);

                    if (batchPublishBuffer.Count >= 20)
                    {
                        break;
                    }
                }

                try
                {
                    if (batchPublishBuffer.Count > 0)
                    {
                        using (var errorChannel = CurrentConnection.CreateModel())
                        {
                            var basicBashPublisher = errorChannel.CreateBasicPublishBatch();
                            foreach (var item in batchPublishBuffer)
                            {
                                basicBashPublisher.Add(Consts.ERROR_EXCHANGE, item.Item3, true, item.Item2, item.Item1);
                            }
                            basicBashPublisher.Publish();
                            batchPublishBuffer.Clear();

                            //安全关闭Channel
                            errorChannel.Close();
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError($"MessageConsumer FlushData Exception: ExType:{ex.FullExType()}, Msg:{Environment.NewLine}{ex.FullMessage()}{Environment.NewLine}{ex.FullStacktrace()}");
                }

                await Task.CompletedTask;
                Thread.Sleep(sleepTimespan);//休眠1秒之后继续尝试连接
            }
        }