Springboot集成Rabbitmq
环境搭建
- 创建SpringBoot项目
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
- 编写application.yml配置文件
spring:
application:
name: rabbitmq-application
rabbitmq:
host: 192.168.192.130
port: 5672
username: user
password: 123456
virtual-host: /test
直连模式
无交换机,一对一模型,一个服务提供者,一个消息队列,一个消费者.
- 生产者发送消息
@Test
public void test_hello(){
//参数为队列名称、要发送的消息
rabbitTemplate.convertAndSend("hello","最简单的直连模式");
}
- 消费者接收消息
@Component
@RabbitListener(queuesToDeclare = @Queue(value = "hello"))
public class HelloConsumer {
@RabbitHandler //代表该方法处理队列中的方法
public void receive(String message){
System.out.println("message="+message);
}
}
@Queue中的属性,如果不配置的话,默认就是持久化、非独占、不自动删除的队列。
工作队列模式
无交换机,一对多模型,一个服务提供者,一个消息队列,多个消费者。默认情况消息被一条一条平均分配给每一个消费者消费。
- 生产者发送消息
@Test
public void test_work(){
for (int i=1;i<=10;i++){
rabbitTemplate.convertAndSend("work","这是work模型发的"+i);
}
}
- 消费者接收消息
该处一个类构造了两个消费者,也可以分开
@Component
public class WorkConsumer {
@RabbitListener(queuesToDeclare = @Queue(value = "work"))
public void test1(String msg){
System.out.println("消费者1:"+msg);
}
@RabbitListener(queuesToDeclare = @Queue(value = "work"))
public void test2(String msg){
System.out.println("消费者2:"+msg);
}
}
广播模型
fanout模型(广播模型):有交换机,一个生产者,多个消费者。生产者将信息发送给交换机,由交换机发送消息给临时队列,每个消费者对应一个临时队列。交换机会将消息放松给绑定过的所有队列,实现一条消息被多个消费者消费。
- 生产者生产消息
@Test
public void test_fanout(){
rabbitTemplate.convertAndSend("fanout_test","","fanout发送的消息");
}
- 消费者接收消息
@Component
public class FanoutConsumer {
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue, //创建临时队列
exchange = @Exchange(value = "fanout_test",type = "fanout") //绑定的交换机
)
})
public void test1(String msg){
System.out.println("消费者1:"+msg);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue, //创建临时队列
exchange = @Exchange(value = "fanout_test",type = "fanout") //绑定的交换机
)
})
public void test2(String msg){
System.out.println("消费者2:"+msg);
}
}
路由模型——Direct模型
跟广播模型类似,其主要是添加了一些路由规则。在广播模型中生产者的消息要发送给每一个消费者。但是在路由——direct模型中,可以实现不同的消息发送给不同的消费者。在Direct模型下,生产者在发送消息时,必须要对消息指定Routing key,消费者的临时队列与交换机的绑定也不再是任意的,需要指定Routing key。这样就可以实现消息路由。比如以下例子实现Consumer1接收error消息,Conusmer2可以接收error、info、debug消息。
- 生产者生产消息
@Test
public void test_route(){
rabbitTemplate.convertAndSend("direct_test","error","route_direct发送的消息");
}
- 消费者接收消息
@Component
public class RouteConsumer {
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "direct_test",type = "direct"),
key = {"info","error","debug"}
)
})
public void test1(String msg){
System.out.println("我是消费者1:"+msg);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "direct_test",type = "direct"),
key = {"info"}
)
})
public void test2(String msg){
System.out.println("我是消费者2:"+msg);
}
}
路由模型——Topic模型
Direct模型的拓展,支持统配的路由。临时队列和交换机绑定时可以将routing key写成通配符的情况。.
代表单词间的分隔符,*
代表一个单词,#
代表一个或多个单词。比如消费者routingkey可以是*.hello.#,表示hello前可以有一个单词,后面可以有多个单词。
- 生产者生产消息
@Test
public void test_topic(){
rabbitTemplate.convertAndSend("topics","a.user","route_topic发送的消息");
}
- 消费者接收消息
@Component
public class TopicConsumer {
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "topic_test",type = "topic"),
key = {"user.*"}
)
})
public void test1(String msg){
System.out.println("消费者1:"+msg);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "topic_test",type = "topic"),
key = {"*.user"}
)
})
public void test2(String msg){
System.out.println("消费者2:"+msg);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "topic_test",type = "topic"),
key = {"user.#"}
)
})
public void test3(String msg){
System.out.println("消费者3:"+msg);
}
}