RabbitMq学习(三)TopicExchange在springboot的用法

配置

步骤类似于DirectExchange,但是我们在定义bindingKey时会用模糊字符串,以便于匹配消息发送者发送消息时用的routingKey
在这里插入图片描述

类似于上图,配置代码如下

package com.xquant.rabbitmq.send.mq;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * topic交换机模式
 * 
 * @author chunhui.tan
 * @version 创建时间:2018年11月15日 上午9:12:20
 *
 */
@Configuration
public class TopicMqConfig {

	/**
	 * 交换机名称
	 */
	public static final String TOPIC_EXCHANGE_NAME = "topic_exchange";

	/**
	 * 定义bindingKey,模糊匹配
	 */
	public static final String BINGDING_KEY_TEST1 = "*.orange.*";

	public static final String BINGDING_KEY_TEST2 = "*.*.rabbit";

	public static final String BINGDING_KEY_TEST3 = "lazy.#";

	/**
	 * 两个queue名字
	 */
	public static final String QUEUE_TEST1 = "topic_queue1";

	public static final String QUEUE_TEST2 = "topic_queue2";

	/**
	 * 构建topic类型交换机
	 * 
	 * @return
	 */
	@Bean
	public TopicExchange topicExchange() {
		return new TopicExchange(TOPIC_EXCHANGE_NAME, true, false);
	}

	/**
	 * 构建序列
	 * 
	 * @return
	 */
	@Bean
	public Queue test1Queue() {
		// 支持持久化
		return new Queue(QUEUE_TEST1, true);
	}

	@Bean
	public Queue test2Queue() {
		// 支持持久化
		return new Queue(QUEUE_TEST2, true);
	}

	/**
	 * 绑定交交换机和队列
	 * topic_queue1的bindingKey为:*.orange.*
	 * topic_queue2的bindingKey有两个:*.*.rabbit和lazy.#
	 * 
	 * @return
	 */
	@Bean
	public Binding test1Binding() {
		return BindingBuilder.bind(test1Queue()).to(topicExchange()).with(BINGDING_KEY_TEST1);
	}

	@Bean
	public Binding test2Binding() {
		return BindingBuilder.bind(test2Queue()).to(topicExchange()).with(BINGDING_KEY_TEST2);
	}

	@Bean
	public Binding test3Binding() {
		return BindingBuilder.bind(test2Queue()).to(topicExchange()).with(BINGDING_KEY_TEST3);
	}
	
	/**
	 * 配置
	 * 
	 * @return
	 */
	@Bean
	public ConnectionFactory connectionFactory() {
		CachingConnectionFactory connectionFactory = new CachingConnectionFactory("127.0.0.1", 5672);
		connectionFactory.setUsername("admin");
		connectionFactory.setPassword("123456");
		return connectionFactory;
	}

	/**
	 * 实例化操作模板
	 * 
	 * @param connectionFactory
	 * @return
	 */
	@Bean
	public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
		return new RabbitTemplate(connectionFactory);
	}
}

在上面的绑定关系中,如果我们发送的所有消息都是用来描述小动物的。发送的消息所携带的路由键是由三个单词所组成的,这三个单词被两个.分割开。路由键里的第一个单词描述的是动物的手脚的利索程度,第二个单词是动物的颜色,第三个是动物的种类
这三个绑定键被可以总结为:
topic_queue1 对所有的桔黄色动物都感兴趣。
topic_queue2 则是对所有的兔子和所有懒惰的动物感兴趣

生产者

为了方便测试,写在接口里面

/**
 * routingKey:quick.orange.rabbit
 * 
 * @return
 */
@GetMapping("/sendMessage1")
public Object sendMessage1() {
	MessageProperties messageProperties = new MessageProperties();
	messageProperties.setContentEncoding("UTF-8");
	Message message = new Message("我是一个跑的飞快的橘黄色的兔子,谁会收到这条消息呢,".getBytes(), messageProperties);
	rabbitTemplate.send(TopicMqConfig.TOPIC_EXCHANGE_NAME, "quick.orange.rabbit", message);
	return "ok";
}

/**
 * routingKey:lazy.orange.elephant
 * 
 * @return
 */
@GetMapping("/sendMessage2")
public Object sendMessage2() {
	MessageProperties messageProperties = new MessageProperties();
	messageProperties.setContentEncoding("UTF-8");
	Message message = new Message("我是一只橘黄色的懒惰大象,谁会收到这条消息呢,".getBytes(), messageProperties);
	rabbitTemplate.send(TopicMqConfig.TOPIC_EXCHANGE_NAME, "lazy.orange.elephant", message);
	return "ok";
}

/**
 * routingKey:lazy.read.mela.rabbit
 * 
 * @return
 */
@GetMapping("/sendMessage3")
public Object sendMessage3() {
	MessageProperties messageProperties = new MessageProperties();
	messageProperties.setContentEncoding("UTF-8");
	Message message = new Message("我是一只懒惰的红色的公兔子,谁会收到这条消息呢".getBytes(), messageProperties);
	rabbitTemplate.send(TopicMqConfig.TOPIC_EXCHANGE_NAME, "lazy.read.mela.rabbit", message);
	return "ok";
}

/**
 * routingKey:orange
 * 
 * @return
 */
@GetMapping("/sendMessage4")
public Object sendMessage4() {
	MessageProperties messageProperties = new MessageProperties();
	messageProperties.setContentEncoding("UTF-8");
	Message message = new Message("我是橘黄色的,谁会收到这条消息呢,".getBytes(), messageProperties);
	rabbitTemplate.send(TopicMqConfig.TOPIC_EXCHANGE_NAME, "orange", message);
	return "ok";
}

/**
 * routingKey:quick.orange.male.rabbit
 * 
 * @return
 */
@GetMapping("/sendMessage5")
public Object sendMessage5() {
	MessageProperties messageProperties = new MessageProperties();
	messageProperties.setContentEncoding("UTF-8");
	Message message = new Message("我是橘黄色的跑的快的公兔子,谁会收到这条消息呢,".getBytes(), messageProperties);
	rabbitTemplate.send(TopicMqConfig.TOPIC_EXCHANGE_NAME, "quick.orange.male.rabbit", message);
	return "ok";
}

消费者

分别监听两个队列

/**
 * 监听test1队列
 * 
 * @param message
 * @throws UnsupportedEncodingException
 */
@RabbitListener(queues = TopicMqConfig.QUEUE_TEST1)
public void consumeMessage1(Message message) throws UnsupportedEncodingException {
	System.out.println("这是监听QUEUE_TEST1得到的消息:======" + new String(message.getBody(), "utf-8"));
}

/**
 * 监听test1队列
 * 
 * @param message
 * @throws UnsupportedEncodingException
 */
@RabbitListener(queues = TopicMqConfig.QUEUE_TEST2)
public void consumeMessage2(Message message) throws UnsupportedEncodingException {
	System.out.println("这是监听QUEUE_TEST2得到的消息:======" + new String(message.getBody(), "utf-8"));
}

测试

启动项目,查看rabbitMq的Web页面
在这里插入图片描述

绑定信息已经展示的很清楚了。
接下来我们依次访问接口

测试1

访问http://localhost:8080/sendMessage1接口,这时候会发送消息:“我是一个跑的飞快的橘黄色的兔子,谁会收到这条消息呢,”,routingKey为:“quick.orange.rabbit”,显然这会匹配到queue1和queue2,结果如下控制台打印:
在这里插入图片描述

测试2

访问http://localhost:8080/sendMessage2接口,这时候会发送消息:“我是一只橘黄色的懒惰大象,谁会收到这条消息呢,”,routingKey为:“lazy.orange.elephant”,这样的话也会同事匹配到queue1和queue2,结果如下控制台打印:
在这里插入图片描述

测试3

访问http://localhost:8080/sendMessage3接口,这时候会发送消息:“我是一只懒惰的红色的公兔子,谁会收到这条消息呢,”,routingKey为:“lazy.read.mela.rabbit”,这样的话只能匹配到queue2,因为queue2的其中一个bindingKey为:“lazy.#”,结果如下控制台打印:
在这里插入图片描述

测试4

访问http://localhost:8080/sendMessage4接口,这时候会发送消息:“我是橘黄色的,谁会收到这条消息呢,”,routingKey为:“orange”,这样是匹配不到任何queue的,消息直接丢失,结果如下控制台打印(无任何反应):
在这里插入图片描述

测试五

访问http://localhost:8080/sendMessage4接口,这时候会发送消息:“我是橘黄色的跑的快的公兔子,谁会收到这条消息呢,”,routingKey为:“quick.orange.male.rabbit”,这样是匹配不到任何queue的,消息直接丢失,结果如下控制台打印(无任何反应):
在这里插入图片描述

总结

topic这个规则是模糊匹配,可以通过通配符满足一部分规则就可以传送消息
发送到主题交换机(topic exchange)的消息不可以携带随意什么样子的路由键(routingKey),它的路由键必须是一个由.(英文的句号)分隔开的词语列表。这些单词随便是什么都可以,但是最好是跟携带它们的消息有关系的词汇。以下是几个推荐的例子:“stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”。词语的个数可以随意,但是不要超过255字节。
* (星号) 用来表示一个单词
# (井号) 用来表示任意数量(零个或多个)单词。
同时匹配一个队列的两个绑定,消息也只会给这个队列发一次。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: RabbitMQ是一个基于AMQP协议的消息中间件,提供了丰富的Exchange(交换机)类型来进行消息的路由和分发。其中,topic类型的交换机可以根据消息的routing key来进行灵活的匹配和分发。 在Spring Boot中使用RabbitMQtopic类型交换机,首先需要在配置文件中配置RabbitMQ的连接信息,如主机地址、端口号、用户名、密码等。 其次,需要创建一个RabbitMQ的配置类,使用@Configuration注解进行标识,并使用@EnableRabbit注解启用RabbitMQ相关的配置。在配置类中,可以使用@Bean注解创建一个RabbitTemplate的实例,用于发送和接收消息。 接下来,在生产者中,可以使用@Autowired注解注入RabbitTemplate实例,并调用其convertAndSend方法发送消息到指定的交换机和routing key。生产者可以根据具体的业务需求设置不同的routing key,用于消息的匹配和分发。 在消费者中,同样可以使用@Autowired注解注入RabbitTemplate实例,并调用其receiveAndConvert方法接收消息。消费者需要在配置类中使用@RabbitListener注解,指定要监听的队列,并根据需要设置不同的routing key或通配符进行匹配。 通过Spring Boot中的自动配置,我们可以方便地使用RabbitMQtopic类型交换机进行消息的发布和订阅。同时,使用Spring AMQP提供的注解和模板类,可以简化开发过程,提高代码的可读性和可维护性。 需要注意的是,使用topic类型交换机时,routing key是由一个或多个单词组成的字符串,用点号(.)进行分隔。其中,单词可以包含字母、数字或通配符(#和*)。#用于匹配零个或多个单词,*用于匹配一个单词。 总之,通过使用RabbitMQtopic类型交换机和Spring Boot提供的自动配置和注解,我们可以方便地实现消息的灵活路由和分发,满足不同业务场景的需求。 ### 回答2: RabbitMQ是一个开源的消息中间件,用于实现可靠的消息传递。它使用AMQP(高级消息队列协议)作为消息传输协议,并通过交换机来路由消息。 Topic类型的交换机在RabbitMQ中是一种灵活的交换机类型。它通过使用通配符的方式将消息路由到与匹配的路由键相关联的队列。使用Spring Boot框架与RabbitMQ集成,可以方便地实现Topic类型的交换机。 首先,在Spring Boot项目中引入RabbitMQ的依赖,例如: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 然后,配置RabbitMQ的连接信息,例如: ```yaml spring: rabbitmq: host: localhost port: 5672 username: guest password: guest ``` 接下来,在代码中创建一个Topic类型的交换机,例如: ```java @Configuration public class RabbitMQConfig { private static final String TOPIC_EXCHANGE_NAME = "topicExchange"; @Bean public TopicExchange topicExchange() { return new TopicExchange(TOPIC_EXCHANGE_NAME); } } ``` 然后,创建一个消费者来监听队列中的消息,例如: ```java @Component public class MessageListener { private static final String QUEUE_NAME = "messageQueue"; private static final String ROUTING_KEY = "message.*"; @RabbitListener(queues = QUEUE_NAME) public void handleMessage(String message) { System.out.println("Received message: " + message); } } ``` 最后,通过发送消息的方式来测试Topic类型的交换机,例如: ```java @Service public class MessageService { private static final String ROUTING_KEY = "message.test"; @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend(TOPIC_EXCHANGE_NAME, ROUTING_KEY, message); } } ``` 以上是使用Spring Boot与RabbitMQ实现Topic类型交换机的基本步骤。通过配置交换机、监听队列和发送消息,可以实现灵活的消息路由机制,满足不同的业务需求。 ### 回答3: RabbitMQ是一种开源的消息代理,用于在分布式系统之间传递消息。它支持多种类型的交换机,其中之一就是Topic类型。 在使用Spring Boot集成RabbitMQ时,我们可以通过配置文件或代码的方式来定义Topic类型的交换机。 首先,在配置文件中我们需要定义RabbitMQ的连接信息,如主机名、端口号、用户名和密码等。同时,我们也需要配置交换机的相关信息,包括交换机名称、类型和持久化等。 例如,我们可以在application.properties文件中添加以下配置: spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest spring.rabbitmq.template.exchange=myExchange spring.rabbitmq.template.routing-key=myTopic 上述配置中,我们定义了RabbitMQ的连接信息和交换机的相关信息。其中,exchange为我们自定义的交换机名称,routing-key为我们自定义的Topic名称。 接下来,在代码中我们可以通过使用注解的方式,将RabbitTemplate对象注入到我们的业务逻辑中。然后,通过调用RabbitTemplate对象的convertAndSend方法来发送消息。 例如,我们可以通过以下方式来发送消息: @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("myExchange", "myTopic", message); } 上述代码中,我们通过调用rabbitTemplate对象的convertAndSend方法来发送消息。其中,第一个参数为交换机名称,第二个参数为Topic名称,第个参数为要发送的消息内容。 总结一下,通过配置文件和代码的方式,我们可以在Spring Boot中使用RabbitMQTopic类型交换机。只需要定义好RabbitMQ的连接信息和交换机的相关信息,然后调用RabbitTemplate对象的convertAndSend方法来发送消息即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值