簡體   English   中英

兔子 MQ 隊列

[英]Rabbit MQ Queues

我有一個隊列發布者和一百個隊列訂閱者。 訂閱者綁定到一個隊列。 Rabbit 的指南說 Rabbit 為每個隊列創建單個線程。 我想通過一個隊列將所有消息發送給訂閱者,如果目標訂閱者離線,則將所有未發送的消息保存在同一個隊列中。 我有兩個解決方案:

  1. 通過聲明交換類型“Direct”並綁定到一個 QueueName,我可以通過一個隊列將所有消息發送給所有訂閱者。 但是如果發布消息中的routingKey不等於隊列名,那么如果直接消費者離線,它就不會保存在隊列中。

訂閱者的代碼

        static void Main(string[] args)
        {
            List<string> serevities1 = new List<string>() { "qwerty.red" };
            List<string> serevities2 = new List<string>() { "asdfgh.green" };
            string exchange = "topic_logs";

            //string direction = ExchangeType.Topic;
            string direction = ExchangeType.Direct;
            var consumer1 = new MqDll.MqConsumer(exchange, direction, serevities1);
            MqDll.MqConsumer consumer2;
            Task.Run(() => {
                Thread.Sleep(10000);
                consumer2 = new MqDll.MqConsumer(exchange, direction, serevities2);
            });
            Console.ReadLine();
        }
public class MqConsumer
    {
        private IConnection connection;
        private IModel channel;
        //ExchangeType.Fanout
        public MqConsumer(string exchange, string direction, List<string> severities = null)
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            connection = factory.CreateConnection();
            channel = connection.CreateModel();
            channel.ExchangeDeclare(exchange, direction);
            string queueName = "task_queue";
            // queueName= channel.QueueDeclare().QueueName;
            channel.QueueDeclare(queue: queueName,
                      durable: true,
                      exclusive: false,
                      autoDelete: false,
                      arguments: null);
            Bind(queueName, exchange, severities);
            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += MsgReceived;
            channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);
            Console.WriteLine("Consumer created");
        }
        ~MqConsumer()
        {
            channel.Close();
            connection.Close();
        }
        private void Bind(string queuename, string exchange, List<string> severities)
        {
            if (severities != null)
            {
                severities.ForEach(x =>
                {
                    channel.QueueBind(queue: queuename,
                                      exchange: exchange,
                                      routingKey: x);
                });
            }
            else
            {
                channel.QueueBind(queue: queuename,
                                  exchange: exchange,
                                  routingKey: "");
            }
        }
        private  void MsgReceived(object model, BasicDeliverEventArgs ea)
        {
            var body = ea.Body.ToArray();
            var message = Encoding.UTF8.GetString(body);
            var rkey = ea.RoutingKey;
            Console.WriteLine($" [x] Received {message} {rkey}");            
            Console.WriteLine($" [x] Done {DateTime.Now} | {this.GetHashCode()}");
        }
    }

出版商代碼

static void Main(string[] args)
        {
            List<string> serevities = new List<string>() { "qwerty.red", "asdfgh.green" };
            string exchange = "topic_logs";

            //string direction = ExchangeType.Topic;
            string direction = ExchangeType.Direct;
            var publisher = new MqDll.MqPublisher(exchange, direction);
            Console.WriteLine("Publisher created");
            var msg = Console.ReadLine();
            while (msg != "q")
            {
                serevities.ForEach(x =>
                {
                    publisher.Publish("SomeMsg..", "topic_logs", x);
                });
                msg = Console.ReadLine();
            }

        }
 public class MqPublisher
    {
        private IConnection connection;
        private IModel channel;
        public MqPublisher(string exchange, string type)
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            connection = factory.CreateConnection();
            channel = connection.CreateModel();

            channel.QueueDeclare(queue: "task_queue",
                                 durable: true,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null);
            channel.ExchangeDeclare(exchange, type);
        }
        ~MqPublisher()
        {
            channel.Close();
            connection.Close();
        }
        public void Publish(string msg, string exchange = "logs", string severity = "", bool isPersistent = true)
        {
            var properties = channel.CreateBasicProperties();
            properties.Persistent = isPersistent;
            channel.BasicPublish(exchange: exchange,
                                 routingKey: severity,
                                 basicProperties: properties,
                                 body: Encoding.UTF8.GetBytes(msg));
            Console.WriteLine(" [x] Sent {0}", msg);
        }
    }
  1. 或者我可以為每個訂閱者創建隊列並刪除綁定。 源代碼很簡單,相當於giude中的代碼。

有沒有辦法將這兩種解決方案結合起來,為所有訂閱者創建一個隊列,將訂閱者綁定到唯一的路由鍵並在直接訂閱者(綁定到直接路由鍵)離線時保存消息?

您是否考慮過為不在線的用戶提供數據庫..

隊列 => 消費者離線 => 發送到數據庫 消費者在線 => 發布者檢查數據庫是否有任何可能丟失的消息 => 然后將它們定向到消費者

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM