使用SpringBoot对RabbitMQ进行整合,模拟生产者服务器(9000)向两台消费者服务器(8001和8002)发送消息的过程,消息生产者通过接受Http请求向消息队列发送消息(Controller层、Service层),接收端则直接监听队列接收消息。这里Demo中通过请求接口向绑定在交换机上的队列发送消息,在两个消费者服务器均会队列的消息。
关于RabbitMQ的搭建及搭建中常见的问题参考连接:RabbitMQ搭建及问题
Fanout交换机会忽略路由键,将消息分发到所有绑定到交换机上的队列,即消息广播。
在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>
demo模拟一个发送端,两个接收端的情况
server:
port: 9001
spring:
application:
name: direct-sender
rabbitmq:
username: admin
password: admin
host: 192.168.108.128
port: 5672
server:
port: 8001
spring:
application:
name: fanout-receiver-1
rabbitmq:
username: admin
password: admin
host: 192.168.108.128
port: 5672
server:
port: 8002
spring:
application:
name: fanout-receiver-1
rabbitmq:
username: admin
password: admin
host: 192.168.108.128
port: 5672
配置信息中创建两个队列分别为fanout.queue.1、fanout.queue.2,通过FanoutExchange类创建Fanout交换机。由于Fanout交换机不关心路由键,因此在创建绑定时不用设置路由键。
@Configuration
public class SendConfig {
public static final String FANOUT_QUEUE_1 = "fanout.queue.1";
public static final String FANOUT_QUEUE_2 = "fanout.queue.2";
public static final String FANOUT_EXCHANGE = "fanout.exchange";
@Bean
public Queue fanoutQueue1() {
return new Queue(FANOUT_QUEUE_1);
}
@Bean
public Queue fanoutQueue2() {
return new Queue(FANOUT_QUEUE_2);
}
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange(FANOUT_EXCHANGE);
}
@Bean
public Binding binding1() {
return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());
}
@Bean
public Binding binding2() {
return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());
}
}
@RestController
@RequestMapping("/fanout")
class SendController{
@Autowired
private SendService sendService;
@GetMapping("/send/{msg}")
public void fanoutSend(@PathVariable String msg){
sendService.send(msg);
}
}
Service层中调用convertAndSend方法进行消息发送,由于Fanout不关心路由键,因此第二个参数可以随意设置,在这里选用空字符串
@Service
public class SendServiceImpl implements SendService {
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void send(String msg) {
System.out.println("Fanout发送数据:" + msg);
rabbitTemplate.convertAndSend(SendConfig.FANOUT_EXCHANGE, "", msg);
}
}
@Component
public class FanoutReceiver {
@Value("${server.port}")
private String port;
@RabbitListener(queues = "fanout.queue.1")
public void receiveDirect1(String msg) {
System.out.println(port+"收到fanout的消息:" + msg);
}
}
@Component
public class FanoutReceiver {
@Value("${server.port}")
private String port;
@RabbitListener(queues = "fanout.queue.2")
public void receiveDirect1(String msg) {
System.out.println(port + "接收到fanout的消息:" + msg);
}
}
在这里将配置文件中的端口号设置到变量中,已便于区分消息来源
启动生产者和两个消费者服务器,调用接口发送消息
http://127.0.0.1:9001/fanout/send/fanout
在RabbitMQ管理界面中可以看到两个队列已经成功声明
此时,调用一次接口,在两个接收端均可以收到接口发送的消息
RabbitDemo代码
初识RabbitMQ——AMQP 0-9-1
RabbitMQ——RabbitMQ搭建及问题
SpringBoot整合RabbitMQ——Direct交换机
SpringBoot整合RabbitMQ——Topic交换机
SpringBoot整合RabbitMQ——Headers交换机