SpringBoot 整合 RabbitMQ 非常方便,只需要两步
- 引入相关依赖
- 在 application.yml 中配置 RabbitMQ
- 通过打注解的方式,使用MQ
引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置 RabbitMQ
# RabbitMQ 基本配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
# 虚拟主机,默认是/
spring.rabbitmq.virtual-host=/
# 超时时间,默认不超时,单位毫秒
spring.rabbitmq.connection-timeout=15000
发送MQ消息
最基本的使用
消息实体
/**
* 订单的消息实体
*/
public class OrderMessage {
private String id;
private String name;
public OrderMessage() {
}
public OrderMessage(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
发送消息
import com.alibaba.fastjson.JSONObject;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SendMessageService {
@Autowired
private AmqpTemplate amqpTemplate;
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 通过 AmqpTemplate 发送消息
*/
public void amqpSend(Object obj) {
// 三个参数分别是 交换机名称 路由键 json化的消息实体
String message = JSONObject.toJSONString(obj);
amqpTemplate.convertAndSend("exchangeName", "routingKeyValue", message);
}
/**
* 通过 RabbitTemplate 发送消息
*/
public void rabbitSend(Object obj) {
// 三个参数分别是 交换机名称 路由键 json化的消息实体
String message = JSONObject.toJSONString(obj);
rabbitTemplate.convertAndSend("exchangeName", "routingKeyValue", message);
}
}
发送
import com.wqlm.rabbitmq.send.message.OrderMessage;
import com.wqlm.rabbitmq.send.service.SendMessageService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SendApplicationTests {
@Autowired
private SendMessageService service;
@Test
public void contextLoads() {
OrderMessage orderMessage = new OrderMessage("123","订单123");
service.amqpSend(orderMessage);
// service.rabbitSend(orderMessage);
}
}
消息的异步确认
上面的代码中,消息虽然发送出去了,但我们根本不知道消息是投递成功了还是投递失败了。实际开发中,为了保证消息的高可靠性投递,一般会采用 confirm 模式并进行异步确认
感兴趣的可以查看我写的另外两篇文章
消费 消息
最基本的使用
基础配置
# RabbitMQ 消费端配置
# 侦听器的最小线程数
spring.rabbitmq.listener.simple.concurrency=5
# 侦听器的最大线程数
spring.rabbitmq.listener.simple.max-concurrency=10
# 签收方式 auth:自动签收 manual:手动签收 NONE:不签收 推荐手动签收
spring.rabbitmq.listener.simple.acknowledge-mode=manual
# 限流数,2表示每个监听器可以同时介绍2条数据
spring.rabbitmq.listener.simple.prefetch=2
监听器
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Map;
/**
* 消费消息
* @author wqlm
* @date 2019/8/25 10:34
*/
@Component
public class ConsumerMessageListener {
/**
* 监听指定队列
* @RabbitListener 指定了 exchange 、key、Queue 后,如果 Rabbitmq 没有会去创建
* @param message 消息体
* @param headers 消息头
* @param channel 通道
* @return
*/
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange("exchangeName"),
key = "routingKeyValue",
value = @Queue("queryName")
))
public void listenerMessage(String message, @Headers Map<String,Object> headers, Channel channel)
throws IOException {
System.out.println(message);
System.out.println(headers);
//手动 ack
channel.basicAck((Long)headers.get(AmqpHeaders.DELIVERY_TAG),false);
}
}