配置:
公共文件:
创建 队列统一配置类 QueueConstant.java
package test.common;
public class QueueConstant {
/**
* 队列名
*/
public static final String RABBITMQ_TEST="rabbitmq.test";
}
创建 交换机类 ExchangeConstant.java
package test.common;
/**
* 交换机统一配置类
* 交换机名称对应模块名、路由可以对于模块的具体触发事件、默认采用topic模式
*/
public class ExchangeConstant {
/**
* 交换机名称-设备
*/
public static final String EXCHANGE_TEST="test";
/**
* 路由key-设备-初始化
*/
public static final String EXCHANGE_KEY_TEST="test.key";
}
创建 测试类 UserDTO .java
import java.io.Serializable;
import lombok.Data;
@Data
public class UserDTO implements Serializable {
private String username;
private String password;
}
生产者:
首先创建一个RabbitMQConfig.java作为生产者的配置类。
package test.producer;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 生产者消息确认--》正常业务关闭,重要数据开启
* 配置文件中开启:publisher-returns publisher-confirms
* ⚫ 消息从 producer 到 exchange 则会返回一个 confirmCallback 。
* ⚫ 消息从 exchange–>queue 投递失败则会返回一个 returnCallback 。
*/
@Configuration
public class RabbitMQConfig {
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
/**
* 配置序列化工具
*/
Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
jackson2JsonMessageConverter.setCreateMessageIds(true);
template.setMessageConverter(jackson2JsonMessageConverter);
/**
* 消息从 producer 到 exchange 立马返回一个 confirmCallback
*/
template.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("ConfirmCallback: "+"相关数据:"+correlationData);
System.out.println("ConfirmCallback: "+"确认情况:"+ack);
System.out.println("ConfirmCallback: "+"原因:"+cause);
}
});
/**
* 进入交换机但是没进入队列才会调用-》路由失败的情况
*/
template.setReturnCallback(new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("ReturnCallback: "+"消息:"+message);
System.out.println("ReturnCallback: "+"回应码:"+replyCode);
System.out.println("ReturnCallback: "+"回应信息:"+replyText);
System.out.println("ReturnCallback: "+"交换机:"+exchange);
System.out.println("ReturnCallback: "+"路由键:"+routingKey);
}
});
return template;
}
}
yml配置文件
spring:
rabbitmq:
host: #网址
port: #端口
username: #账号
password: #密码
virtualHost: /
#交换机ack确认
# correlated-异步 simple-同步 none:关闭confirm确认机制 老版本-》publisher-confirms: true
publisher-confirm-type: none
#队列ack确认
publisher-returns: false
消费者:
创建 队列配置类 QueueConfig.java
package test.consumer;
import test.common.ExchangeConstant;
import test.common.QueueConstant;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;
/**
* 队列配置:队列、交换机、binding 初始化
*/
@Configuration
public class QueueConfig {
@Bean
public TopicExchange DeviceExchange() {
return new TopicExchange(ExchangeConstant.EXCHANGE_TEST);
}
@Bean
public Binding rewardBindingDevice() {
return BindingBuilder
.bind(rewardQueue())
.to(DeviceExchange())
.with(ExchangeConstant.EXCHANGE_KEY_TEST);
}
}
创建 mq配置类 RabbitMQConfig.java
package test.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;
/**
* mq配置类:序列化和反序列化、消息确认机制
*/
@Configuration
public class RabbitMQConfig implements RabbitListenerConfigurer {
/**
* 配置监听反序列化工具
* @param rabbitListenerEndpointRegistrar
*/
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) {
rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
}
@Bean
MessageHandlerMethodFactory messageHandlerMethodFactory(){
DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory();
messageHandlerMethodFactory.setMessageConverter(new MappingJackson2MessageConverter());
return messageHandlerMethodFactory;
}
/**
* 配置发送序列化工具
* @param connectionFactory
* @return
*/
//设置序列化工具,默认用的jdk的objectStream进行序列号--体积大
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(new Jackson2JsonMessageConverter());
return template;
}
}
}
yml配置
spring:
rabbitmq:
listener:
simple:
# 重试机制
retry:
enabled: true #是否开启消费者重试 默认开启并且无限重试
max-attempts: 3 #最大重试次数
initial-interval: 3000ms #重试间隔时间(单位毫秒)
max-interval: 600000ms #重试最大时间间隔(单位毫秒)
multiplier: 2 #间隔时间乘子,间隔时间*乘子=下一次的间隔时间,最大不能超过设置的最大间隔时间
使用
生产者
UserDTO userDTO = new UserDTO ();
userDTO.setUsername("test"); rabbitTemplate.convertAndSend(ExchangeConstant.EXCHANGE_TEST,ExchangeConstant.EXCHANGE_KEY_TEST,userDTO );
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
创建监听队列类 QueueConsumer.java
package test.consumer;
import test.common.userDTO;
import test.common.ExchangeConstant;
import test.common.QueueConstant;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
/**
* 监听队列
*/
@Slf4j
@Component
public class QueueConsumer {
@RabbitListener(queues = QueueConstant.RABBITMQ_TEST)
void listenOrder(Message message){
log.info(message.toString());
try {
switch (message.getMessageProperties().getReceivedRoutingKey())
{
case ExchangeConstant.EXCHANGE_KEY_TEST:
UserDTO userDTO = new ObjectMapper().readValue(message.getBody(),userDTO.class);
log.info(userDTO.toString);
break;
default:
break;
}
} catch (IOException e) {
log.error("反序列化失败",e);
}
}
}