这篇博客本人最近在使用RabbitMq队列的总结经验。
配置RabbitMq队列可以分为以下几种形式:
第一种:在基于在windows环境下安装有RabbitMq客户端的情况下,可以直接进行界面化操作进行进行创建队列,创建交换机,以及将队列绑定到交互机上。
这种方法,比较简单,这里主要讲述在springboot基于配置的方式整合RabbitMq.
第二种:是整合springboot进行配置使用。
第一步:需要引入对应的依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
第二步:在application.properties中配置关于RabbitMQ的连接和用户信息(这一部分是本人的配置)
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
publisher-confirms: true # 消息发送到交换机确认机制,是否确认回调
第三步是对于队列的配置了:
RabbitMq有三种队列,相对应的就有三种不同的配置:
1.直接模式 direct
-
任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue。
-
/** * 创建一个直接模式 direct * 这种模式是不需要指定交换机(因为是使用rabbitMQ自带的Exchange:""(该Exchange的名字为空字符串,我们称其为default Exchange)) **/ @Configuration public class DefaultMQConfig { @Bean public Queue oneQueue(){ return new Queue("DefaultMQ"); } } /** * 消息接收端 **/ @Component public class DefaultMQSender { @Autowired AmqpTemplate rabbitTemplate; public void send() { String context = "DefaultMQSender" + new Date(); System.out.println("DefaultMQ====> sender: " + context); this.rabbitTemplate.convertAndSend("DefaultMQ", context); } } /** * 处理消息端 **/ @Component @RabbitListener(queues = "DefaultMQ") public class DefaultMQReceiver { @RabbitHandler public void receiver(String context){ System.out.println("DefaultMQ+++++Receiver =====> "+context); } }
-
/** * 创建一个直接模式 direct * 这种模式是不需要指定交换机(因为是使用rabbitMQ自带的Exchange:""(该Exchange的名字为空字符串,我们称其为default Exchange)) **/ @Configuration public class DefaultMQConfig { @Bean public Queue oneQueue(){ return new Queue("DefaultMQ"); } } /** * 消息接收端 **/ @Component public class DefaultMQSender { @Autowired AmqpTemplate rabbitTemplate; public void send() { String context = "DefaultMQSender" + new Date(); System.out.println("DefaultMQ====> sender: " + context); this.rabbitTemplate.convertAndSend("DefaultMQ", context); } } /** * 处理消息端 **/ @Component @RabbitListener(queues = "DefaultMQ") public class DefaultMQReceiver { @RabbitHandler public void receiver(String context){ System.out.println("DefaultMQ+++++Receiver =====> "+context); } }
2.Fanout Exchange
-
Fanout 就是我们熟悉的广播模式或者订阅模式,给Fanout交换机发送消息,绑定了这个交换机的所有队列都收到这个消息。
/** * fanout配置类 * 这里分别配置了三个队列 绑定了相对应的交换器 **/ @Configuration public class FanoutConfig { //队列1 @Bean public Queue fanoutQueue1(){ return new Queue("fanout.a"); } //队列2 @Bean public Queue fanoutQueue2(){ return new Queue("fanout.b"); } //队列3 @Bean public Queue fanoutQueue3(){ return new Queue("fanout.c"); } //交换器 @Bean FanoutExchange fanoutExchange(){ return new FanoutExchange("fanoutExchange"); } //绑定交换器和队列1 @Bean Binding bindingFanout1(){ return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange()); } //绑定交换器和队列2 @Bean Binding bindingFanout2(){ return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange()); } //绑定交换器和队列3 @Bean Binding bindingFanout3(){ return BindingBuilder.bind(fanoutQueue3()).to(fanoutExchange()); } }
/** * 消息发送端 **/ @Component public class FanoutSender { @Autowired AmqpTemplate rabbitTemplate; public void fanSender1(){ Date date = new Date(); String dateString = new SimpleDateFormat("yyyy-mm-DD hh:MM:ss").format(date); String message = "FanSender1111:"+dateString; this.rabbitTemplate.convertAndSend("fanoutExchange","",message); } public void fanSender2(){ Date date = new Date(); String dateString = new SimpleDateFormat("yyyy-mm-DD hh:MM:ss").format(date); String message = "FanSender2222:"+dateString; this.rabbitTemplate.convertAndSend("fanoutExchange","",message); } }
/** * 消息接收端 **/ @Component @RabbitListener(queues = "fanout.a") public class Fanout1Reciver { @RabbitHandler public void receiver(String message){ System.out.println("FanoutReceiver---fanout.a:"+message); } } @Component @RabbitListener(queues = "fanout.b") public class Fanout2Reciver { @RabbitHandler public void receiver(String message){ System.out.println("FanoutReceiver---fanout.b:"+message); } } @Component @RabbitListener(queues = "fanout.c") public class Fanout3Reciver { @RabbitHandler public void receiver(String message){ System.out.println("FanoutReceiver---fanout.c:"+message); } }
3.Topic Exchange
- topic 是RabbitMQ中最灵活的一种方式,可以根据routing_key自由的绑定不同的队列。 首先对topic规则配置,这里使用两个队列来测试
/**
* topic配置类
* 这里配置一个topic的转换机 , 然后三种接收队列同时都绑定到了这个交换机上,但是根据绑定是配置的routing_key,消息会发送到不同的队列中
**/
@Configuration
public class TopicConfig {
@Bean
public Queue topicQueueQQ(){
return new Queue("topic.qq");
}
@Bean
public Queue topicQueue163(){
return new Queue("topic.163");
}
@Bean
public Queue topicQueueSINA(){
return new Queue("topic.sina");
}
@Bean
TopicExchange topicExchange(){
return new TopicExchange("topicExchange");
}
//在绑定的过程中多了一个条件with,这是一种通配符方式的匹配,. 为分隔符,*代表一个,#表示0个或者多个,如上面的topic.#就可已匹配,topic,topic.z,topic.ma.z.z.z等,而topic.*.z就可以匹配topic.m.z,topic.z.z等,而topic.msg就只能匹配topic.msg条件的消息。
@Bean
public Binding bindingQQ(){
return BindingBuilder.bind(topicQueueQQ()).to(topicExchange()).with("topic.qq.#");
}
@Bean
public Binding binding163(){
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic.163.#");
}
@Bean
public Binding bindingSINA(){
return BindingBuilder.bind(topicQueueSINA()).to(topicExchange()).with("topic.sina.#");
}
}
/**
* 消息发送端
**/
@Component
public class TopicSender {
@Autowired
private AmqpTemplate rabbitTemplate;
public void topicSendQQ(){
Date date = new Date();
String dateString = new SimpleDateFormat("yyyy-mm-DD hh:MM:ss").format(date);
dateString = "[topic.qq.msg] Send QQ msg:" + dateString;
System.out.println(dateString);
this.rabbitTemplate.convertAndSend("topicExchange","topic.qq.msg",dateString);
}
public void topicSend163(){
Date date = new Date();
String dateString = new SimpleDateFormat("yyyy-mm-DD hh:MM:ss").format(date);
dateString = "[topic.163.msg] Send163 msg:" + dateString;
System.out.println(dateString);
this.rabbitTemplate.convertAndSend("topicExchange","topic.163.msg",dateString);
}
public void topicSendSINA(){
Date date = new Date();
String dateString = new SimpleDateFormat("yyyy-mm-DD hh:MM:ss").format(date);
dateString = "[topic.sina.msg] Send sina msg:" + dateString;
System.out.println(dateString);
this.rabbitTemplate.convertAndSend("topicExchange","topic.sina.msg",dateString);
}
/**
* 消息接收端
**/
@Component
@RabbitListener(queues = "topic.qq")
public class TopicQQReciver {
@RabbitHandler
public void receiver(String message){
System.out.println("topic.qq--Receiver::::"+message);
}
}
@Component
@RabbitListener(queues = "topic.163")
public class Topic163Reciver {
@RabbitHandler
public void receiver(String msg){
System.out.println("topic.163--Receiver::::"+msg);
}
}
@Component
@RabbitListener(queues = "topic.sina")
public class TopicSINAReciver {
@RabbitHandler
public void receiver(String msg){
System.out.println("topic.SINA--Receiver::::"+msg);
}
}
使用总结:
总体使用的过程中,我觉得RabbitMq的整合springboot配置使用,总共分为一下几步,只要以下几步没有出错,基本上是没有问题的。
1.创建队列
2.创建交换机
3.将交换机绑定到相对应接收消息的队列上
4.创建消息发送端和消息接收端(@RabbitListener(queues = “{这里填写你要接收的队列名}”))即可