RabbitMQ-直连交换机(direct)使用方法

RabbitMQ-默认读、写方式介绍

RabbitMQ-发布/订阅模式

RabbitMQ-topic exchange使用方法

目录

1、概述

2、直连交换机

3、多重绑定

4、具体代码实现

4.1 生产者部分

4.2 消费者部分 

 5、运行代码

6、总结


1、概述

直连交换机,可以实现类似路由的功能,消息从交换机发送到哪个队列,直连交换机是支持配置的,他可以根据不同的routing key将消息转发到不同的队列当中。

在上一篇《RabbitMQ-发布/订阅模式》中,介绍过绑定过程,类似:

err = ch.QueueBind(
  q.Name, // queue name
  "",     // routing key
  "logs", // exchange
  false,
  nil)

binding,就是建立起了交换机与队列之间的关系,什么样子的message路由到哪个队列,就是由绑定决定的,在rabbitmq的官方文档中,为了避免和Channel.Publish函数的key参数混淆,在bind函数中的routing key称之为binding key,比如:

err = ch.QueueBind(
  q.Name,    // queue name
  "black",   // binding key
  "logs",    // exchange
  false,
  nil)

在上面的代码中,routing key参数,在扇形交换机是无效的,这点大家要注意。

2、直连交换机

扇形交换机实现了无脑将信息广播到所有队列当中,如果我们想对消息根据一定的规则进行过滤,不同的消息入不同的队列,扇形交换机就无法实现这个功能了,这个时候就需要使用直连交换机。

上图,声明了直连交换机, 并将两个队列绑定到该交换机上,第一个队列的binding key为【orange】,第二个队列设计了两个绑定,第一个binding key为【black】,另外一个为【green】,在这种设计下,routing key为【orange】的消息将会被路由到Q1队列,routing key为【black】【green】的消息将会被路由到Q2队列,其他类型的消息就会被丢弃。

3、多重绑定

在这种模式下,其实现的功能类似扇形交换机,交换机可以将同一个消息路由到多个队列当中。

在上图的设计方式中,routing key为【black】的消息会同时路由到Q1和Q2两个队列中。

4、具体代码实现

4.1 生产者部分

第一步,和扇形交换机一样,声明交换机:

err = ch.ExchangeDeclare(
  "logs_direct", // name
  "direct",      // type
  true,          // durable
  false,         // auto-deleted
  false,         // internal
  false,         // no-wait
  nil,           // arguments
)

第二步,发送消息:

	body := "Hello World by dircet exchange"
	err = ch.Publish(
		"logs", // exchange
		"info", // routing key
		false,
		false,
		amqp.Publishing{
			ContentType: "text/plain",
			Body:        []byte(body),
		})

4.2 消费者部分 

声明队列:

	q, err := ch.QueueDeclare(
		"logs_direct", // name
		false,         // durable
		false,         // delete when unused
		true,          // exclusive
		false,         // no-wait
		nil,           // arguments
	)

绑定:

err = ch.QueueBind(
		q.Name, // queue name
		"info", // routing key(binding key)
		"logs", // exchange
		false,
		nil,
	)

 5、运行代码

生产者部分全部代码:

package main

import (
	"fmt"

	amqp "github.com/rabbitmq/amqp091-go"
)

func main() {
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
	if err != nil {
		fmt.Println("Failed to connect to RabbitMQ")
		return
	}
	defer conn.Close()
	ch, err := conn.Channel()
	if err != nil {
		fmt.Println("Failed to open a channel")
		return
	}
	err = ch.ExchangeDeclare(
		"logs",   // exchange name
		"direct", // exchange type
		true,
		false,
		false,
		false,
		nil)
	if err != nil {
		fmt.Println("Failed to declare an exchange")
		return
	}
	body := "Hello World by dircet exchange"
	err = ch.Publish(
		"logs", // exchange
		"info", // routing key
		false,
		false,
		amqp.Publishing{
			ContentType: "text/plain",
			Body:        []byte(body),
		})
	if err != nil {
		fmt.Println("Failed to publish a message")
		return
	}
}

消费者部分全部代码:

package main

import (
	"fmt"

	amqp "github.com/rabbitmq/amqp091-go"
)

func main() {
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
	if err != nil {
		fmt.Println("Failed to connect to RabbitMQ")
		return
	}
	defer conn.Close()
	ch, err := conn.Channel()
	if err != nil {
		fmt.Println("Failed to open a channel")
		return
	}
	err = ch.ExchangeDeclare("logs", "direct", true, false, false, false, nil)
	if err != nil {
		fmt.Println("Failed to declare an exchange")
		return
	}
	q, err := ch.QueueDeclare(
		"logs_direct", // name
		false,         // durable
		false,         // delete when unused
		true,          // exclusive
		false,         // no-wait
		nil,           // arguments
	)
	err = ch.QueueBind(
		q.Name, // queue name
		"info", // routing key(binding key)
		"logs", // exchange
		false,
		nil,
	)

	msgs, err := ch.Consume(
		q.Name, // queue
		"",     // consumer
		true,   // auto-ack
		false,  // exclusive
		false,  // no-local
		false,  // no-wait
		nil,    // args
	)
	var forever chan struct{}

	go func() {
		for d := range msgs {
			fmt.Printf(" [x] %s\n", d.Body)
		}
	}()

	fmt.Printf(" [*] Waiting for logs. To exit press CTRL+C")
	<-forever
}

启动消费者,程序启动后,从RabbitMQ控制台就会看到一个队列:

之后运行生产者部分代码,生产者发送消息后,消费者侧就会接收到生产者发来的消息:

6、总结

以上就是rabbitmq直连交换机的使用方式,示例代码只是做了简单的演示,对于多重绑定,各种路由规则可以自行尝试,直连交换机模式,为开发者提供了灵活的路由规则,推荐使用。

<think>好的,我现在要处理用户关于RabbitMQ直连交换机路由规则的问题。首先,我需要回忆一下RabbitMQ的基本知识,特别是关于交换机的部分。记得RabbitMQ有几种类型的交换机,包括直连、主题、扇出和头交换机。用户问的是直连交换机的路由规则,所以我需要专注于direct exchange。 直连交换机的工作原理是根据消息的路由键(routing key)和绑定到交换机的队列的绑定键(binding key)进行精确匹配。当生产者发送消息时,会指定一个路由键,而队列在绑定到交换机时会声明一个绑定键。如果两者完全匹配,消息就会被路由到对应的队列。 接下来,我需要确认这个机制的具体细节。例如,如果有多个队列使用相同的绑定键绑定到同一个直连交换机,会发生什么情况?这时候消息会被复制到所有匹配的队列,也就是类似扇出交换机的行为,但仅限于绑定键相同的队列。这一点可能需要举例说明,让用户更容易理解。 然后,用户可能需要了解路由键和绑定键是否区分大小写,或者是否有其他匹配规则。根据RabbitMQ的文档,默认情况下是区分大小写的,并且需要完全匹配。比如,路由键为"error"的消息只会被绑定键为"error"的队列接收,而不会匹配到"Error"或"ERROR"。 另外,应用场景方面,直连交换机适用于需要精确路由的情况,比如日志系统中的不同日志级别(如info、warning、error),每个级别对应一个队列。生产者在发送日志消息时指定路由键,消费者根据绑定的队列处理特定级别的日志。 还需要考虑用户可能遇到的问题,例如如何设置绑定键,或者在代码中如何声明交换机和绑定队列。可能需要提到使用RabbitMQ客户端库时的基本步骤,比如创建直连交换机、声明队列,然后使用队列绑定方法将队列与交换机通过绑定键关联起来。 此外,用户可能想知道直连交换机与其他类型交换机的区别,比如主题交换机允许模式匹配,而扇出交换机忽略路由键。这部分可以作为对比,帮助用户更好地理解直连交换机的适用场景。 最后,根据用户提供的引用内容,比如引用[3]和[4]中提到的消息确认机制和持久化,虽然不直接相关,但可能在回答中提到可靠性的问题,如确保消息正确路由后的确认处理,避免消息丢失。不过用户的问题集中在路由规则,所以这部分可以简要提及或作为扩展内容。 总结一下,回答的结构应该包括直连交换机的定义、路由规则、示例场景、与其他交换机的对比,以及可能的代码示例或配置步骤。需要确保使用正确的中文术语,并按照系统指令中的格式要求,使用行内公式和独立公式(如果有数学表达式的话),但在这个问题中可能不需要数学公式,所以可能不需要使用。另外,生成的相关问题需要围绕直连交换机使用、配置、与其他交换机的比较等展开。</think>### RabbitMQ直连交换机的路由规则 RabbitMQ直连交换机Direct Exchange)通过**精确匹配路由键(Routing Key)和绑定键(Binding Key)**来实现消息的路由[^3]。具体规则如下: 1. **绑定规则** 队列(Queue)在绑定到直连交换机时需指定一个**绑定键**(例如`error`)。生产者发送消息时需指定**路由键**(如`error`或`info`)。当路由键与绑定键完全匹配时,消息会被路由到对应的队列。 2. **匹配逻辑** - **完全匹配**:路由键必须与绑定键一致,区分大小写。例如:路由键为`warning`的消息只会被绑定键为`warning`的队列接收[^3]。 - **多队列绑定**:若多个队列使用相同的绑定键绑定到同一交换机,消息会被复制到所有匹配的队列(类似扇出行为)。 - **默认行为**:若未找到匹配的绑定键,消息会被丢弃(除非设置了备用交换器)。 3. **应用场景** 直连交换机适用于**按类别精确分发消息**的场景,例如: - 日志系统中,按日志级别(`info`/`error`)分发到不同队列; - 订单系统中,按订单状态(`paid`/`shipped`)路由消息。 4. **与其他交换机的对比** | 交换机类型 | 路由规则 | 典型用途 | |------------|----------|----------| | **Direct** | 精确匹配 | 按固定标签分类消息 | | Topic | 通配符匹配(如`user.*.log`) | 按模式分发(如多层级分类) | | Fanout | 广播到所有绑定队列 | 事件通知 | --- ### 代码示例(声明直连交换机并绑定队列) ```python # 使用Python客户端pika import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # 声明直连交换机 channel.exchange_declare(exchange='direct_logs', exchange_type='direct') # 声明队列并绑定绑定键 channel.queue_declare(queue='error_logs') channel.queue_bind(exchange='direct_logs', queue='error_logs', routing_key='error') # 发送消息时指定路由键 channel.basic_publish(exchange='direct_logs', routing_key='error', body='Error message') ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值