Docker安装RabbitMQ
docker pull rabbitmq:3.10-management
如果你的主机上没有rabbimq,可以下载rabbitmq:xxx-management这种版本的,启动起来比较方便。
下载完镜像之后,启动:
docker run --name rabbitmq -d -p 15672:15672 -p 5672:5672 rabbitmq:3.10-management
这个时候,你就可以直接去访问rabbitmq的web端页面了,http://你的主机host:15672/
。
看到该页面,即表示安装成功。默认username和password:guest
注意:如果你是在云服务器上安装,请在云服务中开放15672和5672的端口。
SpringBoot整合RabbitMQ
- 添加依赖
<!-- rabbitmq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
- 在启动类中添加注解
@EnableRabbit
- 编写配置文件
spring:
rabbitmq:
host: your host
port: 5672
virtual-host: / # 不写默认就是 /
- 这个时候,就可以去创建及绑定交换机、队列等操作了
整合了SpringBoot之后,这个步骤变得非常的简单方便,只需要创建一个配置类,通过@Bean注解去创建队列或交换机即可。
@Configuration
public class RabbitMqConfig {
/**
* 创建一个交换机
* book.add.view.exchange
*/
@Bean
public Exchange bookAddViewExchange() {
// 这里可以指定创建交换机类型 你也可以去new TopicExchange("exchange name")
return new DirectExchange("book.add.view.exchange");
}
/**
* 创建一个普通队列
* book.add.view.queue
*/
@Bean
public Queue bookAddViewQueue() {
// 参数1:队列名
// 参数2:是否采用持久化机制
// 参数3和参数4:一般都是false
return new Queue("book.add.view.queue", true, false, false);
}
/**
* 延迟队列
* book.add.view.delay.queue
*/
@Bean
public Queue bookAddViewDelayQueue() {
// 添加延迟队列的一些参数
Map<String, Object> map = new HashMap<String, Object>();
map.put("x-dead-letter-exchange", "book.add.view.exchange"); // 绑定死信交换机
map.put("x-dead-letter-routing-key", "book.add.view"); // 绑定死信交换机路由key
map.put("x-message-ttl", 5000L); // ttl: 5s
return new Queue("book.add.view.delay.queue", true, false, false, map);
}
/**
* 将队列与交换机绑定
*/
@Bean
public Binding bookAddViewDelayQueueWithBookAddViewExchange() {
return new Binding(
"book.add.view.delay.queue", // 队列名
Binding.DestinationType.QUEUE,
"book.add.view.exchange", // 交换机名
"book.clicked", // 绑定它们的routing-key
null
);
}
/**
* 将队列与交换机绑定
*/
@Bean
public Binding bookAddViewQueueWithBookAddViewExchange() {
return new Binding(
"book.add.view.queue",
Binding.DestinationType.QUEUE,
"book.add.view.exchange",
"book.add.view",
null
);
}
}
在上述,创建了一个交换机、一个延迟队列和一个普通队列。该交换机也充当了死信交换机。
- 发送routing-key为book.clicked的消息会被交换机转发到延迟队列;
- 延迟队列设置TTL:5s,消息过期之后会将该消息转发到交换机中,并携带routing-key为book.add.view;
- routing-key为book.add.view的消息最终会被转发到普通队列中。
- 启动服务,我们可以看到刚刚创建的交换机和队列
注意,这里如果在代码无误的情况下,你并没有在页面发现新创建的交换机和队列,不要着急,继续下面的步骤,这是因为在第一次创建时,要进行一次消息的发送和监听,这些交换机和队列才会被创建在页面中展示。
- 发送消息进行测试
@PutMapping("/add/{id}")
public R addViewCount(@PathVariable("id") Long id) {
// 参数1:消息发送到的交换机
// 参数2:发送该消息携带的routing-key
// 参数3:消息
rabbitTemplate.convertAndSend("book.add.view.exchange", "book.clicked", id);
return R.ok();
}
-
测试一下,发送两条routing-key为book.clicked的消息,该消息会被交换机转发到我们创建的延迟队列book.add.view.delay.queue中。
当我们延迟队列消息过期之后,会将消息重新发送到交换机,交换机再转发到我们普通队列book.add.view.queue中。
-
写一个监听器去监听该队列,处理队列中的消息
@Component
public class AddBookViewListener {
@RabbitListener(queues = "book.add.view.queue")
@RabbitHandler
public void addBookViewCount(Long bookId, Message message, Channel channel) {
System.out.println(bookId);
}
}
@RabbitListener
,使用该注解来监听指定的队列,也可以作用代类上,表示该类所有带@RabbitHandler
的方法都可以监听处理该队列的消息;作用在方法上,指定该方法监听的队列。
我们可以通过上述方法的参数1直接获得接收的消息体,如果我们发送的消息是一个User类型的对象,那么这里的参数也可以直接写User user接收。
使用channel对象可以进行一些手动ack或者拒绝消息的一些操作。
再次发送消息进行测试
查看控制台输出