1.概念
1.1名词.
1.2准备
以下皆为springboot版代码,安装过程不做详解
1.3Pom文件
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.4application.yml
spring:
rabbitmq:
host: 192.168.140.211
port: 5672
username: admin
password: admin
2.各大模式下的生产者和消费者
1.简单模式
1.1队列声明
@Bean
public Queue helloWorld(){
//非持久化
return new Queue("HelloWorld",false);
}
PS:固定的队列最好现在RabbitMq Management创建,如果没有在客户端创建,springboot自动配置下也会自动创建队列并且创建对应的实例对象,但是有概率启动异常或者发生些迷之错误导致消息收不到,原因不明
1.2生产者
@Component
public class Produdcer {
@Autowired
private AmqpTemplate amqpTemplate;
//向指定队列发送
public void send(){
amqpTemplate.convertAndSend("HelloWorld","我真牛");
amqpTemplate.convertAndSend("HelloWorld",222);
}
}
这个生产者使用的是交换机为MQ的默认交换机
convertAndSend表示自动将发送的消息转为byte数组并发送
参数1为要发送的队列名,表示将消息发送到HelloWorld队列
参数2是要发送的消息,如果想发送对象,最好提前转化为json字符串或xml形式 字符串
1.3消费者
@RabbitListener(queues = "HelloWorld")
@Component
public class Listen {
@RabbitHandler
public void consumer(String msg){
System.out.println("打印字符:"+msg);
}
@RabbitHandler
public void consumer1(Integer num){
System.out.println("打印数字:"+num);
}
}
@RabbitListener 表示该类为消费者
queues 指定监听的队列名
@RabbitHandler 指定消费接受到的消息的方式,根据形参的不同可以监听不同类型的消息,在上面生产者发送的两个消息的情况下,consumer会收到"我真牛",而consumer1会收到222的消息
1.4消费者的其他写法
@Component
public class SimpleReceiver {
@RabbitListener(queues = "helloworld")
public void receive(String msg) {
System.out.println("收到: "+msg);
}
}
或者
@RabbitListener(queuesToDeclare = @Queue(name = "helloworld",durable = "false"))
2.工作模式
工作模式是指向多个互相竞争的消费者发送消息的模式,它包含一个生产者、两个消费者和一个队列。两个消费者同时绑定到一个队列上去,当消费者获取消息处理耗时任务时,空闲的消费者从队列中获取并消费消息。
2.1队列声明
队列持久化是指当没有消费者监听该队列时,保持该队列
@Bean
public Queue helloWorld(){
//持久化队列
return new Queue("task_queue",true);
}
2.2生产者
@Component
public class Produdcer {
@Autowired
private AmqpTemplate amqpTemplate;
//向指定队列发送
public void send(){
while (true){
System.out.println("输入消息");
String msg=new Scanner(System.in).nextLine();
amqpTemplate.convertAndSend("task_queue", msg);
}
}
}
生产者发送消息到task_queue队列,且消息为持久化
pring boot封装的 rabbitmq api 中, 发送的消息默认是持久化消息.
如果希望发送非持久化消息, 需要在发送消息时做以下设置:
使用 MessagePostProcessor 前置处理器参数
从消息中获取消息的属性对象
在属性中把 DeliveryMode 设置为非持久化
//如果需要设置消息为非持久化,可以取得消息的属性对象,修改它的deliveryMode属性
t.convertAndSend("task_queue", (Object) s, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
MessageProperties props = message.getMessageProperties();
props.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
return message;
}
});
2.3消费者
@Component
public class Listen {
@RabbitListener(queues = "task_queue")
public void consumer(String msg) throws InterruptedException {
System.out.