RabbitMQ - 4种交换机详解

1、  默认的交换机

实质是一个没有设置名称的直连交换机,它有一个特殊的属性使得它对于简单应用特别有用处:那就是每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称与队列名称相同

所以,当你声明一个 fanout 的交换机,绑定 routing key = "testqueue" 的时候,default exchange 也会多一个队列名为 "testqueue" 的队列。

2、直连交换机( Direct Exchange)

  • 选择 type 为 Direct (type: ExchangeType.Direct)的交换机 

  • 把 直连交换机(Direct Exchange)  和 Queue 绑定(routing key)

  • 消息代理(message brokere )会根据生产者指定的路由(routing key)将消息发送给相应的消费者(消息处理器),这个消息处理器可以是单个也可以多个。

  • 直连交换机一般用来处理单播路由

  • 为什么直连交换机一般用于处理单播路由 ? 因为用扇形或主题交换机做 【多播路由更加方便】,因为扇形交换机不用再绑定路由值(routing key),就能做到把消息广播给所有绑定在这个交换机的队列(queue)中

  • 创建信道,声明路由,插入消息

        using (var connection = factory.CreateConnection())
        {
            using (IModel channel = connection.CreateModel())
            { 
                //声明一个路由 type: ExchangeType.Direct Direct类型的路由                           channel.ExchangeDeclare(exchange: "DirectExChange", type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);

                //声明一个队列用来接受Error类型的日志
                channel.QueueDeclare(queue: "DirectExchangeErrorQueue", durable: true, exclusive: false, autoDelete: false, arguments: null); 
                
                //路由绑定 key
                channel.QueueBind(queue: "DirectExchangeErrorQueue",
                              exchange: "DirectExChange",
                              routingKey: "error");
                    
                 List<LogMsgModel> logList = new List<LogMsgModel>();
                 var i = 1;
                 logList.Add(new { LogType = "error", Msg = Encoding.UTF8.GetBytes($"error第{i}条信息") });
                //插入信息
                 channel.BasicPublish(exchange: "DirectExChange",
                                            routingKey: log.LogType,
                                            basicProperties: null,
                                            body: log.Msg);
                }
             }

3、  扇形交换机(FanoutExchange)

  • 相对于直连交换机(deriect exchange),扇形交换机(fanout exhcange)只和队列(queue)建立绑定没有 routing key

  • 当生产者给该扇形交换机(fanout exchange)发送消息时,所有的订阅这个 (交换机+队列)绑定的消费者都会接收到信息

  • 综合两面两点扇形交换机更适合处理广播路由(broadcast routing)

//生产者:

 using (var connection = RabbitMQHelper.GetConnection())
            {
                using(var channel = connection.CreateModel())
                {
                    // 声明交换机对象
                    channel.ExchangeDeclare("fanout_exchange", "fanout");
                    // 创建队列
                    string queueName1 = "fanout_queue1";
                    channel.QueueDeclare(queueName1, false, false, false, null);
                    string queueName2 = "fanout_queue2";
                    channel.QueueDeclare(queueName2, false, false, false, null);
                    string queueName3 = "fanout_queue3";
                    channel.QueueDeclare(queueName3, false, false, false, null);
                    // 绑定到交互机
                    // fanout_exchange 绑定了 3个队列 
                    channel.QueueBind(queue: queueName1, exchange: "fanout_exchange", routingKey: "");
                    channel.QueueBind(queue: queueName2, exchange: "fanout_exchange", routingKey: "");
                    channel.QueueBind(queue: queueName3, exchange: "fanout_exchange", routingKey: "");

                    for (int i = 0; i < 10; i++)
                    {
                        string message = $"RabbitMQ Fanout {i + 1} Message";
                        var body = Encoding.UTF8.GetBytes(message);
                        channel.BasicPublish("fanout_exchange", "", null, body);
                        Console.WriteLine("Send Fanout {0} message",i + 1);
                    }
                }
            }

//消费者 

 var connection = RabbitMQHelper.GetConnection();
            {
                var channel = connection.CreateModel();
                {
                    //申明exchange
                    channel.ExchangeDeclare(exchange: "fanout_exchange", type: "fanout");
                    // 创建队列
                    string queueName1 = "fanout_queue1";
                    channel.QueueDeclare(queueName1, false, false, false, null);
                    string queueName2 = "fanout_queue2";
                    channel.QueueDeclare(queueName2, false, false, false, null);
                    string queueName3 = "fanout_queue3";
                    channel.QueueDeclare(queueName3, false, false, false, null);
                    // 绑定到交互机
                    channel.QueueBind(queue: queueName1, exchange: "fanout_exchange", routingKey: "");
                    channel.QueueBind(queue: queueName2, exchange: "fanout_exchange", routingKey: "");
                    channel.QueueBind(queue: queueName3, exchange: "fanout_exchange", routingKey: "");


                    Console.WriteLine("[*] Waitting for fanout logs.");
                    //申明consumer
                    var consumer = new EventingBasicConsumer(channel);
                    //绑定消息接收后的事件委托
                    consumer.Received += (model, ea) => {
                        var body = ea.Body;
                        var message = Encoding.UTF8.GetString(body.ToArray());
                        Console.WriteLine("[x] {0}", message);

                    };

                    channel.BasicConsume(queue: queueName1, autoAck: true, consumer: consumer);
                    Console.WriteLine(" Press [enter] to exit.");
                    Console.ReadLine();
                }
            }

4、主题路由(topic exchange)

  • 路由绑定队列需要指定 Key

  • Key 有自己的规则,可以有占位符, * 匹配单个单词、#匹配多个单词,可以模糊匹配

  //声明一个ExchangeType.Topic类型的路由
  channel.ExchangeDeclare(exchange: "TopicExchange", type: ExchangeType.Topic, durable: true, autoDelete: false, arguments: null); 
  
//声明 queue
channel.QueueDeclare(queue: "ChinaQueue", durable: true, exclusive: false, autoDelete: false, arguments: null); 
​
//路由和消息队列绑定====》模糊匹配 Chain. 开头的消息
 channel.QueueBind(queue: "ChinaQueue", exchange: "TopicExchange", routingKey: "China.#", arguments: null); 
 

5、头交换机(Header Exchange)

  • headers头路由模型中,消息是根据prop即请求头中key-value来匹配的。

  • 消费方指定的headers中必须包含一个"x-match"的键。

  • 键"x-match"的值有2个:all和any。

  • all:表示消费方指定的所有key-value都必须在消息header中出现并匹配。

  • any:表示消费方指定的key-value至少有一个在消息header中出现并匹配即可。

    //生成端代码    
    Map<String, Object> header = new HashMap<String, Object>();
    header.put("name", "张三");
    header.put("idcard","123321"); 
    header.put("phone","13567655555");
    AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties().builder().headers(header);
    channel.basicPublish(EXCHANGE_NAME, "", properties.build(), message.getBytes("UTF-8"));
​
​
  //消费端代码
  Map<String, Object> header = new HashMap<String, Object>();
  header.put("x-match", "all");  //x-match: all表所有key-value全部匹配才匹配成功 ,any表只需要匹配任意一个key-value 即匹配成功。
  header.put("name", "张三");
  header.put("idcard","123321"); 
  
  channel.queueBind(queueName, EXCHANGE_NAME, "", header);
  //处理消息
 channel.BasicConsume(queue: "DirectExchangeErrorQueue",
                      autoAck: true,
                      consumer: consumer);

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ交换机的扩展参数用于扩展AMQP协议的定制化使用。 所谓扩展参数,指的是在交换机属性中的Arguments字段,它可以接受一些额外的参数来自定义交换机的行为。这些参数可以根据具体的需求来设置,例如根据业务逻辑定制化消息的路由规则、过滤消息、设置优先级等。扩展参数的具体使用方式可以参考AMQP协议的相关文档。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [RabbitMQ交换机详解](https://blog.csdn.net/a1034996/article/details/106520394)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [RabbitMQ学习记录(八)-交换机](https://blog.csdn.net/cuierdan/article/details/124147813)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [1.6 RabbitMQ-Exchange内容详解](https://download.csdn.net/download/weixin_38564826/14035505)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值