C#中RabbitMQ的使用小结

 更新时间:2025年12月17日 11:25:14   作者:wangnaisheng  
RabbitMQ是一个开源的消息队列中间件,用于实现应用程序之间的异步通信,本文主要介绍了C#中RabbitMQ的使用小结,具有一定的参考价值,感兴趣的可以了解一下

一、RabbitMQ是什么?

RabbitMQ是一个开源的消息代理软件,实现了AMQP(高级消息队列协议),用来实现应用程序之间的异步通信。简单说,它就像一个"消息邮局",生产者把消息投递到"邮局",消费者从"邮局"取走消息。

RabbitMQ:企业级消息中间件

RabbitMQ是一个开源的消息队列中间件,作用是:

系统解耦:不同应用间通过消息传递通信,无需直接依赖 ✅ 异步处理:将耗时操作放入队列,提升系统响应速度 ✅ 流量削峰:在高并发场景下缓冲请求,避免系统崩溃 ✅ 高可用:支持镜像队列和仲裁队列,保证服务可用性

典型应用:电商平台用户注册后,通过RabbitMQ异步发送注册邮件和短信;电商大促时,用消息队列缓冲订单,避免下游系统被压垮。

RabbitMQ是用Erlang语言写的,但C#有很好的客户端库支持,特别适合企业级应用。

二、环境准备

2.1. 安装RabbitMQ服务器

  • Windows:下载安装RabbitMQ(官网下载),安装时记得同时安装Erlang
  • Linux:使用yum或apt安装,或者用Docker

重要提示:安装完成后,启用Web管理插件(rabbitmq-plugins enable rabbitmq_management),然后访问http://localhost:15672/,默认账号guest/guest

2.2. 安装C#客户端库

# 使用NuGet安装RabbitMQ.Client(官方客户端)
Install-Package RabbitMQ.Client
 
# 如果喜欢更简单的封装,可以安装EasyNetQ(基于RabbitMQ.Client)
Install-Package EasyNetQ

三、基础使用示例

3.1. 简单发布/订阅模式(使用RabbitMQ.Client)

发布者(Publisher)

using RabbitMQ.Client;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using (var connection = factory.CreateConnection())
        using (var channel = connection.CreateModel())
        {
            // 声明交换机(使用fanout类型,适合广播)
            channel.ExchangeDeclare(exchange: "logs", type: "fanout");
            
            // 发送消息
            string message = "Hello RabbitMQ from C#!";
            var body = Encoding.UTF8.GetBytes(message);
            
            channel.BasicPublish(exchange: "logs", 
                                routingKey: "", 
                                basicProperties: null, 
                                body: body);
            
            Console.WriteLine($" [x] Sent '{message}'");
        }
    }
}

订阅者(Consumer)

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

class Program
{
    static void Main(string[] args)
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using (var connection = factory.CreateConnection())
        using (var channel = connection.CreateModel())
        {
            // 声明相同交换机
            channel.ExchangeDeclare(exchange: "logs", type: "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 '{message}'");
            };
            
            channel.BasicConsume(queue: queueName,
                                autoAck: true,
                                consumer: consumer);
            
            Console.WriteLine(" [*] Waiting for messages. To exit press CTRL+C");
            Console.ReadLine();
        }
    }
}

四、高级特性

4.1. 持久化消息(确保消息不丢失)

重要:必须同时设置交换机、队列、消息为持久化,才能保证消息不丢失

// 发布者
channel.ExchangeDeclare(exchange: "persistent", type: "direct", durable: true);
channel.QueueDeclare(queue: "persistent_queue", durable: true);
channel.QueueBind(queue: "persistent_queue", exchange: "persistent", routingKey: "key");

var message = "Persistent message";
var body = Encoding.UTF8.GetBytes(message);
var properties = channel.CreateBasicProperties();
properties.Persistent = true; // 关键!设置为持久化

channel.BasicPublish(exchange: "persistent", 
                    routingKey: "key",
                    basicProperties: properties,
                    body: body);

4.2. 使用EasyNetQ简化代码

EasyNetQ是RabbitMQ.Client的封装,让代码更简洁:

// 安装EasyNetQ
// Install-Package EasyNetQ

using EasyNetQ;
using System;

class Program
{
    static void Main()
    {
        // 创建连接
        var bus = RabbitHutch.CreateBus("host=localhost");
        
        // 发布消息
        bus.Publish(new Message { Text = "Hello EasyNetQ!" });
        
        // 订阅消息
        bus.Subscribe<Message>("my-queue", message => 
        {
            Console.WriteLine($"Received: {message.Text}");
        });
        
        Console.WriteLine("Waiting for messages...");
        Console.ReadLine();
    }
}

五、实际应用场景

5.1.电商订单处理(解耦系统)

// 订单服务(生产者)
public void CreateOrder(Order order)
{
    // 处理订单逻辑...
    
    // 发布订单消息到RabbitMQ
    var bus = RabbitHutch.CreateBus("host=localhost");
    bus.Publish(new OrderCreatedEvent { OrderId = order.Id });
}

// 邮件服务(消费者)
bus.Subscribe<OrderCreatedEvent>("order-events", order => 
{
    // 发送确认邮件
    EmailService.SendOrderConfirmation(order.OrderId);
});

5.2.日志收集系统

// 日志服务(生产者)
public void Log(string message)
{
    var bus = RabbitHutch.CreateBus("host=localhost");
    bus.Publish(new LogMessage { Message = message, Timestamp = DateTime.UtcNow });
}

// 日志处理服务(消费者)
bus.Subscribe<LogMessage>("log-queue", log => 
{
    // 保存到数据库或文件
    LogRepository.Save(log);
});

六、专业建议

  • 连接管理:使用连接池,避免频繁创建连接

// 使用连接工厂创建连接
var factory = new ConnectionFactory { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
    // 用同一个连接创建多个channel
    using (var channel = connection.CreateModel())
    {
        // ...
    }
}
  • 错误处理:不要只检查连接状态,要处理所有可能的异常
try
{
    // 消息处理逻辑
}
catch (Exception ex)
{
    // 记录错误并重试
    Console.WriteLine($"处理消息失败: {ex.Message}");
}
  • 队列持久化:生产环境中,几乎所有的队列都应该是持久化的
channel.QueueDeclare(queue: "my-queue", 
                   durable: true, 
                   exclusive: false, 
                   autoDelete: false);
  • 消息确认:使用手动确认(manual acknowledgment)确保消息被正确处理
channel.BasicConsume(queue: "my-queue",
                   autoAck: false, // 关键!设置为false
                   consumer: consumer);

七、常见问题

Q: RabbitMQ和MQTT有什么区别? A: RabbitMQ是企业级消息中间件,适合应用间通信;MQTT是物联网专用轻量级协议,适合设备间通信。两者可以结合使用,例如用MQTT收集物联网设备数据,用RabbitMQ处理业务逻辑。

Q: 为什么我的消息不见了? A: 可能原因:

  1. 队列没有持久化
  2. 没有正确绑定交换机和队列
  3. 消费者没有正确订阅
  4. 交换机类型不匹配(如用direct交换机但用fanout方式发送)

Q: 如何监控RabbitMQ? A: 用Web管理界面(http://localhost:15672),或者用RabbitMQ的API进行监控。

八、其他类似中间件对比总结表

九、选择建议

  1. 如果你需要低延迟、简单路由 → 选RabbitMQ
  2. 如果你处理海量数据、日志收集 → 选Kafka
  3. 如果你需要顺序消息、电商场景 → 选RocketMQ
  4. 如果你需要多协议支持、复杂路由 → 选ActiveMQ
  5. 如果你追求极致速度、不关心数据丢失 → 选ZeroMQ
  6. 如果你做云原生应用、需要长期存储 → 选Pulsar

到此这篇关于C#中RabbitMQ的使用小结的文章就介绍到这了,更多相关C# RabbitMQ使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入C#中get与set的详解

    深入C#中get与set的详解

    本篇文章是对C#中的get与set进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • WinForm实现多屏交互的实战技巧和避坑指南

    WinForm实现多屏交互的实战技巧和避坑指南

    你是否遇到过这些问题窗体显示在错误的屏幕、窗口位置被任务栏遮挡或者跨屏拖拽卡顿,本文将通过 3步核心流程、5大实战技巧和10个高频避坑指南,教你彻底掌握WinForm多屏交互开发,让窗体精准飞向副屏,需要的朋友可以参考下
    2025-09-09
  • C#判断给定IP地址是否在指定范围内的方法

    C#判断给定IP地址是否在指定范围内的方法

    这篇文章主要介绍了C#判断给定IP地址是否在指定范围内的方法,涉及C#针对IP地址的转换与匹配操作技巧,非常具有实用价值,需要的朋友可以参考下
    2015-03-03
  • C# ExecuteScalar()方法案例讲解

    C# ExecuteScalar()方法案例讲解

    这篇文章主要介绍了C# ExecuteScalar()方法案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • WinForm调用百度地图接口用法示例

    WinForm调用百度地图接口用法示例

    这篇文章主要介绍了WinForm调用百度地图接口用法,结合具体实例形式简单分析了WinForm WebBrower控件与前端百度接口交互的相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • C#优雅的实现INotifyPropertyChanged接口

    C#优雅的实现INotifyPropertyChanged接口

    这篇文章介绍了C#实现INotifyPropertyChanged接口的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • C# 实现窗口无边框,可拖动效果

    C# 实现窗口无边框,可拖动效果

    这篇文章主要介绍了C# 实现窗口无边框,可拖动效果,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2018-03-03
  • C#判断三角形的类型

    C#判断三角形的类型

    这篇文章主要介绍了C#判断三角形的类型的方法,通过输入三角形的三条边长,判断是否能构成一个三角形,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • C#函数out多个返回值问题

    C#函数out多个返回值问题

    这篇文章主要介绍了C#函数out多个返回值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C#读写Config配置文件案例

    C#读写Config配置文件案例

    这篇文章介绍了C#读写Config配置文件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04

最新评论