.netcore3.1 RabbitMq Header交换机 电脑版发表于:2021/1/27 11:22 ![](https://img.tnblog.net/arcimg/hb/585b0f1ffa7f4c2095baa20c175b32a0.png) >#.netcore3.1 RabbitMq Header交换机 [TOC] tn>标头交换机指在用于在多个属性上路由,这些属性比路由键更容易表示为消息标头。标头交换忽略路由键属性。相反,用于路由的属性取自`headers`属性。如果标头的值等于绑定时指定的值,则认为消息匹配。 可以使用多个标题进行匹配,将队列绑定到标题交换。在这种情况下,代理需要从应用程序开发人员那里获得另一条信息,即,它是否应该考虑具有任何匹配的标头或全部匹配的消息?这就是`x-match`绑定参数的作用。当`x-match`参数设置为` any`时,仅一个匹配的标头值就足够了。或者,将`x-match`设置为`all`要求所有值必须匹配。 >其实这个玩意比较像我们在编程中的`and`与`all`的关系,简单来看可以如下面这张图所示。 ![](https://img.tnblog.net/arcimg/hb/7ce5b925249b424a8e75560089178745.png) 创建Header交换机与队列 ------------ tn>注意这里的`routingKey`其实并不起到任何作用所以这里我们可以将它设置为空,我们通过上图所示创建一个Header交换机,并先创建`x-match:any`的队列`myheaderQueue1` ```csharp var factory = new ConnectionFactory() { HostName = "47.98.187.188", UserName = "bob", Password = "bob" }; // 创建一个链接 using (var connection = factory.CreateConnection()) { // 创建一个通道 using (var channel = connection.CreateModel()) { // 创建Header类型的交换机 channel.ExchangeDeclare(exchange: "MyHeaderExchange", ExchangeType.Headers, true, false); // 声明一个队列 channel.QueueDeclare( queue: "myheaderQueue1", durable: true, exclusive: false, autoDelete: false, arguments: null); // 绑定相关参数并将x-match设置为any channel.QueueBind("myheaderQueue1", "MyHeaderExchange",string.Empty,new Dictionary<string, object> { { "x-match","any" }, { "name","aidasi" }, { "age","18" } }); Console.WriteLine("myheaderQueue1 Created!"); } } ``` tn>随后我们再创建`x-match:all`的`myheaderQueue1`队列。 ```csharp var factory = new ConnectionFactory() { HostName = "47.98.187.188", UserName = "bob", Password = "bob" }; // 创建一个链接 using (var connection = factory.CreateConnection()) { // 创建一个通道 using (var channel = connection.CreateModel()) { // 创建Header类型的交换机 channel.ExchangeDeclare(exchange: "MyHeaderExchange", ExchangeType.Headers, true, false); // 声明一个队列 channel.QueueDeclare( queue: "myheaderQueue2", durable: true, exclusive: false, autoDelete: false, arguments: null); // 绑定相关参数并将x-match设置为any channel.QueueBind("myheaderQueue2", "MyHeaderExchange",string.Empty,new Dictionary<string, object> { { "x-match","all" }, { "name","aidasi" }, { "age","18" } }); Console.WriteLine("myheaderQueue1 Created!"); } } ``` tn>运行并在`UI`上查看绑定情况。 ![](https://img.tnblog.net/arcimg/hb/73231cbd6d04462aa0883dc0edcc68b2.png) 发布消息 ------------ tn>发布3条消息。代码如下: ```csharp var factory = new ConnectionFactory() { HostName = "47.98.187.188", UserName = "bob", Password = "bob" }; // 创建一个链接 using (var connection = factory.CreateConnection()) { // 创建一个通道 using (var channel = connection.CreateModel()) { var properties = channel.CreateBasicProperties(); // 消息持久化 properties.Persistent = true; // 实例化消息投 // 创建any的队列 properties.Headers = new Dictionary<string, object>() { { "name","aidasi" }, { "age","18" } }; var msg = Encoding.UTF8.GetBytes("Message: name-aidasi,age-18"); channel.BasicPublish("MyHeaderExchange", string.Empty, properties, msg); properties.Headers = new Dictionary<string, object>() { { "name","aidasi" } }; var msg1 = Encoding.UTF8.GetBytes("Message: name-aidasi"); channel.BasicPublish("MyHeaderExchange", string.Empty, properties, msg1); properties.Headers = new Dictionary<string, object>() { { "name","bob" }, { "age","19" } }; var msg2 = Encoding.UTF8.GetBytes("Message: name-bob,age-19"); channel.BasicPublish("MyHeaderExchange", string.Empty, properties, msg2); } } ``` tn>在`UI`中我们发现有相应的消息进入到了队列中 ![](https://img.tnblog.net/arcimg/hb/2ca7b4d980a1425f860b18539d0e6f91.png) 消费消息 ------------ tn>代码如下: ```csharp var factory = new ConnectionFactory() { HostName = "47.98.187.188", UserName = "bob", Password = "bob" }; Console.WriteLine("Please enter a queue name:"); // MyTopicExchange1 MyTopicExchange2 string queuename = Console.ReadLine(); // 创建一个链接 using (var connection = factory.CreateConnection()) { // 创建一个通道 using (var channel = connection.CreateModel()) { // 创建消费实例 var consumer = new EventingBasicConsumer(channel); // 事件在交付到使用者时触发。(消费处理事件) consumer.Received += (model, ea) => { string EventQueueName = queuename; var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); Console.WriteLine($" Queue:{EventQueueName} Message: {message}"); // 手动确认 channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: true); }; // 绑定到队列中去 channel.BasicConsume(queue: queuename, autoAck: false, consumer: consumer); Console.ReadLine(); } } ``` tn>我们找到程序生成后的目录,并运行两个`Bash`到两个`Header`队列中进行消费消息。 ![](https://img.tnblog.net/arcimg/hb/82bc9304ff8d4e40a16a2bd8d8dfd44a.png) tn>我们发现处理`bob`那条消息没有消费外,其他的消息都对应了相应的`or`与`and`进行消费