分布式异步队列学习总结8(交换机HeaderExchange)

Header交换机不依赖于routing key和binding key,而是根据发送消息内容的headers参数来确定消息发送到哪一个队列中,供消费者消费。

通过一个示例说明此类交换机的用法,项目结构:

代码实例:

生产者

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;

namespace AspNetCore.RabbitMQ.MessageProducer.MessageProducer
{
    /// <summary>
    /// Header类型交换机
    /// </summary>
    public class HeaderExchange
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("生产者已准备就绪......");

                    //声明交换机exchange
                    channel.ExchangeDeclare(exchange: "HeaderExchange", type: ExchangeType.Headers, durable: true, autoDelete: false, arguments: null);


                    //声明两个队列
                    channel.QueueDeclare(queue: "HeaderExchangeAllQueue", durable: true, exclusive: false, autoDelete: false, arguments: null);
                    channel.QueueDeclare(queue: "HeaderExchangeAnyQueue", durable: true, exclusive: false, autoDelete: false, arguments: null);


                    //绑定exchange和queue
                    channel.QueueBind(queue: "HeaderExchangeAllQueue", exchange: "HeaderExchange", routingKey: string.Empty,
                        arguments: new Dictionary<string, object>
                    {
                            { "x-match","all"},
                            { "name","zhangsan"},
                            { "pass","123"}
                    });

                    channel.QueueBind(queue: "HeaderExchangeAnyQueue", exchange: "HeaderExchange", routingKey: string.Empty,
                       arguments: new Dictionary<string, object>
                   {
                            { "x-match","any"},
                            { "name","zhangsan"},
                            { "pass","123"}
                   });


                    //待发送的消息
                    {
                        string message = "name和pass都相同";
                        var props = channel.CreateBasicProperties();
                        props.Headers = new Dictionary<string, object>()
                        {
                            { "name","zhangsan"},
                            { "pass","123"}
                        };
                        var body = Encoding.UTF8.GetBytes(message);
                        channel.BasicPublish(exchange: "HeaderExchange", routingKey: string.Empty, basicProperties: props, body: body);
                        Console.WriteLine($"消息 {message} 已发送到队列");
                    }

                    {
                        string message = "只有name相同";
                        var props = channel.CreateBasicProperties();
                        props.Headers = new Dictionary<string, object>()
                        {
                            { "name","zhangsan"},
                            { "pass","234"}
                        };
                        var body = Encoding.UTF8.GetBytes(message);
                        channel.BasicPublish(exchange: "HeaderExchange", routingKey: string.Empty, basicProperties: props, body: body);
                        Console.WriteLine($"消息 {message} 已发送到队列");
                    }

                }
            }
        }
    }
}

 声明了两个队列,HeaderExchangeAllQueue和HeaderExchangeAnyQueue。HeaderExchangeAllQueue是需要name和pass两个参数完全匹配才会进入此队列中。HeaderExchangeAnyQueue是name和pass两个参数中有任一参数匹配到就会进入此队列。

main方法:

class Program
    {
        static void Main(string[] args)
        {
            HeaderExchange.Show();

            Console.ReadLine();
        }
    }

消费者一:

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

namespace AspNetCore.RabbitMQ.MessageConsumer_01.MessageConsumer
{
    /// <summary>
    /// 消费者 Header类型交换机
    /// </summary>
    public class HeaderExchange
    {
        public static void Show()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "localhost";//rabbitmq服务在本地运行
            factory.UserName = "guest";//用户名
            factory.Password = "guest";//密码

            //创建链接
            using (IConnection connection = factory.CreateConnection())
            {
                //创建信道
                using (IModel channel = connection.CreateModel())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    try
                    {
                        //基于当前信道创建事件
                        var consumer = new EventingBasicConsumer(channel);
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());
                            Console.WriteLine($"接收成功 {message}");
                        };
       

                        //处理消息
                        channel.BasicConsume(queue: "HeaderExchangeAllQueue", autoAck: true, consumer: consumer);
                        channel.BasicConsume(queue: "HeaderExchangeAnyQueue", autoAck: true, consumer: consumer);


                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
            }

        }
    }
}

main方法:
 

class Program
    {
        static void Main(string[] args)
        {
            HeaderExchange.Show();
            Console.ReadLine();
        }
    }

运行结果:

生产者服务启动后,可以看到消息进入到队列中

 

 从可视化工具中也可以看到两个消息根据规则进入到对应的队列中,消息一同时符合两个队列的规则,消息二符合HeaderExchangeAnyQueue队列的规则。所以最终HeaderExchangeAnyQueue队列中有两条消息,HeaderExchangeAllQueue队列中有一条消息。

启动消费者服务,可以看到第一条消息从两个不同的队列中各被消费了一次,第二条消息被消费一次。

 

总结:Header类型交换机不需要依赖key。更多的时候像这种key-value的键值,可能会存储在数据库中,就可以定义一个动态规则来拼装这个key-value,从而达到消息灵活转发到不同的队列中去。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值