工作模式相当于是一个生产者对应多个消费者,和普通模式的区别就是消费者数量不同(欢迎指正)
1:首先是pom
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2:生产者
application.yml
server:
port: 7001
spring:
rabbitmq:
host: localhost
port: 5672
username: xx
password: xx
virtual-host: /
常量类
package com.example.rabbitmq.constant;
public class Constant {
//队列名称
public static final String DIRECT_QUEUE_NAME = "testDirectQueue";
}
rabbitmq配置类
@Configuration
public class RabbitConfig {
// 普通队列模式 发送消息的时候指定队列名称
// 消费者指定队列名称 如果路由模式和普通模式的队列名称一致 消费者相当于消费这两个模式的消息
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
// return new Queue("TestDirectQueue",true,true,false);
//一般设置一下队列的持久化就好,其余两个就是默认false
@Bean
public Queue testDirectQueue() {
return new Queue(Constant.DIRECT_QUEUE_NAME, true);
}
}
controller发送消息
package com.example.rabbitmq.controller;
import com.alibaba.fastjson.JSON;
import com.example.rabbitmq.constant.Constant;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@RestController
public class RabbitmqController {
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("/directMq")
public void directMq() {
Map<String, Object> map = new HashMap<>();
map.put("messageId", UUID.randomUUID());
map.put("messageData", "hello testDirect");
map.put("createTime", System.currentTimeMillis());
//rabbitTemplate.convertAndSend(Constant.DIRECT_EXCHANGE_NAME, Constant.DIRECT_ROUTING, JSON.toJSONString(map));
//rabbitTemplate.convertAndSend(Constant.DIRECT_EXCHANGE_NAME, Constant.DIRECT_ROUTING02, JSON.toJSONString(map));
rabbitTemplate.convertAndSend(Constant.DIRECT_QUEUE_NAME,JSON.toJSONString(map));
}
}
消费者
application.yml
server:
port: 7003
spring:
rabbitmq:
host: localhost
port: 5672
username: xx
password: xx
virtual-host: /
listener:
simple:
acknowledge-mode: manual//手动确认消息
retry:
enabled: true
消费者代码
package com.example.rabbitmq.mq;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Component
public class RabbitmqListener {
@RabbitListener(queues = "testDirectQueue")
public void listener(Message message, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
String msg = new String(message.getBody(), StandardCharsets.UTF_8);
System.out.println("02==" + msg);
try {
channel.basicAck(deliveryTag,false);
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.example.rabbitmq.mq;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Component
public class RabbitmqListener {
@RabbitListener(queues = "testDirectQueue")
public void listener(Message message, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
String msg = new String(message.getBody(), StandardCharsets.UTF_8);
System.out.println("01==" + msg);
try {
channel.basicAck(deliveryTag,false);
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试
发送10条消息查看消费者消费情况
消费者1
消费者2
修改消费者1的代码逻辑,休息10秒
package com.example.rabbitmq.mq;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Component
public class RabbitmqListener {
@RabbitListener(queues = "testDirectQueue")
public void listener(Message message, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
String msg = new String(message.getBody(), StandardCharsets.UTF_8);
try {
Thread.sleep(10000);
System.out.println("01==" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
channel.basicAck(deliveryTag,false);
} catch (IOException e) {
e.printStackTrace();
}
}
}
消费者1
消费者2
发现虽然消费者1消费的慢了,但是最后还是消费5条数据,不能实现多劳多得,影响我们的消费速度,这时可以添加一个参数
server:
port: 7003
spring:
rabbitmq:
host: localhost
port: 5672
username: xx
password: xx
virtual-host: /
listener:
simple:
acknowledge-mode: manual
retry:
enabled: true
prefetch: 1//每次读取1条消息,在消费者未回执确认之前,不在进行下一条消息的投送
此时再次测试发现
消费者1
消费者2
实现了多劳多得