当前位置:首页 > 行业动态 > 正文

如何在C中有效利用消息队列?

C#中使用消息队列可以通过.NET内置的System.Messaging命名空间,或者使用第三方库如RabbitMQ、Azure Service Bus等。

在C#中使用消息队列,可以选择多种消息队列实现方式,如RabbitMQ、Microsoft Message Queue(MSMQ)等,下面将详细介绍如何使用这两种消息队列。

MSMQ(Microsoft Message Queuing)

安装与配置

1、安装

打开控制面板 -> 程序和功能 -> 启用或关闭Windows功能 -> 勾选“Microsoft Message Queue”,点击确定进行安装。

2、创建消息队列

 using System.Messaging;
   public void CreateMessageQueue()
   {
       string path = @".Private$myQueue";
       if (!MessageQueue.Exists(path))
       {
           MessageQueue.Create(path);
       }
   }

发送消息

1、发送字符串消息

如何在C中有效利用消息队列?

 public void SendMessage(string message)
   {
       string path = @".Private$myQueue";
       var mq = new MessageQueue(path);
       mq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
       mq.Send(message);
   }

2、发送二进制消息(如图像)

 public void SendImage(Image image)
   {
       string path = @".Private$myQueue";
       var mq = new MessageQueue(path);
       mq.Formatter = new BinaryMessageFormatter();
       mq.Send(image);
   }

接收消息

1、接收字符串消息

 public string ReceiveStringMessage()
   {
       string path = @".Private$myQueue";
       var mq = new MessageQueue(path);
       mq.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
       System.Messaging.Message msg = mq.Receive();
       return msg.Body.ToString();
   }

2、接收二进制消息

 public Image ReceiveImage()
   {
       string path = @".Private$myQueue";
       var mq = new MessageQueue(path);
       mq.Formatter = new BinaryMessageFormatter();
       System.Messaging.Message msg = mq.Receive();
       return (Image)msg.Body;
   }

RabbitMQ

安装与配置

1、安装:使用Docker部署RabbitMQ镜像。

如何在C中有效利用消息队列?

 mkdir -p /opt/lib/rabbitmq
   docker run -itd --name rabbitmq -p 5672:5672 -p 15672:15672 -v /opt/lib/rabbitmq:/var/lib/rabbitmq rabbitmq:3.12.8-management

2、创建队列

 using RabbitMQ.Client;
   using RabbitMQ.Client.Events;
   using System.Text;
   using System.IO;
   public class Send
   {
       public static void Main()
       {
           var factory = new ConnectionFactory() { HostName = "localhost" };
           using(var connection = factory.CreateConnection())
           using(var channel = connection.CreateModel())
           {
               channel.QueueDeclare(queue: "hello",
                   durable: false,
                   exclusive: false,
                   autoDelete: false,
                   arguments: null);
               string message = "Hello World!";
               var body = Encoding.UTF8.GetBytes(message);
               channel.BasicPublish(exchange: "",
                   routingKey: "hello",
                   basicProperties: null,
                   body: body);
               Console.WriteLine(" [x] Sent {0}", message);
           }
       }
   }

接收消息

1、接收消息

 public static void Main() {
       var factory = new ConnectionFactory() { HostName = "localhost" };
       using(var connection = factory.CreateConnection())
       using(var channel = connection.CreateModel())
       {
           channel.QueueDeclare(queue: "hello",
               durable: false,
               exclusive: false,
               autoDelete: false,
               arguments: null);
           var consumer = new EventingBasicConsumer(channel);
           consumer.Received += (model, ea) =>
           {
               var body = ea.Body.ToArray();
               var message = Encoding.UTF8.GetString(body);
               Console.WriteLine(" [x] Received {0}", message);
           };
           channel.BasicConsume(queue: "hello",
               autoAck: true,
               consumer: consumer);
           Console.WriteLine(" Press [enter] to exit.");
           Console.ReadLine();
       }
   }

FAQs

问题1:如何在多个客户端向同一个队列发送消息?

答:确保所有客户端都指向同一个队列路径,并使用相同的消息格式进行发送,对于RabbitMQ,所有客户端应连接到同一台服务器上的同一个队列名称,对于MSMQ,确保队列路径一致,并且消息体和格式化程序兼容。

问题2:如何处理消息队列中的消息丢失问题?

如何在C中有效利用消息队列?

答:为了确保消息不丢失,可以采取以下措施:

确保消息队列的持久化配置正确,这样即使RabbitMQ或MSMQ重启,消息也不会丢失。

使用事务或确认机制,确保消息在处理过程中不会丢失,在RabbitMQ中,可以使用channel.BasicAck方法手动确认消息已成功处理。

定期备份消息队列数据,以防止意外情况导致的数据丢失。

小编有话说

消息队列是现代分布式系统中不可或缺的一部分,它提供了异步通信的能力,使得不同系统之间的耦合度降低,提高了系统的可扩展性和可靠性,无论是选择MSMQ还是RabbitMQ,都需要根据具体的业务需求和技术栈来决定,在实际开发中,建议深入了解所选消息队列的特性和最佳实践,以便更好地发挥其优势。