知识点记录-springboot集成rabbitmq
1. 修改pom.xml
<!-- 集成rabbitmq start-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- 集成rabbitmq end-->
2. 修改yml文件
#集成rabbitmq start
spring:
rabbitmq:
host: 地址
virtual-host: /mall
port: 5672
username: 用户
password: 密码
publisher-confirms: true #发送端 发送到交换机确认
publisher-returns: true #发送端 交换机发送到队列异常确认
template: #发送端
mandatory: true #发送端 手动确认用于publisher-confirms publisher-returns
listener: #接收端
simple:
acknowledge-mode: manual #接收端手动确认
concurrency: 1
max-concurrency: 16
retry:
enabled: true
type: simple #接收端类型
direct:
acknowledge-mode: manual #接收端手动确认
retry:
enabled: true
#集成rabbitmq end
3. 编写发送接收
@Configuration
public class DirectConfig {//使用direct交换机模式
@Bean
public DirectExchange directExchangeMessage() {
return new DirectExchange(RabbitMqConstants.DIRECT_EXCHANGE_MESSAGE_ORDER);
}
@Bean
public Queue queueMessage() {
return new Queue(RabbitMqConstants.QUEUE_MESSAGE_ORDER);
}
@Bean
public Binding bindingDirectExchangeMessage() {
return BindingBuilder.bind(queueMessage())
.to(directExchangeMessage())
.with(RabbitMqConstants.ROUTINGKEY_MESSAGE_ORDER);
}
}
@Configuration
public class RabbitConfig {
@Bean//发送端
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {//CachingConnectionFactory
RabbitTemplate template = new RabbitTemplate();
template.setConnectionFactory(connectionFactory);
//消息格式序列化
template.setMessageConverter(new Jackson2JsonMessageConverter());
return template;
}
@Bean //接收端
public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {//CachingConnectionFactory
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
//消息格式序列化
factory.setMessageConverter(new Jackson2JsonMessageConverter());
return factory;
}
}
@Component
@Slf4j
public class MessageProducer implements ConfirmCallback, ReturnCallback {
private RabbitTemplate rabbitTemplate;
@Autowired
public MessageProducer(RabbitTemplate rabbitTemplate) {
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(this);
rabbitTemplate.setReturnCallback(this);
this.rabbitTemplate = rabbitTemplate;
}
//发送消息
public void sendMessageEvent(String exchange, String routingKey, MessageEvent messageEvent) {
CorrelationData correlationData =
new CorrelationData(new Random().nextInt() + UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(
exchange, routingKey, messageEvent, correlationData);
}
//发送延迟消息
public void sendMessageEventDelay(String exchange, String routingKey, MessageEvent messageEvent, final long delayTimes) {
CorrelationData correlationData =
new CorrelationData(new Random().nextInt() + UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(
exchange, routingKey, messageEvent, message -> {
//给消息设置延迟毫秒值
message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
return message;
}, correlationData);
}
//消息到交换机回调
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
log.info(" 回调id:" + correlationData);
if (ack) {
log.info("消息发送消费");
} else {
log.info("消息发送失败:" + cause);
}
}
//交换机发送到队列异常回调,没有异常不回调
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
log.info("sender return success" + message.toString() + " replyCode=" + replyCode + " replyText=" + replyText
+ " exchange=" + exchange + " routingKey=" + routingKey);
}
}
@Component
@Slf4j
public class MessageReceiver {
//确认消息的方式有none、auto(默认)、manual
// auto方式: 没异常则确认
// 当抛出 AmqpRejectAndDontRequeueException 异常的时候,则消息会被拒绝,且 requeue = false(不重新入队列)
// 当抛出 ImmediateAcknowledgeAmqpException 异常,则消费者会被确认
// 别的异常,则消息会被拒绝,且 requeue = true, 则循环异常, 通过 setDefaultRequeueRejected(默认是true)去设置抛弃消息
// manual方式:须调用以下的某个方法,否则rmq不向此接收端发消息
// 确认 void basicAck(long deliveryTag, boolean multiple)
// deliveryTag: 消息标志
// multiple: false 确认此次的消费端ack true 确认所有消费端ack
//
// 确认否定消息 void basicNack(long deliveryTag, boolean multiple, boolean requeue)
// deliveryTag: 消息标志
// multiple: false 确认此次的消费端ack true 确认所有消费端ack
// requeue: true 否定的消息入队
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
//
// 确认拒掉消息 void basicReject(long deliveryTag, boolean multiple, boolean requeue)
// deliveryTag: 消息标志
// requeue: true 拒掉的消息入队
// channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
//
// 消息入队时默认在head位置,可确认消息再发送到尾部位置
@RabbitListener(
containerFactory = "rabbitListenerContainerFactory",
bindings = @QueueBinding(
value = @Queue(value = QUEUE_MESSAGE_ORDER, durable = "true", autoDelete = "false"),
exchange = @Exchange(
value = DIRECT_EXCHANGE_MESSAGE_ORDER,
durable = "true",
type = ExchangeTypes.DIRECT),
key = ROUTINGKEY_MESSAGE_ORDER))
@RabbitHandler
public void receiveQueueMessageOrderCancel(MessageEvent messageEvent, Channel channel, Message message) {
log.info("接收receiveQueueMessageOrderCancel队列消息 messageEvent=" + messageEvent);
handleQueueMessageOrderCancel(messageEvent, channel, message);
}
private void handleQueueMessageOrderCancel(MessageEvent messageEvent, Channel channel, Message message) {
try {
log.info("handleQueueMessageOrderCancel messageEvent" + messageEvent);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
log.error("handleQueueMessageOrderCancel fail " + e.getMessage());
e.printStackTrace();
}
}
}
博客介绍了Spring Boot中消息发送接收的配置步骤,包括修改pom.xml、修改yml文件,还展示了RabbitConfig配置类和MessageProducer组件类的代码,主要运用Java语言。
1384





