SpringBoot与RabbitMQ的集成非常简单,不需要做任何的额外设置,只需要引入相关依赖并对application.properties进行配置即可
这边直接通过IDEA建立两个SpringBoot项目即可,一个作为消费端一个作为生产端,由于后文中消费端需要实时监控队列,要开启web服务,所以创建消费端时可以先选择web依赖包免得后面再去导入。
在com.rabbitmq目录下创建以下目录
在com.rabbitmq目录下创建以下目录
org.springframework.boot
spring-boot-starter-amqp
org.apache.commons
commons-lang3
commons-io
commons-io
2.4
com.alibaba
fastjson
1.2.47
javax.servlet
servlet-api
log4j
log4j
1.2.17
在application.properties文件中进行如下配置
spring.rabbitmq.addresses=192.168.11.81:5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#rabbitMQ默认虚拟主机为`/`
spring.rabbitmq.virtual-host=/
spring.rabbitmq.connection-timeout=15000s
#并发数
spring.rabbitmq.listener.simple.concurrency=5
spring.rabbitmq.listener.simple.max-concurrency=10
#签收模式,auto:自动,manual:手工
spring.rabbitmq.listener.simple.acknowledge-mode=manual
#限流,即指定一个线程中同一时间接收处理的消息数量,防止挤爆
spring.rabbitmq.listener.simple.prefetch=1
#项目路径前缀,可以不设,SpringBoot默认就是"/"
server.servlet.context-path=/
#项目端口,消费端跟生产端端口需不同
server.port=8080
spring.http.encoding.charset=UTF-8
#日期格式化
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#不允许传递空值
spring.jackson.default-property-inclusion=NON_NULL
public class Order implements Serializable {
private static final long serialVersionUID = -236444488241798054L;
private String id;
private String name;
/**存储消息发送的唯一标识*/
private String massageId;
public Order() {
}
public Order(String id, String name, String massageId) {
this.id = id;
this.name = name;
this.massageId = massageId;
}
getter、setter......
}
注意,实体对象必须实现Serializable
,因为实体类会经过序列化后通过网络传输到MQ上
@Component
public class OrderSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(Order order) throws Exception {
CorrelationData correlationData = new CorrelationData();
correlationData.setId(order.getMassageId());
/**
* convertAndSend参数解释
* 第一个参数: exchange,指定交换机名称,交换机和队列可以在rabbitMQ图形洁面上进行创建
* 第二个参数: routingKey, 指定路由key
* 第三个参数: 传输的对象
* 第四个参数: correlationData,指定消息唯一id
**/
rabbitTemplate.convertAndSend("order-exchange", "order.abcd", order, correlationData);
}
}
这里因为我们使用了SpringBoot,只要进行对应的依赖包导入和配置,就可以直接使用RabbitTemplate
,十分便利。
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitmqProducerApplicationTests {
@Autowired
private OrderSender orderSender;
@Test
public void testSend() throws Exception {
Order order = new Order("1", "orderOne", System.currentTimeMillis() + "#" + UUID.randomUUID().toString());
orderSender.send(order);
}
}
运行发送成功后,可以到RabbitMQ的管理界面的队列中点击getMassage进行查看,会看到一串序列化后的数据。注意,这里的getMassage不表示将队列中的数据消费掉,只是简单的查看。
创建实体类
这里的需要与生产者端保持一致,否则在序列化以及反序列化时会出现问题,直接从生产者端复制Order
即可。
创建消费服务类
public class OrderReceiver {
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "order-queue", durable = "true"),
exchange = @Exchange(value = "order-exchange", durable = "true", type = "topic"),
key = "order.#"
)
)
@RabbitHandler
public void orderMassage(@Payload Order order, @Headers Map headers, Channel channel) throws IOException {
System.out.println("--------接收到消息,开始消费--------");
System.out.println("订单号为: " + order.getId());
//确认签收消息
Long delivery = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
channel.basicAck(delivery, false);
}
}
@RabbitHandler
注解来对指定函数进行消息监听,该注解用在指定的消息处理函数上。@Payload
和@Headers
注解进行接收,第三个参数为Channel
是因为我们配置了消息手动签收模式,需要通过Channel
类的basicAck
方法来进行签收,该方法的第一个参数需要从消息头中获取,第二个参数为boolean值,指定是否支持批量签收。测试,直接启动消费端的SpringBoot项目,然后从生产端发送信息即可,消费端会自动消费RabbitMQ接收到的信息。