SpringBoot mq快速上手

1.依赖

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2.示例代码

基础信息配置

java 复制代码
package com.example.demo.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {
    public static final String EXCHANGE = "boot-EXCHANGE";

    public static final String QUEUE = "boot-queue";

    public static final String routingKey = "*.black.*";
    @Bean
    public Queue bootQueue(){
        return QueueBuilder.durable(QUEUE).build();
    }
    @Bean
    public Exchange bootExchange(){
        return ExchangeBuilder.topicExchange(EXCHANGE).build();
    }
    @Bean
    public Binding binding(Queue bootQueue,Exchange bootExchange){
        return BindingBuilder.bind(bootQueue).to(bootExchange).with(routingKey).noargs();

    }
}

实例配置代码如上

实操代码如下:

java 复制代码
  rabbitTemplate.convertAndSend(EXCHANGE,"white.black.hello","nihao");
        System.out.println("消息发送成功");

mq确保生产者发送到交换机链路正常:

基本:

java 复制代码
  //设置回调(保证消息发到交换机上)
        channel.confirmSelect();
        //设置回调函数
        channel.addConfirmListener(new ConfirmListener() {
            @Override
            public void handleAck(long deliveryTag, boolean multiple) throws IOException {
                System.out.println("消息成功发送到交换机");
            }

            @Override
            public void handleNack(long deliveryTag, boolean multiple) throws IOException {
                System.out.println("消息没有发送到交换机,请重试");
            }
        });

SpringBoot

java 复制代码
 // publisher-confirm-type: correlated  # 新版本 spring配置
    rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {

            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if(ack){
                    System.out.println("消息成功发送到交换机");
                }
                else{
                    System.out.println("消息没有发送到交换机");
                }
            }
        });

该方法中的ack为true,或false代表如上,该方法会被异步调用,不会阻塞主方法,效率高,可以在这里记下来,记到数据库中,事后进行补充。。

交换机路由到队列正常

java 复制代码
//保证消息发到Queue
        channel.addReturnListener(new ReturnCallback() {
            @Override
            public void handle(Return returnMessage) {
                System.out.println("消息未发送到交换机,请进行相关处理");//111
            }
        });

该方法在路由队列失败时进行回调

java 复制代码
  // publisher-returns: true # 开启Return机制
 rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returned) {
                String msg = new String(returned.getMessage().getBody());
                System.out.println("msg路由队列失败,请进行补救操作"+msg);
            }
        });

该方法只会在队列路由失败时被调用,属于回调方法

设置队列持久化(不是指durable设置为true,是指mq重启后,队列依然有消息)

java 复制代码
  //设置消息持久化
        AMQP.BasicProperties prop =new AMQP.BasicProperties().builder()
                .deliveryMode(2)
                .build();
        //6.发送消息
        channel.basicPublish(Exchange,"",prop,"nihao".getBytes(StandardCharsets.UTF_8));

设置属性,并把这个属性带上,deliveryMode设置为2即可

java 复制代码
  rabbitTemplate.convertAndSend(EXCHANGE, "big.black.dog", "nihao", new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                return message;
            }
        });

springboot中,需要用 MessagePostProcessor里的message设置deleveryMode 并且设置为枚举类型的PERSISTENT类型,并且记得返回消息,不然无法设置队列类型为持久化

保证消息被消费者正常消费

java 复制代码
  //4.监听消息
        DefaultConsumer callback=new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
                    throws IOException {
                System.out.println("消费者1好收到消息"+new String(body,"utf-8"));
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
       channel.basicConsume(QUEUE,false,callback);

mq在原始代码的时候需要在消费者端设置自动ack为false来进行处理,并在方法里进行手动ack。

java 复制代码
  listener:
      simple:
        acknowledge-mode: manual #开启手动ACK
        prefetch: 10 #消费者一次拿走10个消息

配置如上

@Component
public class Consumer {
    @RabbitListener(queues = RabbitConfig.QUEUE)
    public void Consume(String msg, Channel channel, Message message) throws IOException {
        System.out.println("msg"+msg);
        System.out.println("标示符"+message.getMessageProperties().getCorrelationId());
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}

springboot需要在配置文件里设置值为manual,prefetch表示一次可以取走的消息

相关推荐
周末也要写八哥4 分钟前
线程的生命周期之“守护“线程
java·开发语言·jvm
乐之者v5 分钟前
地图技术后端开发的知识点
java
亦暖筑序11 分钟前
Java 8老系统AI工具接入:API包装成受控工具,只读优先+权限拦截
java·人工智能·aigc·企业架构·mcp协议
砍材农夫12 分钟前
物联网实战:Spring Boot + Netty 搭建 MQTT 统一接入层
java·网络·spring boot·后端·物联网·spring
写代码的小阿帆13 分钟前
英语四六级证书审核(SpringBoot+Dify+RPA)
java·spring boot
redaijufeng14 分钟前
我在C++中深入理解了继承,收获颇丰
java·c++·算法
摇滚侠15 分钟前
Spring 零基础入门到进阶 基于注解的声明式事务 65-70
数据库·mysql·spring
就叫_这个吧21 分钟前
HTML或JSP页面链接CSS,link标签没问题,但不显示样式问题解决
java·前端·css·html·intellij-idea·jsp
阿坤带你走近大数据26 分钟前
分别介绍下java主流的开发框架、设计模式与对应编程语言的高级特性
java·开发语言·设计模式
摇滚侠28 分钟前
Spring 零基础入门到进阶 基于 XML 的声明式事务 71
xml·数据库·spring