C#中RocketMQ与Redis的使用指南
一、C#中使用Redis(最常用、最简单)
Redis在C#中最流行的客户端是StackExchange.Redis,下面我来手把手教你用。
1. 安装与连接
cs
// 1. 安装NuGet包
// Install-Package StackExchange.Redis
using StackExchange.Redis;
using System;
class RedisExample
{
static void Main(string[] args)
{
// 2. 创建连接配置
var configuration = ConfigurationOptions.Parse("localhost:6379");
configuration.AbortOnConnectFail = false; // 允许自动重连
// 3. 建立连接
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(configuration);
IDatabase db = redis.GetDatabase();
Console.WriteLine("Redis连接成功!"); // 连接成功提示
}
}
2. 基础数据操作
字符串操作(最常用)
cs
// 设置值(带过期时间)
db.StringSet("user:1001:name", "张三", TimeSpan.FromMinutes(30));
// 获取值
string name = db.StringGet("user:1001:name");
Console.WriteLine($"用户名称: {name}"); // 输出: 张三
哈希操作(存储对象)
cs
// 存储用户对象
db.HashSet("user:1001", new[] {
new HashEntry("name", "李四"),
new HashEntry("age", "25"),
new HashEntry("email", "lisi@example.com")
});
// 获取用户信息
var user = db.HashGetAll("user:1001");
foreach (var field in user)
{
Console.WriteLine($"{field.Name}: {field.Value}");
}
列表操作(实现简单队列)
cs
// 添加任务
db.ListLeftPush("task_queue", "处理订单1001");
db.ListLeftPush("task_queue", "处理订单1002");
// 获取任务(出队)
string task = db.ListRightPop("task_queue");
Console.WriteLine($"正在处理任务: {task}"); // 输出: 处理订单1001
发布/订阅(消息通知)
cs
// 订阅消息
var subscriber = redis.GetSubscriber();
subscriber.Subscribe("order_status", (channel, message) =>
Console.WriteLine($"收到订单状态更新: {message}"));
// 发布消息
db.Publish("order_status", "订单1001已发货");
注意 :Redis在C#中主要用作缓存、会话存储、简单消息队列,但不推荐作为核心消息中间件,因为可靠性不如RocketMQ/RabbitMQ。
二、C#中使用RocketMQ(官方支持有限,但有第三方库)
RocketMQ官方主要支持Java,C#支持相对较少,但有几个不错的第三方库可以使用,比如:
- RocketMQ.Client(推荐)
- Apache.RocketMQ(NuGet包)
1. 安装RocketMQ.Client
cs
Install-Package RocketMQ.Client
2. 发送消息示例
cs
using RocketMQ.Client;
using RocketMQ.Client.Common;
using RocketMQ.Client.Producer;
using System;
class RocketMQExample
{
static void Main(string[] args)
{
// 1. 创建生产者
DefaultMQProducer producer = new DefaultMQProducer("my_group");
producer.SetNamesrvAddr("127.0.0.1:9876"); // RocketMQ NameServer地址
// 2. 启动生产者
producer.Start();
try
{
// 3. 发送消息
for (int i = 0; i < 5; i++)
{
Message message = new Message("MyTopic", "TagA", $"Hello RocketMQ {i}".GetBytes());
SendResult result = producer.Send(message);
Console.WriteLine($"发送结果: {result}");
}
}
finally
{
// 4. 关闭生产者
producer.Shutdown();
}
}
}
3. 接收消息示例
cs
using RocketMQ.Client;
using RocketMQ.Client.Consumer;
using RocketMQ.Client.Common;
using System;
class ConsumerExample
{
static void Main(string[] args)
{
// 1. 创建消费者
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("my_group");
consumer.SetNamesrvAddr("127.0.0.1:9876");
consumer.Subscribe("MyTopic", "*"); // 订阅所有Tag
// 2. 注册消息处理
consumer.RegisterMessageListener((msgs, context) =>
{
foreach (var msg in msgs)
{
Console.WriteLine($"收到消息: {msg.BodyString}");
}
return ConsumeConcurrentlyStatus.ConsumeSuccess;
});
// 3. 启动消费者
consumer.Start();
Console.WriteLine("消费者已启动,按任意键退出...");
Console.ReadKey();
// 4. 关闭消费者
consumer.Shutdown();
}
}
注意:C#的RocketMQ客户端可能不如Java版本完善,如果需要在生产环境中使用,建议考虑使用Java服务端+C#客户端的组合方式。
三、RocketMQ与Redis协同工作的经典场景
1. 订单系统(高并发场景)
cs
// 1. 用户下单后,先缓存订单到Redis
db.StringSet($"order:{orderId}", JsonConvert.SerializeObject(order), TimeSpan.FromMinutes(10));
// 2. 同时发送消息到RocketMQ
var message = new Message("OrderTopic", "OrderTag", JsonConvert.SerializeObject(order));
producer.Send(message);
// 3. 订单服务消费RocketMQ消息后,处理订单并更新数据库
// 4. 如果处理失败,可以重试或记录错误
2. 实时通知系统
cs
// 1. 用户注册后,发送通知消息到RocketMQ
var notification = new Notification { UserId = userId, Type = "welcome" };
var message = new Message("NotificationTopic", "WelcomeTag", JsonConvert.SerializeObject(notification));
producer.Send(message);
// 2. 通知服务消费消息后,通过Redis的发布/订阅发送实时通知
var subscriber = redis.GetSubscriber();
subscriber.Publish("user:notifications", JsonConvert.SerializeObject(notification));
3. 数据同步
cs
// 1. 用户修改资料后,先更新Redis缓存
db.HashSet($"user:{userId}", "name", newName);
// 2. 同时发送数据变更消息到RocketMQ
var message = new Message("UserDataTopic", "UpdateTag", $"user:{userId}");
producer.Send(message);
// 3. 数据同步服务消费消息后,更新其他系统数据库
四、为什么这样组合使用?
- Redis作为缓存:快速读取热门数据,减少数据库压力
- RocketMQ作为消息中间件:保证消息可靠传递,解耦系统
- 两者结合:实现"缓存+消息"的双重保障,既快又可靠,Redis缓存热点数据,RocketMQ保证业务流程
五、RocketMQ、RabbitMQ、Redis:区别与联系详解
1. 核心定位
| 产品 | 核心定位 | 主要用途 | 设计初衷 |
|---|---|---|---|
| RocketMQ | 分布式消息中间件 | 高吞吐、高可靠性消息传递 | 解决电商、金融等高并发场景下的消息处理问题 |
| RabbitMQ | 消息代理 | 消息路由、协议适配 | 为异构系统提供灵活的消息通信平台 |
| Redis | 内存数据结构存储 | 缓存、实时数据处理 | 作为高性能缓存和存储解决方案 |
2. 详细对比:从多个维度看
2.1 消息模型与核心特性
| 特性 | RocketMQ | RabbitMQ | Redis |
|---|---|---|---|
| 消息顺序 | ✅ 原生支持 | ❌ 需特殊配置 | ❌ 不支持 |
| 事务消息 | ✅ 原生支持 | ❌ 不支持 | ❌ 不支持 |
| 定时/延时消息 | ✅ 原生支持 | ⚠️ 需插件 | ⚠️ 需额外逻辑 |
| 消息可靠性 | ⭐⭐⭐⭐⭐ (高,支持刷盘、主从复制) | ⭐⭐⭐⭐ (高,持久化+确认机制) | ⭐⭐ (低,除非配置持久化) |
| 吞吐量 | ⭐⭐⭐⭐⭐ (百万级TPS) | ⭐⭐⭐⭐ (万级到十万级) | ⭐⭐⭐⭐ (高,但受内存限制) |
| 消息堆积能力 | ⭐⭐⭐⭐⭐ (亿级) | ⭐⭐⭐ (一般) | ⭐⭐ (有限) |
2.2 架构设计对比
RocketMQ:
- 核心组件:NameServer(路由中心) + Broker(消息存储) + Producer + Consumer
- 采用"多Master多Slave"的分布式架构
- 适合大规模集群部署,水平扩展能力强
RabbitMQ:
- 核心组件:Exchange(交换机) + Queue(队列) + Binding(绑定规则)
- 采用Broker架构,支持集群
- 路由机制灵活,支持Direct、Topic、Fanout等多种模式
Redis:
- 通过数据结构实现消息队列功能
- List(列表)、Sorted Set(有序集合)、Pub/Sub(发布/订阅)可实现简单消息队列
- 本质上是内存数据库,消息队列是附加功能
2.3 适用场景分析
| 场景 | RocketMQ | RabbitMQ | Redis |
|---|---|---|---|
| 电商订单处理 | ✅ 顶级推荐 | ⚠️ 可用,但不如RocketMQ | ❌ 不推荐 |
| 金融交易系统 | ✅ 顶级推荐 | ⚠️ 可用,但需注意顺序 | ❌ 不推荐 |
| 业务系统解耦 | ⚠️ 可用 | ✅ 顶级推荐 | ⚠️ 仅适用于轻量级 |
| 实时消息推送 | ⚠️ 可用 | ✅ 顶级推荐 | ✅ 适合轻量级 |
| 缓存热点数据 | ❌ 不适用 | ❌ 不适用 | ✅ 顶级推荐 |
| 实时排行榜 | ❌ 不适用 | ❌ 不适用 | ✅ 顶级推荐 |
2.4 为什么不能混用?
RocketMQ vs RabbitMQ:
- RocketMQ更适合需要严格顺序 和事务性的场景(如电商下单)
- RabbitMQ更适合需要灵活路由的场景(如订单状态变更需要通知多个系统)
Redis vs 消息中间件:
- Redis不是设计为消息中间件,虽然可以实现简单队列,但可靠性低 、堆积能力差
- 举个例子:如果Redis宕机,所有未处理的消息都会丢失,而RocketMQ/RabbitMQ有持久化机制
3. 实际案例说明
3.1 电商秒杀系统
- RocketMQ:处理订单消息,保证"下单-支付-库存扣减"的事务一致性
- RabbitMQ:处理短信通知、邮件通知等异步任务
- Redis:缓存热门商品信息,加速查询
3.2 金融交易系统
- RocketMQ:处理交易消息,确保"交易-清算-对账"的顺序和一致性
- RabbitMQ:处理报表生成、通知等非核心业务
- Redis:缓存用户账户信息,提高查询速度
3.3 社交应用实时消息
- RabbitMQ:处理用户消息的发布/订阅,支持多种消息类型
- Redis:实现消息的实时推送(通过Pub/Sub)
- RocketMQ:处理关键交易(如支付、充值)等需要高可靠性的消息
4. 选择建议:如何选对工具?
-
优先选RocketMQ的情况:
- 电商、金融等需要高可靠性 和顺序性的场景
- 需要处理大量消息(百万级TPS)
- 需要事务消息保证业务一致性
-
优先选RabbitMQ的情况:
- 需要灵活的路由 和多协议支持
- 消息量不是特别大,但需要异构系统集成
- 需要发布/订阅模式处理多目标消息
-
考虑Redis的情况:
- 已经在使用Redis作为缓存,且消息量不大
- 需要简单消息队列功能,如实时通知
- 作为临时解决方案,但不推荐作为核心消息处理