RabbitMQ消息队列(九)-通过Headers模式分发消息(.Net Core版)
Headers类型的exchange使用的比较少,以至于官方文档貌似都没提到,它是忽略routingKey的一种路由方式。是使用Headers来匹配的。Headers是一个键值对,可以定义成Hashtable。发送者在发送的时候定义一些键值对,接收者也可以再绑定时候传入一些键值对,两者匹配的话,则对应的队列就可以收到消息。
匹配有两种方式all和any。这两种方式是在接收端必须要用键值”x-mactch”来定义。all代表定义的多个键值对都要满足,any代表只要满足一个就可以。fanout,direct,topic exchange的routingKey都需要要字符串形式的,而headers exchange则没有这个要求,因为键值对的值可以是任何类型。
那在.Net Core中怎么应用呢?
headers也是一种交换机类型,但是在rabbitmq官网中的教程中并没有说到。资料也很少,但是找一找总会有的。
headers与direct的模式不同,不是使用routingkey去做绑定。而是通过消息headers的键值对匹配
发布者 -- > headersexchange --> (user: “小明 ”) binding --> queue
也就是说 user: 小明 替代了之前的routingkey。在做绑定的时候有两种匹配方式供选择。x-match (all/any)
意思就是键值对中所有的项都要匹配与只要有一个匹配就可以。下面就可以动手写代码了
新建HeadersProduct用来发布新消息:

using System; using System.Collections.Generic; using System.Text; using RabbitMQ.Client; using RabbitMQ.Client.Events; namespace HeadersProduct { class Program { static void Main(string[] args) { String exchangeName = "wytExchangeHeaders"; ConnectionFactory factory = new ConnectionFactory(); factory.HostName = "192.168.63.129"; factory.Port = 5672; factory.VirtualHost = "/wyt"; factory.UserName = "wyt"; factory.Password = "wyt"; using (IConnection connection=factory.CreateConnection()) { using (IModel channel=connection.CreateModel()) { channel.ExchangeDeclare(exchange: exchangeName, type: "headers", durable: true, autoDelete: false, arguments: null); IBasicProperties properties = channel.CreateBasicProperties(); properties.Headers = new Dictionary<String, Object>() { {"user","wyt" }, {"password","wyt"} }; Byte[] body = Encoding.UTF8.GetBytes("Hello World"); channel.BasicPublish(exchange: exchangeName, routingKey: String.Empty, basicProperties: properties, body: body); } } Console.Write("发布成功!"); Console.ReadKey(); } } }
新建HeadersConsumerA来以正确的headers接收消息:

using System; using System.Collections.Generic; using System.Text; using RabbitMQ.Client; using RabbitMQ.Client.Events; namespace HeadersConsumerA { class Program { static void Main(string[] args) { String exchangeName = "wytExchangeHeaders"; ConnectionFactory factory = new ConnectionFactory(); factory.HostName = "192.168.63.129"; factory.Port = 5672; factory.VirtualHost = "/wyt"; factory.UserName = "wyt"; factory.Password = "wyt"; bool flag = true; string pattern = ""; while (flag) { Console.WriteLine("请选择headers匹配模式 1(any)/2(all)"); pattern = Console.ReadLine(); if (pattern == "1" || pattern == "2") flag = false; else Console.Write("请做出正确的选择"); } //根据声明使用的队列 var headersType = pattern == "1" ? "any" : "all"; using (IConnection connection = factory.CreateConnection()) { using (IModel channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: exchangeName, type: ExchangeType.Headers, durable: true, autoDelete: false, arguments: null); String queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: String.Empty, arguments: new Dictionary<String, Object> { {"x-math",headersType }, {"user","wyt" }, {"password","wyt" } }); EventingBasicConsumer consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var msg = Encoding.UTF8.GetString(ea.Body); Console.WriteLine($"{msg}"); }; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); Console.ReadKey(); } } } } }
新建HeadersConsumerB来以错误的headers接收消息:

using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Collections.Generic; using System.Text; namespace HeadersConsumerB { class Program { static void Main(string[] args) { String exchangeName = "wytExchangeHeaders"; ConnectionFactory factory = new ConnectionFactory(); factory.HostName = "192.168.63.129"; factory.Port = 5672; factory.VirtualHost = "/wyt"; factory.UserName = "wyt"; factory.Password = "wyt"; bool flag = true; string pattern = ""; while (flag) { Console.WriteLine("请选择headers匹配模式 1(any)/2(all)"); pattern = Console.ReadLine(); if (pattern == "1" || pattern == "2") flag = false; else Console.Write("请做出正确的选择"); } //根据声明使用的队列 var headersType = pattern == "1" ? "any" : "all"; using (IConnection connection = factory.CreateConnection()) { using (IModel channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: exchangeName, type: ExchangeType.Headers, durable: true, autoDelete: false, arguments: null); String queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: String.Empty, arguments: new Dictionary<String, Object> { {"x-math",headersType }, {"user","xxx" }, {"password","xxx" } }); EventingBasicConsumer consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var msg = Encoding.UTF8.GetString(ea.Body); Console.WriteLine($"{msg}"); }; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); Console.ReadKey(); } } } } }
运行结果
一个可以接收到消息,另一个由于headers是不匹配的,所有接收不到消息
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构