面试官:你说你会RabbitMQ,那聊聊它的交换机

channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);

log.info(“消息已确认”);

}

}

这两段代码都很好理解,不再赘述。

其中发送消息的代码有三个参数,第一个参数是Exchange的名称,第二个参数是routingKey的名称,这个参数在扇形交换机里面用不到,在其他两个交换机类型里面会用到。

代码的准备到此结束,我们可以运行发送方法之后run一下了~

项目启动后,我们可以先来观察一下队列与交换机的绑定关系有没有生效,我们在RabbitMQ控制台使用rabbitmqctl list_bindings命令查看绑定关系。

![](https://imgconvert.csdnimg.cn/aHR0 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8xNzE3OTczMS1iMjc4MTcwZWFiNjc0OTMzLnBuZw?x-oss-process=image/format,png)

关键部分我用红框标记了起来,这就代表着名叫fanoutExchange的交换机绑定着两个队列,一个叫fanout1,另一个叫fanout2

紧接着,我们来看控制台的打印情况:

可以看到,一条信息发送出去之后,两个队列都接收到了这条消息,紧接着由我们的两个消费者消费。

Tip: 如果你的演示应用启动之后没有消费信息,可以尝试重新运行一次生产者的方法发送消息。

[](()3. Direct-Exchange


Direct-Exchange是一种精准匹配的交换机,我们之前一直使用默认的交换机,其实默认的交换机就是Direct类型。

如果将Direct交换机都比作一所公寓的管理员,那么队列就是里面的住户。(绑定关系)

管理员每天都会收到各种各样的信件(消息),这些信件的地址不光要标明地址(ExchangeKey)还需要标明要送往哪一户(routingKey),不然消息无法投递。

以上图为例,准备一条消息发往名为SendService的直接交换机中去,这个交换机主要是用来做发送服务,所以其绑定了两个队列,SMS队列和MAIL队列,用于发送短信和邮件。

我们的消息除了指定ExchangeKey还需要指定routingKeyroutingKey对应着最终要发送的是哪个队列,我们的示例中的routingKey是sms,这里这条消息就会交给SMS队列。


听了上面这段,可能大家对routingKey还不是很理解,我们上段代码实践一下,大家应该就明白了。

准备工作:

@Bean

public Queue directQueue1() {

return new Queue(“directQueue1”);

}

@Bean

public Queue directQueue2() {

return new Queue(“directQueue2”);

}

@Bean

public DirectExchange directExchange() {

// 三个构造参数:name durable autoDelete

return new DirectExchange(“directExchange”, false, false);

}

@Bean

public Binding directBinding1() {

return BindingBuilder.bind(directQueue1()).to(directExchange()).with(“sms”);

}

@Bean

public Binding directBinding2() {

return BindingBuilder.bind(directQueue2()).to(directExchange()).with(“mail”);

}

新建两个队列,新建了一个直接交换机,并设置了绑定关系。

这里的示例代码和上面扇形交换机的代码很像,唯一可以说不同的就是绑定的时候多调用了一个withroutingKey设置了上去。

所以是交换机和队列建立绑定关系的时候设置的routingKey,一个消息到达交换机之后,交换机通过消息上带来的routingKey找到自己与队列建立绑定关系时设置的routingKey,然后将消息分发到这个队列去。

生产者:

public void sendDirect() {

Client client = new Client();

log.info("Message content : " + client);

rabbitTemplate.convertAndSend(“directExchange”,“sms”,client);

System.out.println(“消息发送完毕。”);

}

消费者:

@Slf4j

@Component(“rabbitDirectConsumer”)

public class RabbitDirectConsumer {

@RabbitListener(queues = “directQueue1”)

public void onMessage1(Message message, Channel channel) throws Exception {

log.info("Message content : " + message);

channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);

log.info(“消息已确认”);

}

@RabbitListener(queues = “directQueue2”)

public void onMessage2(Message message, Channel channel) throws Exception {

log.info("Message content : " + message);

channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);

log.info(“消息已确认”);

}

}

效果图如下:

只有一个消费者进行了消息,符合我们的预期。

[](()4. Topic-Exchange


Topic-Exchange是直接交换机的模糊匹配版本,Topic类型的交换器,支持使用"*“和”#"通配符定义模糊bindingKey,然后按照routingKey进行模糊匹配队列进行分发。

  • *:能够模糊匹配一个单词。

  • #:能够模糊匹配零个或多个单词。

因为加入了两个通配定义符,所以Topic交换机的routingKey也有些变化,routingKey可以使用.将单词分开。


这里我们直接来用一个例子说明会更加的清晰:

准备工作:

// 主题交换机示例

@Bean

public Queue topicQueue1() {

return new Queue(“topicQueue1”);

}

@Bean

public Queue topicQueue2() {

return new Queue(“topicQueue2”);

}

@Bean

public TopicExchange topicExchange() {

// 三个构造参数:name durable autoDelete

return new TopicExchange(“topicExchange”, false, false);

}

@Bean

public Binding topicBinding1() {

return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with(“sms.*”);

}

@Bean

public Binding topicBinding2() {

return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with(“mail.#”);

}

新建两个队列,新建了一个Topic交换机,并设置了绑定关系。

这里的示例代码我们主要看设置routingKey,这里的routingKey用上了通配符,且中间用.隔开,这就代表topicQueue1消费sms开头的消息,topicQueue2消费mail开头的消息,具体不同往下看。

生产者:

public void sendTopic() {

Client client = new Client();

log.info("Message content : " + client);

rabbitTemplate.convertAndSend(“topicExchange”,“sms.liantong”,client);

System.out.println(“消息发送完毕。”);

}

消费者:

@Slf4j

@Component(“rabbitTopicConsumer”)

public class RabbitTopicConsumer {

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值