本文目录
1.构建消息生产者
- 创建一个Spring Boot消息生产者(mqproducer)项目,在
POM文件中引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 配置RabbitMQ服务相关信息
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.connection-timeout=5000
spring.rabbitmq.virtual-host=/
#消息confirm确认
spring.rabbitmq.publisher-confirm-type=correlated
# return消息
spring.rabbitmq.publisher-returns=true
#当mandatory标志位设置为true时,如果exchange根据自身类型和消息routingKey无法找到一个合适的queue存储消息,那么broker会调用basic.return方法将消息返还给生产者
# 如果为false,则直接丢弃消息
spring.rabbitmq.template.mandatory=true
配置说明:
spring.rabbitmq.template.mandatory设置为true时,如果exchange根据自身类型和消息routingKey无法找到一个合适的queue存储消息,那么broker会调用basic.return方法将消息返还给生产者。为false,则直接丢弃消息spring.rabbitmq.publisher-confirm-type在最新版本的Spring Boot AMQP中spring.rabbitmq.publisher-confirms已被此属性取代,表示是否开启消息的Confirm
2.构建消息消费者
- 创建一个Spring Boot消息消费者(mqconsumer)项目,POM文件与消息生产者一样。
- 配置RabbitMQ服务相关信息
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.connection-timeout=5000
spring.rabbitmq.virtual-host=/
#消息确认模式 手工模式
spring.rabbitmq.listener.simple.acknowledge-mode=manual
# 初始化链接
spring.rabbitmq.listener.simple.concurrency=5
# 最大链接
spring.rabbitmq.listener.simple.max-concurrency=10
#限流,同一时间只有一条消息消费
spring.rabbitmq.listener.simple.prefetch=1
3.消息发送与监听
3.1.消息生产者
- RabbitTemplate 发送消息,并设置消息的Confirm与Return
@Component
public class RabbitMQSender {
@Autowired
private RabbitTemplate rabbitTemplate;
//回调函数: confirm确认
final ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.err.println("correlationData: " + correlationData.getId());
System.err.println("ack: " + ack);
if(!ack){
System.err.println("异常处理....");
}
}
};
//回调函数: return返回
final RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(org.springframework.amqp.core.Message message, int replyCode, String replyText,
String exchange, String routingKey) {
System.err.println("return exchange: " + exchange + ", routingKey: "
+ routingKey + ", replyCode: " + replyCode + ", replyText: " + replyText);
}
};
/**
* @param exchangeName
* @param routeKey
* @param contents
* @param properties
*/
public void sendMessage(String exchangeName,String routeKey,Object contents, Map<String, Object> properties){
MessageHeaders headers=new MessageHeaders(properties);
Message message= MessageBuilder.createMessage(contents,headers);
rabbitTemplate.setConfirmCallback(confirmCallback);
rabbitTemplate.setReturnCallback(returnCallback);
//消息唯一性
CorrelationData correlationData = new CorrelationData();
correlationData.setId(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(exchangeName,routeKey,message,correlationData);
}
}
3.2.消息消费者
@RabbitListener 注解可以声明队列、交换机以及绑定订单与与交换机。当收到消息的时候,就交给 @RabbitHandler 的方法处理。
@Component
public class ConsumberReceiver {
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "queue-springboot-test",
durable="true"),
exchange = @Exchange(value = "springboot_exchange_test",
durable="true",
type= "topic",
ignoreDeclarationExceptions = "true"),
key = "springboot.test"
))
@RabbitHandler
public void onMessage(Message message, Channel channel) throws Exception {
MessageHeaders messageHeaders=message.getHeaders();
System.err.println("--------------------------------------");
System.err.println("消费端接收到的消息: " + message.getPayload());
Long deliveryTag = (Long)message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
//手工ACK
channel.basicAck(deliveryTag, false);
}
}
说明:
@RabbitListener->bindings->@Exchange的type属性值有direct、topic、fanout、headers ,也是RabbitMQ支持的四种交换机类型。
4.Message 内容的JSON序列化与反序列化
创建一个Order实体类
public class Order implements Serializable{
private Integer id;
private String orderNum;
private String title;
private String desc;
public Order() {
}
public Order(Integer id, String orderNum, String title, String desc) {
this.id = id;
this.orderNum = orderNum;
this.title = title;
this.desc = desc;
}
-------------------------省略get set---------------------
4.1.消费者MessageConverter配置
RabbitMQ 提供了 Jackson2JsonMessageConverter 来支持消息内容 JSON 序列化与反序列化,消息消费者配置 MessageConverter 为 Jackson2JsonMessageConverter
@Configuration
public class RabbitMQConfig {
@Bean
public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
DefaultJackson2JavaTypeMapper javaTypeMapper=new DefaultJackson2JavaTypeMapper();
//添加信任包名称,不然会转化失败
javaTypeMapper.setTrustedPackages("com.warybee.mqconsumer.entity");
jackson2JsonMessageConverter.setJavaTypeMapper(javaTypeMapper);
factory.setMessageConverter(jackson2JsonMessageConverter);
return factory;
}
}
说明:
javaTypeMapper.setTrustedPackages(...)默认只支持java.util和java.lang包下的类的反序列化,这里需要添加我们需要反序列实体所在的package
消息监听代码:
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "queue-springboot-test",
durable="true"),
exchange = @Exchange(value = "springboot_exchange_test",
durable="true",
type= "topic",
ignoreDeclarationExceptions = "true"),
key = "springboot.save"
))
@RabbitHandler
public void onMessage(Order order, Channel channel,
@Headers Map<String, Object> headers) throws IOException {
System.out.println("接收的消息-订单号::"+order.getDesc());
System.out.println("接收的消息-标题::"+order.getTitle());
Long deliveryTag = (Long)headers.get(AmqpHeaders.DELIVERY_TAG);
//手工应答
channel.basicAck(deliveryTag,false);
}
4.2.生产者MessageConverter配置
消息生产者也应配置 MessageConverter 为 Jackson2JsonMessageConverter
/**
* String类型参数
* @param exchangeName
* @param routeKey
* @param properties
*/
public void sendMessage(String exchangeName, String routeKey, Order order, Map<String, Object> properties){
MessageHeaders headers=new MessageHeaders(properties);
Message message= MessageBuilder.createMessage(order,headers);
rabbitTemplate.setConfirmCallback(confirmCallback);
rabbitTemplate.setReturnCallback(returnCallback);
//消息唯一性
CorrelationData correlationData = new CorrelationData();
correlationData.setId(UUID.randomUUID().toString()+"_"+System.currentTimeMillis());
// 使用Jackson2JsonMessageConverter 消息转化
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
rabbitTemplate.convertAndSend(exchangeName,routeKey,order,correlationData);
}
PS: rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter()); 配置 MessageConverter 为 Jackson2JsonMessageConverter
RabbitMQ系列文章目录
1、RabbitMQ Windows/CentOS7平台安装手册
2、RabbitMQ中一些重要概念
3、RabbitMQ Exchange类型之Direct Exchange
4、RabbitMQ Exchange类型之Topic Exchange
5、RabbitMQ Exchange类型之fanout Exchange
6、RabbitMQ Exchange类型之headers Exchang
7、Confirm消息确认机制
8、RabbitMQ中ReturnListener的使用
9、RabbitMQ消费端限流
10、ACK确认机制与消息补偿
11、RabbitMQ队列/消息的生存时间(Time-To-Live)
12、RabbitMQ死信队列(Dead Letter Exchanges)
13、Spring AMQP API详解
14、Spring Boot整合RabbitMQ
本文详细介绍如何在SpringBoot项目中整合RabbitMQ,包括构建消息生产者与消费者,配置消息确认与返回机制,实现消息的JSON序列化与反序列化。
Spring Boot整合RabbitMQ&spm=1001.2101.3001.5002&articleId=103339292&d=1&t=3&u=1ae192a36b724dc6a2fcf3f66cdb4dc4)
11万+

被折叠的 条评论
为什么被折叠?



