使用SpringBoot对RabbitMQ进行整合,模拟生产者服务器(9000)向向消费者服务器(8088)发送消息的过程,消息生产者通过接受Http请求向消息队列发送消息(Controller层、Service层),接收端则直接监听队列接收消息。这里Demo中通过请求两个不同的接口向不同的队列发送消息,在消费者端将会接收到对应监听队列的消息。
关于RabbitMQ的搭建及搭建中常见的问题参考连接:RabbitMQ搭建及问题
Direct Exchange是RabbitMQ默认的交换机模式,也是最简单的模式,根据路由键全文匹配去寻找队列
在pom.xml文件中添加依赖,主要是springboot中web和amqp的starter
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.0.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-amqpartifactId>
dependency>
dependencies>
server:
port: 9000
spring:
application:
name: direct-sender
rabbitmq:
username: admin
password: admin
host: 192.168.108.128
port: 5672
server:
port: 8088
spring:
application:
name: direct-receiver
rabbitmq:
username: admin
password: admin
host: 192.168.108.128
port: 5672
配置中创建两个队列,分别为direct.queue.1和direct.queue.2,并且分别通过路由键direct.route.key.1和direct.route.key.2进行绑定。使用两个队列进行演示目的是展示交换机通过路由键将消息进行分发
@Configuration
public class SendConfig {
public static final String DIRECT_QUEUE_1 = "direct.queue.1";
public static final String DIRECT_QUEUE_2 = "direct.queue.2";
public static final String DIRECT_EXCHANGE = "direct.exchange";
public static final String DIRECT_ROUTE_KEY_1 = "direct.route.key.1";
public static final String DIRECT_ROUTE_KEY_2 = "direct.route.key.2";
@Bean
public Queue directQueue1() {
return new Queue(DIRECT_QUEUE_1);
}
@Bean
public Queue directQueue2() {
return new Queue(DIRECT_QUEUE_2);
}
@Bean
public DirectExchange directExchange() {
return new DirectExchange(DIRECT_EXCHANGE);
}
@Bean
public Binding binding1() {
return BindingBuilder.bind(directQueue1()).to(directExchange()).with(DIRECT_ROUTE_KEY_1);
}
@Bean
public Binding binding2() {
return BindingBuilder.bind(directQueue2()).to(directExchange()).with(DIRECT_ROUTE_KEY_2);
}
}
设置访问路径和参数调用service层
@RestController
@RequestMapping("/direct")
public class SendController {
@Autowired
private DirectSendService directSendService;
@GetMapping("/queue1/{msg}")
public void sendQueue1(@PathVariable String msg) {
directSendService.sendQueue1(msg);
}
@GetMapping("/queue2/{msg}")
public void sendQueue2(@PathVariable String msg) {
directSendService.sendQueue2(msg);
}
}
使用RabbitTemplate的convertAndSend方法进行发送,方法有很多重载方法,选用convertAndSend(String exchange, String routingKey, Object object),指定交换机、路由键和发送的消息
@Service
public class DirectSendServiceImpl implements DirectSendService {
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void sendQueue1(String msg) {
System.out.println("发送到队列1:" + msg);
rabbitTemplate.convertAndSend(SendConfig.DIRECT_EXCHANGE, SendConfig.DIRECT_ROUTE_KEY_1, msg);
}
@Override
public void sendQueue2(String msg) {
System.out.println("发送到队列2:" + msg);
rabbitTemplate.convertAndSend(SendConfig.DIRECT_EXCHANGE, SendConfig.DIRECT_ROUTE_KEY_2, msg);
}
}
消息接收端通过@RabbitListener注解监听队列,当队列有消息时自动读取
@Component
public class DirectReceiver {
@RabbitListener(queues = "direct.queue.1")
public void receiveDirect1(String msg) {
System.out.println("接收到direct.queue.1的消息:" + msg);
}
@RabbitListener(queues = "direct.queue.2")
public void receiveDirect2(String msg) {
System.out.println("接收到direct.queue.2的消息:" + msg);
}
}
启动服务器,分别调用发送端接口
http://127.0.0.1:9000/direct/queue1/direct
http://127.0.0.1:9000/direct/queue2/direct
调用成功后RabbitMQ管理页面中便会新增两个队列,对列名为SendConfig中设置的名字
此时如果关闭接收端服务器,然后一直调用发送接口,消息会都积累在队列中,在管理页面中显示为ready。
当再次启动接收端时便会以此将消息从队列中读取出来
RabbitDemo代码
初识RabbitMQ——AMQP 0-9-1
RabbitMQ——RabbitMQ搭建及问题
SpringBoot整合RabbitMQ——Direct交换机
SpringBoot整合RabbitMQ——Topic交换机
SpringBoot整合RabbitMQ——Headers交换机