前言:进来的看官,默认你对RabbitMQ的原理比较懂了啊,不懂的先学习一下再来。
一、引入rabbitmq依赖包
// rabbitmq依赖包
<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>
二、在application.yml中配置rabbitmq
server:
port: 8000
spring:
rabbitmq:
host: 192.168.107.128
username: root
password: root@123
virtual-host: /
template:
retry:
enabled: true
listener:
simple:
acknowledge-mode: manual
type: simple
publisher-returns: true
publisher-confirm-type: correlated
三、开启撸代码模式,定义队列信息
- 定义一个常量类
//定义个常量类
public class RabbitConstants {
//订单队列
public static final String ORDER_ROUTE_KEY = "order_route_key";
public static final String ORDER_EXCHANGE = "order_exchange";
public static final String ORDER_QUEUE = "order_queue_test";
//死信队列
public static final String DEAD_QUEUE = "dead_queue";
public static final String DEAD_EXCHANGE = "dead_exchange";
public static final String DEAD_ROUTE_KEY = "dead_route_key";
}
- 配置消息队列
//配置队列信息
@Configuration
public class RabbitQueueConfig {
//队列过期时间
private int orderQueueTTL = 5000;
// 配置普通队列
@Bean
public Queue orderQueue() {
return QueueBuilder.durable(RabbitConstants.ORDER_QUEUE)
.ttl(orderQueueTTL)
.deadLetterRoutingKey(RabbitConstants.DEAD_ROUTE_KEY)//设置死信队列的RouteKey
.deadLetterExchange(RabbitConstants.DEAD_EXCHANGE)//设置死信队列的Exchange
.build();
}
@Bean
public TopicExchange orderTopicExchange() {
return new TopicExchange(RabbitConstants.ORDER_EXCHANGE);
}
@Bean
public Binding orderBinding() {
return BindingBuilder.bind(orderQueue())
.to(orderTopicExchange())
.with(RabbitConstants.ORDER_ROUTE_KEY);
}
//配置死信队列
@Bean
public Queue deadQueue() {
return new Queue(RabbitConstants.DEAD_QUEUE, true);
}
@Bean
public TopicExchange deadExchange() {
return new TopicExchange(RabbitConstants.DEAD_EXCHANGE);
}
@Bean
public Binding deadBinding() {
return BindingBuilder.bind(deadQueue())
.to(deadExchange())
.with(RabbitConstants.DEAD_ROUTE_KEY);
}
}
- 定义消息生产者和消费者,并对消息进行确认回调
//定义一个类,发送消息,接收消息,并进行消息确认回调
@Service
public class OrderProduceService implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void setCallback() {
rabbitTemplate.setReturnCallback(this);
rabbitTemplate.setConfirmCallback(this);
Runnable runnable=()->send("这是我发送的测试消息,测试id="+UUID.randomUUID().toString());
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(runnable,20,5, TimeUnit.SECONDS);
}
public void send(Object message) {
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(RabbitConstants.ORDER_EXCHANGE, RabbitConstants.ORDER_ROUTE_KEY, message, correlationData);
}
// confirm确认消息投递成功了
//如果没有 Exchange ack=false,
// * 如果有 Exchange ack=tru
@Override
public void confirm(CorrelationData correlationData, boolean ack, String s) {
System.out.println("消息发送成功,发送ack确认,id="+correlationData.getId());
if (ack){
System.out.println("发送成功");
}else {
System.out.println("发送失败");
}
}
//Exchange 到Queue投递成功,不回调ReturnCallback
@Override
public void returnedMessage(Message message, int i, String s, String s1, String s2) {
System.out.println("消息丢失, 没有投递成功");
}
// 监听订单队列
@RabbitListener(queues = RabbitConstants.ORDER_QUEUE)
public void orderQueueListener(Message message,Channel channel) throws IOException {
String receivedRoutingKey = message.getMessageProperties().getReceivedRoutingKey();
String msg = new String(message.getBody());
System.out.println("路由key= [ "+receivedRoutingKey+" ]接收到的消息= [ "+msg +" ]");
//Thread.sleep(5000);
//发送ack给消息队列,收到消息了
channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
}
// 监听死信队列
@RabbitListener(queues = RabbitConstants.DEAD_QUEUE)
public void deadQueueListener(Message message, Channel channel) throws InterruptedException, IOException {
String receivedRoutingKey = message.getMessageProperties().getReceivedRoutingKey();
String msg = new String(message.getBody());
System.out.println("路由key= [ "+receivedRoutingKey+" ]接收到的消息= [ "+msg +" ]");
//Thread.sleep(5000);
// 发送ack给消息队列,收到消息了
channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
}
}
- 启动项目,消息正常发送,正常接收
- 在RabbitMQ管理界面上可以看到定义的队列,死信队列dead_queue,order_queue_test测试队列
就是这么简单粗暴,关于RabbitMQ概念自己不清楚的,先去学习下再来看吧