예제 #1
0
        public void Init(IRabbitMQClient client)
        {
            var isOnce = QueueCount == 1;

            if (isOnce)
            {
                models.Add(Queue, client.PullModel().GetAwaiter().GetResult());
            }
            else
            {
                nodeList = new List <string>();
                for (int i = 0; i < QueueCount; i++)
                {
                    var queue = $"{ Queue}_{i}";
                    nodeList.Add(queue);
                    if (!models.ContainsKey(queue))
                    {
                        models.Add(queue, client.PullModel().GetAwaiter().GetResult());
                    }
                }
                _CHash = new ConsistentHash(nodeList, QueueCount * 10);
            }
            //申明exchange
            client.ExchangeDeclare(Exchange).Wait();
            Client = client;
        }
예제 #2
0
        private async Task StartSub(ConsumerInfo consumer, bool first)
        {
            var child = new ConsumerChild
            {
                Channel = await client.PullModel(),
                Qos     = consumer.MinQos
            };

            if (first)
            {
                child.Channel.Model.ExchangeDeclare(consumer.Exchange, "direct", true);
                child.Channel.Model.QueueDeclare(consumer.Queue, true, false, false, null);
                child.Channel.Model.QueueBind(consumer.Queue, consumer.Exchange, consumer.RoutingKey);
            }
            child.Channel.Model.BasicQos(0, consumer.MinQos, false);

            child.BasicConsumer           = new EventingBasicConsumer(child.Channel.Model);
            child.BasicConsumer.Received += async(ch, ea) =>
            {
                await Process(consumer, child, ea, 0);
            };
            child.BasicConsumer.ConsumerTag = child.Channel.Model.BasicConsume(consumer.Queue, consumer.AutoAck, child.BasicConsumer);
            child.NeedRestart = false;
            consumer.Children.Add(child);
            consumer.NowQos   += child.Qos;
            consumer.StartTime = DateTime.UtcNow;
        }
예제 #3
0
        public async Task Start(List <ConsumerInfo> consumerList)
        {
            if (consumerList != null)
            {
                var channel = await client.PullModel();

                for (int i = 0; i < consumerList.Count; i++)
                {
                    var consumer = consumerList[i];
                    consumer.Channel = channel;
                    channel.Model.ExchangeDeclare(consumer.Exchange, "direct", true);
                    channel.Model.QueueDeclare(consumer.Queue, true, false, false, null);
                    channel.Model.QueueBind(consumer.Queue, consumer.Exchange, consumer.RoutingKey);
                    consumer.BasicConsumer           = new EventingBasicConsumer(consumer.Channel.Model);
                    consumer.BasicConsumer.Received += (ch, ea) =>
                    {
                        try
                        {
                            consumer.Handler.Notice(ea.Body).ContinueWith(t =>
                            {
                                if (t.Exception == null && !t.IsCanceled)
                                {
                                    consumer.Channel.Model.BasicAck(ea.DeliveryTag, false);
                                }
                                else if (t.Exception != null)
                                {
                                    throw t.Exception;
                                }
                                else if (t.IsCanceled)
                                {
                                    throw new Exception("Message processing timeout");
                                }
                            }).GetAwaiter().GetResult();
                        }
                        catch (Exception exception)
                        {
                            //需要记录错误日志
                            var e = exception.InnerException ?? exception;
                            logger.LogError(e, $"An error occurred in {consumer.Exchange}-{consumer.Queue}");
                            ReStart(consumer);//重启队列
                        }
                    };
                    consumer.BasicConsumer.ConsumerTag = consumer.Channel.Model.BasicConsume(consumer.Queue, false, consumer.BasicConsumer);
                    if (i % 4 == 0 && i != 0)
                    {
                        channel = await client.PullModel();
                    }
                    if (!ConsumerAllList.Contains(consumer))
                    {
                        ConsumerAllList.Add(consumer);
                    }
                }
            }
        }
예제 #4
0
 public async ValueTask <ModelWrapper> PullModel(string route)
 {
     if (!modelDict.TryGetValue(route, out var model))
     {
         var pullTask = rabbitMQClient.PullModel();
         if (!pullTask.IsCompletedSuccessfully)
         {
             await pullTask;
         }
         if (!modelDict.TryAdd(route, pullTask.Result))
         {
             pullTask.Result.Dispose();
         }
         model = pullTask.Result;
     }
     else if (model.Model.IsClosed)
     {
         if (modelDict.TryRemove(route, out var value))
         {
             value.Dispose();
         }
         var pullTask = PullModel(route);
         if (!pullTask.IsCompletedSuccessfully)
         {
             await pullTask;
         }
         return(pullTask.Result);
     }
     return(model);
 }
예제 #5
0
        private async Task StartSub(ConsumerInfo consumer)
        {
            consumer.NeedRestart = false;
            consumer.Channel     = await client.PullModel();

            consumer.Channel.Model.ExchangeDeclare(consumer.Exchange, "direct", true);
            consumer.Channel.Model.QueueDeclare(consumer.Queue, true, false, false, null);
            consumer.Channel.Model.BasicQos(0, 100, false);
            consumer.Channel.Model.QueueBind(consumer.Queue, consumer.Exchange, consumer.RoutingKey);

            consumer.BasicConsumer           = new EventingBasicConsumer(consumer.Channel.Model);
            consumer.BasicConsumer.Received += async(ch, ea) =>
            {
                try
                {
                    await consumer.Handler.Notice(ea.Body);

                    if (!consumer.AutoAck)
                    {
                        consumer.Channel.Model.BasicAck(ea.DeliveryTag, false);
                    }
                }
                catch (Exception exception)
                {
                    //需要记录错误日志
                    logger.LogError(exception.InnerException ?? exception, $"An error occurred in {consumer.Exchange}-{consumer.Queue}");
                    consumer.NeedRestart = true;
                }
            };
            consumer.BasicConsumer.ConsumerTag = consumer.Channel.Model.BasicConsume(consumer.Queue, consumer.AutoAck, consumer.BasicConsumer);
        }
예제 #6
0
        private async Task StartSub(ConsumerInfo consumer, bool expand = false)
        {
            if (expand && consumer.NowQos == consumer.MaxQos)
            {
                return;
            }
            if (consumer.BasicConsumer != null)
            {
                consumer.Close();
            }
            consumer.Channel = await client.PullModel();

            if (consumer.NowQos == 0)
            {
                consumer.Channel.Model.ExchangeDeclare(consumer.Exchange, "direct", true);
                consumer.Channel.Model.QueueDeclare(consumer.Queue, true, false, false, null);
                consumer.Channel.Model.QueueBind(consumer.Queue, consumer.Exchange, consumer.RoutingKey);
            }
            consumer.NowQos = expand ? (ushort)(consumer.NowQos + startQos) : startQos;
            if (consumer.NowQos > consumer.MaxQos)
            {
                consumer.NowQos = consumer.MaxQos;
            }

            consumer.Channel.Model.BasicQos(0, consumer.NowQos, false);

            consumer.BasicConsumer           = new EventingBasicConsumer(consumer.Channel.Model);
            consumer.BasicConsumer.Received += async(ch, ea) =>
            {
                await Process(consumer, ea, 0);
            };
            consumer.BasicConsumer.ConsumerTag = consumer.Channel.Model.BasicConsume(consumer.Queue, consumer.AutoAck, consumer.BasicConsumer);
            consumer.StartTime   = DateTime.UtcNow;
            consumer.NeedRestart = false;
        }
예제 #7
0
 public async Task Work(RabbitEventBus bus)
 {
     eventBusDictionary.TryAdd(bus.ProducerType, bus);
     eventBusList.Add(bus);
     using (var channel = await rabbitMQClient.PullModel())
     {
         channel.Model.ExchangeDeclare(bus.Exchange, "direct", true);
     }
 }
예제 #8
0
 private async Task InitModel(ConsumerInfo consumer)
 {
     if (consumer.Channel == default)
     {
         consumer.Channel = await client.PullModel();
     }
     else
     {
         if (consumer.Channel.Model.IsClosed)
         {
             consumer.Channel.Dispose();
             consumer.Channel = await client.PullModel();
         }
         else
         {
             return;
         }
     }
     consumer.Channel.Model.ExchangeDeclare(consumer.Exchange, "direct", true);
     consumer.Channel.Model.QueueDeclare(consumer.Queue, true, false, false, null);
     consumer.Channel.Model.QueueBind(consumer.Queue, consumer.Exchange, consumer.RoutingKey);
 }
예제 #9
0
        public async Task Work(RabbitEventBus bus)
        {
            if (eventBusDictionary.TryAdd(bus.ProducerType, bus))
            {
                eventBusList.Add(bus);
                using var channel = await rabbitMQClient.PullModel();

                channel.Model.ExchangeDeclare(bus.Exchange, "direct", true);
            }
            else
            {
                throw new EventBusRepeatException(bus.ProducerType.FullName);
            }
        }
예제 #10
0
        private async Task Init(IRabbitMQClient client)
        {
            var isOnce = QueueCount == 1;

            if (isOnce)
            {
                var pullTask = client.PullModel();
                if (!pullTask.IsCompleted)
                {
                    await pullTask;
                }
                models.Add(Queue, pullTask.Result);
            }
            else
            {
                var nodeList = new List <string>();
                for (int i = 0; i < QueueCount; i++)
                {
                    var queue = $"{ Queue}_{i}";
                    nodeList.Add(queue);
                    if (!models.ContainsKey(queue))
                    {
                        var pullTask = client.PullModel();
                        if (!pullTask.IsCompleted)
                        {
                            await pullTask;
                        }
                        models.Add(queue, pullTask.Result);
                    }
                }
                _CHash = new ConsistentHash(nodeList, QueueCount * 10);
            }
            //申明exchange
            await client.ExchangeDeclare(Exchange);

            Client = client;
        }
예제 #11
0
 public ValueTask Publish(byte[] bytes, string hashKey)
 {
     using var model = rabbitMQClient.PullModel();
     model.Publish(bytes, publisher.Exchange, publisher.GetRoute(hashKey), publisher.Persistent);
     return(Consts.ValueTaskDone);
 }