SpringBoot整合RabbitMQ
GitHub: link. 欢迎star
注意:本篇博客风格(不多比比就是撸代码!!!)
一、maven依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-amqp -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.6.1</version>
</dependency>
二、RabbitMQConfig.java
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
/**
* @author Andon
* 2021/12/7
*/
@SpringBootConfiguration
public class RabbitMQConfig {
// work模式
@Value("${rabbitmq.work.queue-name}")
private String queue_name_work;
// 订阅模式
@Value("${rabbitmq.fanout.queue-name-1}")
private String queue_name_fanout_1;
@Value("${rabbitmq.fanout.queue-name-2}")
private String queue_name_fanout_2;
@Value("${rabbitmq.fanout.exchange-name}")
private String exchange_name_fanout;
// topic模式
@Value("${rabbitmq.topic.queue-name-1}")
private String queue_name_topic_1;
@Value("${rabbitmq.topic.routing-key-1}")
private String routing_key_name_topic_1;
@Value("${rabbitmq.topic.queue-name-2}")
private String queue_name_topic_2;
@Value("${rabbitmq.topic.routing-key-2}")
private String routing_key_name_topic_2;
@Value("${rabbitmq.topic.exchange-name}")
private String exchange_name_topic;
// 消息confirm机制
@Value("${rabbitmq.confirm.queue-name}")
private String queue_name_confirm;
// 消息return机制
@Value("${rabbitmq.return.queue-name}")
private String queue_name_return;
@Value("${rabbitmq.return.routing-key}")
private String routing_key_name_return;
@Value("${rabbitmq.return.exchange-name}")
private String exchange_name_return;
/**
* work模式
* <p>
* 声明一个队列名称
*/
@Bean
public Queue queueWork() {
return new Queue(queue_name_work);
}
/**
* 订阅模式
* <p>
* 声明两个队列名称
* 声明一个交换机
* 交换机和队列进行绑定
*/
@Bean
public Queue queueFanout1() {
return new Queue(queue_name_fanout_1);
}
@Bean
public Queue queueFanout2() {
return new Queue(queue_name_fanout_2);
}
@Bean
public FanoutExchange exchangeFanout() {
return new FanoutExchange(exchange_name_fanout);
}
@Bean
public Binding bindingFanoutExchange1() {
return BindingBuilder.bind(queueFanout1()).to(exchangeFanout());
}
@Bean
public Binding bindingFanoutExchange2() {
return BindingBuilder.bind(queueFanout2()).to(exchangeFanout());
}
/**
* topic模式
* <p>
* 声明两个队列名称
* 声明一个交换机
* 交换机和队列进行绑定,队列和路由键进行绑定
*/
@Bean
public Queue queueTopic1() {
return new Queue(queue_name_topic_1);
}
@Bean
public Queue queueTopic2() {
return new Queue(queue_name_topic_2);
}
@Bean
public TopicExchange exchangeTopic() {
return new TopicExchange(exchange_name_topic);
}
@Bean
public Binding bindingTopicExchange1() {
return BindingBuilder.bind(queueTopic1()).to(exchangeTopic()).with(routing_key_name_topic_1);
}
@Bean
public Binding bindingTopicExchange2() {
return BindingBuilder.bind(queueTopic2()).to(exchangeTopic()).with(routing_key_name_topic_2);
}
/**
* 测试消息confirm机制
* <p>
* 声明一个队列
*/
@Bean
public Queue queueConfirm() {
return new Queue(queue_name_confirm);
}
/**
* 测试消息return机制
* <p>
* 声明一个队列
* 声明一个交换机
*/
@Bean
public Queue queueReturn() {
return new Queue(queue_name_return);
}
@Bean
public TopicExchange exchangeReturn() {
return new TopicExchange(exchange_name_return);
}
@Bean
public Binding bindingReturnExchange() {
return BindingBuilder.bind(queueReturn()).to(exchangeReturn()).with(routing_key_name_return);
}
}
三、RabbitMQProducer.java
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author Andon
* 2021/12/7
* <p>
* 生产者
*/
@Slf4j
@Component
public class RabbitMQProducer {
@Resource
private RabbitTemplate rabbitTemplate;
// work模式
@Value("${rabbitmq.work.queue-name}")
private String queue_name_work;
// 订阅模式
@Value("${rabbitmq.fanout.exchange-name}")
private String exchange_name_fanout;
// topic模式
@Value("${rabbitmq.topic.exchange-name}")
private String exchange_name_topic;
// 消息confirm机制
@Value("${rabbitmq.confirm.queue-name}")
private String queue_name_confirm;
// 消息return机制
@Value("${rabbitmq.return.exchange-name}")
private String exchange_name_return;
/**
* work模式
* <p>
* 消息直接发送到消息队列
* 一个生产者,多个消费者,每个消息只能被一个消费者消费
*/
public void sendWork(String message) {
rabbitTemplate.convertAndSend(queue_name_work, message);
}
/**
* 订阅模式
* <p>
* 消息发送到交换机
* 一个生产者,多个消费者,每个消息被每个消费者消费
*/
public void sendFanout(String message) {
rabbitTemplate.convertAndSend(exchange_name_fanout, "", message);
}
/**
* topic模式
* <p>
* 消息发送到交换机
* 一个生产者,多个消费者,每个消息被每个对应路由键的消费者消费
*/
public void sendTopic(String routingKey, String message) {
rabbitTemplate.convertAndSend(exchange_name_topic, routingKey, message);
}
/**
* 消息confirm机制
*/
public void sendConfirm(Object message) {
CorrelationData correlationData = new CorrelationData(Thread.currentThread().getId() + "_" + System.currentTimeMillis());
rabbitTemplate.convertAndSend(queue_name_confirm, message, correlationData);
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack) {
log.info("消息confirm成功!! id:{}", correlationData.getId());
} else {
log.info("消息confirm失败!! id:{} cause:{}", correlationData.getId(), cause);
}
}
});
}
/**
* 消息return机制
* <p>
* return 的回调方法(找不到路由才会触发)
*/
public void sendReturn(String routingKey, String message) {
rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
@Override
public void returnedMessage(ReturnedMessage returned) {
log.info("returnedMessage >> exchange:{} routingKey:{} getMessage:{} replyCode:{} replyText:{}", returned.getExchange(), returned.getRoutingKey(), returned.getMessage(), returned.getReplyCode(), returned.getReplyText());
}
});
rabbitTemplate.convertAndSend(exchange_name_return, routingKey, message);
}
}
四、RabbitMQConsumer.java
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author Andon
* 2021/12/7
* <p>
* 消费者
*/
@Slf4j
@Component
public class RabbitMQConsumer {
// work1
@RabbitListener(queues = "${rabbitmq.work.queue-name}")
public void consumeWork1(String message) {
log.info("consumeWork1 message:{}", message);
}
// work2
@RabbitListener(queues = "${rabbitmq.work.queue-name}")
public void consumeWork2(String message) {
log.info("consumeWork2 message:{}", message);
}
// 订阅1
@RabbitListener(queues = "${rabbitmq.fanout.queue-name-1}")
public void consumeFanout1(String message) {
log.info("consumeFanout1 message:{}", message);
}
// 订阅2
@RabbitListener(queues = "${rabbitmq.fanout.queue-name-2}")
public void consumeFanout2(String message) {
log.info("consumeFanout2 message:{}", message);
}
// topic1
@RabbitListener(queues = "${rabbitmq.topic.queue-name-1}")
public void consumeTopic1(String message) {
log.info("consumeTopic1 message:{}", message);
}
// topic2
@RabbitListener(queues = "${rabbitmq.topic.queue-name-2}")
public void consumeTopic2(String message) {
log.info("consumeTopic2 message:{}", message);
}
// 消息confirm机制
@RabbitListener(queues = "${rabbitmq.confirm.queue-name}")
public void consumeConfirm(String message) {
log.info("consumeConfirm message:{}", message);
}
// 消息return机制
@RabbitListener(queues = "${rabbitmq.return.queue-name}")
public void consumeReturn(String message) {
log.info("consumeReturn message:{}", message);
}
}
五、application.yml
spring:
# RabbitMQ
rabbitmq:
host: 127.0.0.1
port: 5672
username: admin
password: admin
# 配置虚拟机
virtual-host: /
# 开启消息确认机制 confirm 异步
publisher-confirm-type: correlated
# 开启return机制
publisher-returns: true
# 消息开启手动确认
listener:
direct:
acknowledge-mode: manual
rabbitmq:
work:
queue-name: queue_work
fanout:
queue-name-1: queue_fanout_1
queue-name-2: queue_fanout_2
exchange-name: exchange_fanout
topic:
queue-name-1: queue_topic_1
routing-key-1: topic.#
queue-name-2: queue_topic_2
routing-key-2: topic.*
exchange-name: exchange_topic
confirm:
queue-name: queue_confirm
return:
queue-name: queue_return
exchange-name: exchange_return
routing-key: return.*
六、DatabaseTest.java
import com.andon.springbootrabbitmq.rabbitmq.RabbitMQProducer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
* @author Andon
* 2021/12/7
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class DatabaseTest {
@Resource
private RabbitMQProducer rabbitMQProducer;
@Test
public void test05() {
rabbitMQProducer.sendReturn("return.an.return", "return!!");
}
@Test
public void test04() {
rabbitMQProducer.sendConfirm("confirm!!");
}
@Test
public void test03() {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
rabbitMQProducer.sendTopic("topic.an.topic", "topic" + i);
} else {
rabbitMQProducer.sendTopic("topic.an", "topic" + i);
}
}
}
@Test
public void test02() {
for (int i = 0; i < 10; i++) {
rabbitMQProducer.sendFanout("fanout" + i);
}
}
@Test
public void test01() {
for (int i = 0; i < 10; i++) {
rabbitMQProducer.sendWork("work" + i);
}
}
}
七、测试
GitHub: link. 欢迎star