SpringBoot引入Rabbitmq并调用微服务

1.打开Rabbitmq管理后台:http://192.168.204.128:15672/

创建交换机=》创建消息队列=》交换机绑定消息通道

1.1创建交换机(Exchanges)
  • Name:交换机名称(如 order.exchange)
  • Type:选择类型(direct/fanout/topic/headers)
  • Durability:是否持久化
  • Auto delete:是否自动删除
类型Routing Key匹配性能使用频率典型应用
Direct精确匹配最高点对点精确路由(如订单状态更新)
Fanout忽略广播通知(如日志分发)
Topic通配符匹配(*/#)最高灵活路由(如新闻分类)
Headers消息头匹配(非Routing Key)基于属性的复杂路由
x-delayed-message依赖底层交换机类型中低延迟任务(如订单超时取消)
x-local-random不适用(队列参数)集群负载均衡

补充说明:

  1. Direct Exchange:Routing Key必须完全匹配,如"order.paid"只能路由到绑定键为"order.paid"的队列
  2. Fanout Exchange:所有绑定队列都会收到消息,适合事件广播
  3. Topic Exchange:支持*(匹配一个词)和#(匹配零或多个词),如"news.*.sports"
  4. Headers Exchange:通过消息headers匹配,可设置x-match为all/any
  5. x-delayed-message:需设置x-delay头(毫秒),实际是插件模拟的延迟
  6. x-local-random:队列声明参数,使队列优先绑定到随机本地节点减少网络跳数
    在这里插入图片描述
1.2创建消息队列(Queues)
  • Name:队列名称(如 order.queue)
  • Type:选择类型(Default for virtual host/Classic/Quorum/Stream)
  • Durability:是否持久化(Durable/Transient)
类型特点性能使用频率典型应用场景
Default (Classic)基础队列类型,支持持久化和内存模式最高最高常规消息处理场景
Quorum基于Raft协议实现的高可用队列,支持数据复制金融交易、订单处理等关键业务
Stream高性能持久化日志,支持消息回溯和消费者组中高日志处理、事件溯源、大数据管道

详细说明:

  1. Classic队列

    • RabbitMQ默认的队列类型
    • 支持持久化(写入磁盘)和非持久化(内存)两种模式
    • 单节点部署时性能最佳
    • 适合:普通消息队列需求
  2. Quorum队列

    • 基于Raft共识算法
    • 自动数据复制(所有节点都有完整数据)
    • 牺牲部分性能换取高可靠性
    • 适合:支付系统、交易系统等不能丢失消息的场景
  3. Stream队列

    • 消息以追加日志形式存储
    • 支持消息回溯和重复消费
    • 消费者可以按需读取历史消息
    • 适合:日志收集、事件溯源、审计跟踪等场景

选择建议:

  • 需要最高性能 → Classic队列
  • 需要最高可靠性 → Quorum队列
  • 需要消息回溯/大量历史数据 → Stream队列
    在这里插入图片描述
1.3交换机绑定队列:一对一、一对多

在这里插入图片描述

2.pom.xml引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

3.application.properties参数配置

# 配置RabbitMQ连接
#spring.rabbitmq.addresses=192.168.204.128,192.168.204.128
# 管理后台:http://192.168.204.128:15672/
spring.rabbitmq.host=192.168.204.129
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456
# 消费者重试
spring.rabbitmq.listener.simple.retry.enabled=true
spring.rabbitmq.listener.simple.retry.max-attempts=3
spring.rabbitmq.listener.simple.retry.initial-interval=2000

4.创建配置文件

package com.lecher.testspring.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMQConfig {

    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setMessageConverter(jsonMessageConverter());
        return template;
    }

    // ========================== 监听器容器配置 ==========================

    /*@Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
            ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(jsonMessageConverter());
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);  // 手动ACK
        // 重试配置
        factory.setAdviceChain(
                RetryInterceptorBuilder.stateless()
                        .maxAttempts(3)  // 最大重试次数(包括首次)
                        .backOffOptions(1000, 2.0, 5000)  // 初始间隔、倍数、最大间隔
                        .build()
        );
        return factory;
    }*/

//    @Bean
//    public Exchange delayExchange() {
//        Map<String, Object> args = new HashMap<>(2);
//        //  x-delayed-type    声明 延迟交换机的类型为路由直连
//        args.put("x-delayed-type", "direct");
//        // 设置名字 交换机类型(延迟消息) 持久化 不自动删除
//        return new CustomExchange("test-delayed-exchange", "x-delayed-message", true, false, args);
//    }

}

5.RabbitMQ 消息队列工具类

package com.lecher.testspring.util;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;

/**
 * RabbitMQ 消息队列工具类
 * 提供通用消息发送方法,支持自动JSON序列化
 * 管理后台:http://192.168.204.128:15672/#/queues
 * 1.配置交换机
 * 2.配置队列
 * 3.将交换机和队列绑定
 * 时间交换机分发多个队列处理任务
 */
@Component
public class QueueUtil {

    private final static RabbitTemplate rabbitTemplate;

    static {

        rabbitTemplate = SpringUtil.getBean(RabbitTemplate.class);
    }

    //------------------ 基础发送方法 ------------------//

    /**
     * 发送消息到指定交换机和路由键
     * @param exchange   交换机名称
     * @param routingKey 路由键
     * @param message    消息对象(自动转JSON)
     */
    public static void send(String exchange, String routingKey, Object message) {
        rabbitTemplate.convertAndSend(exchange, routingKey, message);
    }

    /**
     * 发送消息到默认交换机(根据队列名直发)
     * @param queueName 队列名称
     * @param message   消息对象
     */
    public static void sendToQueue(String queueName, Object message) {
        rabbitTemplate.convertAndSend(queueName, message);
    }

    //------------------ 带消息属性的高级发送 ------------------//

    /**
     * 发送带Header属性的消息
     * @param exchange   交换机
     * @param routingKey 路由键
     * @param message    消息体
     * @param headers    自定义Header属性
     */
    public static void sendWithHeaders(String exchange, String routingKey, Object message,
                                Map<String, Object> headers) {
        Message amqpMessage = MessageBuilder
                .withBody(rabbitTemplate.getMessageConverter().toMessage(message, new MessageProperties()).getBody())
                .copyHeaders(headers)
                .build();
        rabbitTemplate.send(exchange, routingKey, amqpMessage);
    }

    //------------------ 延迟队列支持 ------------------//

    /**
     * 发送延迟消息到指定交换机和路由键(需RabbitMQ安装延迟消息插件并配置x-delayed-type交换机)
     * @param exchange    交换机名称
     * @param routingKey  路由键
     * @param message     消息对象(自动转JSON)
     * @param delaySecond 延迟时间(秒)
     */
    public static void sendWithDelay(String exchange, String routingKey, Object message, int delaySecond) {
        rabbitTemplate.convertAndSend(exchange, routingKey, message, messagePostProcessor -> {
            messagePostProcessor.getMessageProperties().setDelay(delaySecond*1000);
            return messagePostProcessor;
        });
    }

    //------------------ 消费者工具方法(需配合@RabbitListener使用) ------------------//

    /**
     * 通用消息处理模板(供消费者类继承)
     */
    public static abstract class MessageHandler<T> {

        /**
         * 消息处理逻辑(子类实现)
         * @param message 反序列化后的消息对象
         */
        protected abstract void handle(T message);

        /**
         * 统一异常处理
         */
        public void onError(Exception e, String rawMessage) {
            System.err.println("消息处理失败(父): " + rawMessage);
            e.printStackTrace();
        }
    }
}

6.发送消息

    /**
     * 发送消息队列
     * @param message
     * @return
     */
    @GetMapping("/sendMQ")
    public Result sendMQ(@RequestParam String message){
        DictionaryVo dictionaryVo = new DictionaryVo();
        dictionaryVo.setName(message);
        dictionaryVo.setSlug("order.status");
        // 发送到指定交换机
        QueueUtil.send("order.exchange", "order.create", dictionaryVo);

        // 发送到指定队列
        QueueUtil.sendToQueue("order.queue", dictionaryVo);
//
//        // 发送带Header的消息
        Map<String, Object> headers = new HashMap<>();
        headers.put("priority", "high");
        QueueUtil.sendWithHeaders("order.exchange", "order.create", dictionaryVo, headers);
        return Result.success(StrUtil.format("消息队列:{}",message));
    }

7.监听队列中的数据

package com.lecher.testspring.handler;

import cn.hutool.json.JSONUtil;
import com.lecher.testspring.domain.vo.DictionaryVo;
import com.lecher.testspring.util.QueueUtil;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 监听队列中的数据
 */
@Component
public class OrderMessageConsumer extends QueueUtil.MessageHandler<DictionaryVo> {

    // 使用Spring原生注解监听队列
    @RabbitListener(queues = "order.queue")
    @Override
    public void handle(DictionaryVo message) {

        try {
            System.out.println("处理订单: " + message.getName());
            // 业务逻辑...
            throw new RuntimeException(JSONUtil.toJsonStr(message));
        }catch (Exception e){
            onError(e,JSONUtil.toJsonStr(message));
        }

    }


    // 统一异常处理(可选覆盖)
//    @Override
//    public void onError(Exception e, String rawMessage) {
//        System.err.println("订单处理失败: " + rawMessage);
//        // 记录错误日志或重试逻辑
//    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咯拉咯啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值