RabbitMQ(七)——主题模式
RabbitMQ系列
RabbitMQ(七)——主题模式
前言
本章我们学习主题模式(Topic),主题模式与路由模式类似,不同的是路由模式生产者向指定路由发送消息,消费者接收指定路由的消息;主题模式生产者向交换机发送消息后,消费者可以对队列进行匹配,提供两个匹配字符,’ * ‘星号和 ‘ # ’井号,‘ * ’匹配一个词,‘ # ’ 匹配多个词,一般使用#号匹配多个,*号用的比较少。
解释:生产者P向topic交换机发送消息,向指定routekey发布消息,消费者通过绑定routekey匹配词接收消息。
如:生产者向routekey : topic.orange.rabbit 发送消息,消费者可通过绑定*.orange.* / *.*.rabbit接收到消息;
示例
生产者:

static void Main(string[] args) { Console.WriteLine("TopicServer发布服务器启动..."); //创建连接工厂 var factory = new ConnectionFactory() { HostName = "127.0.0.1", UserName = "guest", Password = "guest" }; //创建连接和通道 using (var conn = factory.CreateConnection()) { using (var channel = conn.CreateModel()) { //创建topic类型交换机 channel.ExchangeDeclare("topicExchange", "topic"); string msg = ""; //模拟向不同路由发送消息 for (int i = 0; i < 40; i++) { msg = $"发布消息{i}"; var body = Encoding.UTF8.GetBytes(msg); string Topic = ""; if (i % 2 == 0) { Topic = "Topic.add"; } else { Topic = "Topic.remove"; } channel.BasicPublish("topicExchange", Topic, null, body); Console.WriteLine($"{Topic}-发布消息成功:{msg}"); Thread.Sleep(1000); } Console.ReadKey(); } } }
消费者1:

static void Main(string[] args) { Console.WriteLine("TopicClient接收客户端启动..."); //创建连接工厂 var factory = new ConnectionFactory() { HostName = "127.0.0.1", UserName = "guest", Password = "guest" }; //创建连接和通道 using (var conn = factory.CreateConnection()) { using (var channel = conn.CreateModel()) { //创建队列 var queue = channel.QueueDeclare().QueueName; //绑定交换机,指定匹配路由Topic.# channel.QueueBind(queue, "topicExchange", "Topic.#"); //创建消费者 可接收topic路由下全部消息 var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { //接收消息 var body = Encoding.UTF8.GetString(ea.Body.ToArray()); Console.WriteLine($"Topic.#接收消息:{body.ToString()}"); }; channel.BasicConsume(queue, true, consumer); Console.ReadKey(); } } }
消费者2:

static void Main(string[] args) { Console.WriteLine("TopicClient接收客户端启动..."); //创建连接工厂 var factory = new ConnectionFactory() { HostName = "127.0.0.1", UserName = "guest", Password = "guest" }; //创建连接和通道 using (var conn = factory.CreateConnection()) { using (var channel = conn.CreateModel()) { //创建队列 var queue = channel.QueueDeclare().QueueName; //绑定交换机 匹配路由Topic.add channel.QueueBind(queue, "topicExchange", "Topic.add"); //创建消费者 只能接受到Topic.add路由消息 var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { //接收消息 var body = Encoding.UTF8.GetString(ea.Body.ToArray()); Console.WriteLine($"Topic.add接收消息:{body.ToString()}"); }; channel.BasicConsume(queue, true, consumer); Console.ReadKey(); } } }
结果
理想的结果应该是生产者分别向Topic.add与Topic.remove路由发送消息,消费者1匹配路由Topic.# ,可以接收到Topic路由下所有消息,而消费者2匹配的是Topic.add路由,能接受到生产者发送给Topic.add路由的消息;
与上面猜测一致,消费者1能接收到生产者topic路由下的所有消息,消费者2能接收到topic.add路由下的消息,这与消费者交换机绑定的路由有关。
总结
- 主题模式(Topic)是最常用的模式,相较于路由模式(Direct)更灵活、更方便、更强大。
- 生产者模式需要在声明交换机时指定类型为Topic。
- 消费者接收消息有两种模糊查询:# 匹配一个或多个词,* 匹配一个词,# 使用较多
附上Demo源码:https://github.com/1164887865/RabbitMQDemo
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现