RABBITMQ

 

  1. 连接(Connection): 连接是消息队列客户端与消息代理(如 RabbitMQ、Kafka 等)之间的网络连接。当客户端应用程序需要与消息代理进行通信时,首先需要建立一个连接。连接是一个低开销的资源,应尽量重用,以避免频繁地建立和断开连接。一个连接可以同时支持多个通道。

  2. 通道(Channel): 通道是在连接中创建的虚拟信道,用于进行实际的消息传递操作。通道允许在不同的信道上进行并发的消息操作,而不需要建立多个物理连接。通过使用通道,可以更有效地管理资源,并减少开销。通道还允许在同一连接中执行多个操作,如声明队列、发布消息、订阅消息等。

  3. 队列(Queue): 队列是消息的存储和传递的地方。消息被发布到队列中,然后订阅者可以从队列中获取消息并进行处理。队列是一种先进先出(FIFO)的数据结构,确保消息按照顺序被处理。消息可以在队列中暂存,直到订阅者准备好处理它们。

using System;
using System.Text;
using RabbitMQ.Client;

namespace BasicQueueProducer
{
  class Program
  {
      static void Main(string[] args)
      {
          var factory = new ConnectionFactory() { HostName = "localhost" };
           
          using (var connection = factory.CreateConnection())
          using (var channel = connection.CreateModel())
          {
              channel.QueueDeclare(queue: "basic_queue",
                                    durable: false,
                                    exclusive: false,
                                    autoDelete: false,
                                    arguments: null);

              string message = "Hello, RabbitMQ!";
              var body = Encoding.UTF8.GetBytes(message);

              channel.BasicPublish(exchange: "",
                                    routingKey: "", // No routingKey needed
                                    basicProperties: null,
                                    body: body);

              Console.WriteLine(" [x] Sent {0}", message);
          }

          Console.WriteLine(" Press [enter] to exit.");
          Console.ReadLine();
      }
  }
}
using System;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace BasicQueueConsumer
{
  class Program
  {
      static void Main(string[] args)
      {
          var factory = new ConnectionFactory() { HostName = "localhost" };
          using (var connection = factory.CreateConnection())
          using (var channel = connection.CreateModel())
          {
              channel.QueueDeclare(queue: "basic_queue",
                                    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: "basic_queue", autoAck: true, consumer: consumer);

              Console.WriteLine(" Press [enter] to exit.");
              Console.ReadLine();
          }
      }
  }
}
channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
string message = "Hello, subscribers!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "logs",routingKey: "", basicProperties: null, body: body);
channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,exchange: "logs",routingKey: "");
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: queueName, autoAck: true, consumer: consumer);
channel.ExchangeDeclare(exchange: "direct_logs", type: ExchangeType.Direct);
string message = "Hello, direct exchange!";
var body = Encoding.UTF8.GetBytes(message);
string routingKey = "error";
channel.BasicPublish(exchange: "direct_logs",routingKey: routingKey,basicProperties: null,body: body);
channel.ExchangeDeclare(exchange: "direct_logs", type: ExchangeType.Direct);
var queueName = channel.QueueDeclare().QueueName;
string routingKey = "error"; // Specify the routing key to bind to
channel.QueueBind(queue: queueName,exchange: "direct_logs",routingKey: routingKey);
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: queueName, autoAck: true, consumer: consumer);

RabbitMQ 和 Kafka 都是流行的消息传递平台,但它们在设计和使用场景方面有一些不同。以下是 RabbitMQ 和 Kafka 的优劣势,以及它们不同的使用场景:

RabbitMQ: 优势:

  • 支持多种消息传递模式,包括点对点、发布订阅、RPC(远程过程调用)等。

  • 提供多种交换机类型,如直接、主题、扇出等,以及丰富的路由选项。

  • 简单易用,适合用于一般的消息传递需求。

  • 拥有丰富的插件和扩展,使得可以更容易地集成到各种应用中。

劣势:

  • 在高吞吐量和大规模数据处理方面可能不如 Kafka 高效。

  • 对于长时间的消息保留和持久化存储,可能会受限于性能。

适用场景:

  • 适用于实时通信、任务队列、日志收集等需求。

  • 当需要多样化的消息模式和交换机类型时,RabbitMQ 是一个良好的选择。

  • 对于小到中等规模的消息传递需求,以及简单的消息路由和分发。

Kafka: 优势:

  • 高吞吐量、低延迟,适合处理大量的实时数据流。

  • 能够持久化存储大规模的消息,支持长时间的消息保留。

  • 通过分区和副本机制,支持高可用性和故障恢复。

  • 适用于构建事件驱动架构和流处理应用。

劣势:

  • 相对于 RabbitMQ,配置和管理可能会稍显复杂。

  • 不如 RabbitMQ 支持多种消息模式,主要用于发布订阅和日志流式处理。

适用场景:

  • 适用于大规模数据流处理、事件驱动架构、日志流式处理等。

  • 当需要高吞吐量、低延迟和长时间的消息保留时,Kafka 是一个优秀的选择。

  • 对于构建实时流处理应用,Kafka 提供了强大的支持。

总之,选择 RabbitMQ 还是 Kafka 取决于您的应用需求和架构设计。如果您需要灵活的消息模式、交换机类型和适用于一般消息传递需求的平台,那么 RabbitMQ 可能更适合。如果您的重点在于处理大量的实时数据流、构建事件驱动架构或流处理应用,那么 Kafka 是更好的选择。最佳方案将取决于您的具体业务场景和性能需求。

 

在 RabbitMQ 中,确实是默认情况下,一条消息只会被消费者中的一个消费者消费一次。一旦消息被一个消费者消费,它就不再可用于其他消费者。

posted @ 2023-09-05 16:06  朦朦胧胧的月亮最美好  阅读(13)  评论(0编辑  收藏  举报