介绍和安装
安装部署
利用docker
docker run \
-e RABBITMQ_DEFAULT_USER=orange \
-e RABBITMQ_DEFAULT_PASS=123321 \
-v mq-plugins:/plugins \
--name mq \
--hostname mq \
-p 15672:15672 \
-p 5672:5672 \
--network hm-net\
-d \
rabbitmq:3.8-management
基本介绍
RabbitMQ的整体架构及核心概念:
- publisher:生产者,也就是发送消息的一方
- consumer:消费者,也就是消费消息的一方
- queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理
- exchange:交换机,负责消息路由。生产者发送的消息由交换机决定投递到哪个队列。
- virtual host:虚拟主机,起到数据隔离的作用。每个虚拟主机相互独立,有各自的exchange、queue
快速入门
添加队列
在交换机里模拟发消息
但是在此之前需要先让交换机绑定队列
注意
- 交换机只能路由消息,无法存储消息
- 交换机只会路由消息给与其绑定的队列,因此队列必须与交换机绑定
数据隔离
添加一个新用户
然后切换用户,创建自己的虚拟主机
Java客户端
将来我们开发业务功能的时候,肯定不会在控制台收发消息,而是应该基于编程的方式。由于RabbitMQ
采用了AMQP协议,因此它具备跨语言的特性。任何语言只要遵循AMQP协议收发消息,都可以与RabbitMQ
交互。并且RabbitMQ
官方也提供了各种不同语言的客户端。
但是,RabbitMQ官方提供的Java客户端编码相对复杂,一般生产环境下我们更多会结合Spring来使用。而Spring的官方刚好基于RabbitMQ提供了这样一套消息收发的模板工具:SpringAMQP。并且还基于SpringBoot对其实现了自动装配,使用起来非常方便。
快速入门
1.引入spring-amqp依赖
在父工程中引入spring-amqp依赖,这样publisher和consumer服务都可以使用: .
<!--AMQP依赖,包含RabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.配置RabbitMQ服务端地址
在每个微服务中引入MQ服务端信息,这样微服务才能连接到RabbitMQ
spring:
rabbitmq:
host: 192.168.21.129 # 你的虚拟机IP
port: 5672 # 端口
virtual-host: /hmall # 虚拟主机
username: hamll # 用户名
password: 123 # 密码
3.发送消息
SpringAMQP提供了RabbitTemplate工具类,方便我们发送消息。发送消息代码如下:
@SpringBootTest
public class SpringAmqpTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSimpleQueue() {
// 队列名称
String queueName = "simple.queue";
// 消息
String message = "hello, spring amqp!";
// 发送消息
rabbitTemplate.convertAndSend(queueName, message);
}
}
4.接受消息
SpringAMQP提供声明式的消息监听,我们只需要通过注解在方法上声明要监听的队列名称,将来SpringAMQP就会把消息传递给当前方法:
public class SpringRabbitListener {
@RabbitListener(queues = "simple.queue")
public void listenSimpleQueue(String message){
log.info("监听到simple.queue的消息:【{}】",message);
}
}
WorkQueue
Work queues,任务模型。简单来说就是让多个消费者绑定到- -个队列,共同消费队列中的消息。
@RabbitListener(queues = "work.queue")
public void listenWorkQueue1(String message){
System.out.println("消费者1接受到消息:"+message+" "+ LocalTime.now());
}
@RabbitListener(queues = "work.queue")
public void listenWorkQueue2(String message){
System.err.println("消费者2.......接受到消息:"+message+" "+ LocalTime.now());
}
@Test
public void testWorkQueue(){
//队列名
String queueName = "work.queue";
for (int i = 1; i <=50; i++) {
//消息
String message = "hello,spring amqp_" +i;
//发送消息
rabbitTemplate.convertAndSend(queueName,message);
}
}
消费者消息推送限制
默认情况下,RabbitMQ的会将消息依次轮询投递给绑定在队列上的每一个消费者。 但这并没有考虑到消费者是否已经处理完消息,可能出现消息堆积。
因此我们需要修改application.yml,设置preFetch值为1,确保同一时刻最多投递给消费者1条消息: