Springboot整合RabbitMQ基础使用

Springboot整合RabbitMQ基础使用

  • 整合SpringBoot
    • 依赖引入及配置
  • MQ五种模式
    • 简单模式 一对一消费
        • 定义消费者
        • 定义生产者
        • 测试示例
    • Work queues工作队列(一对多)
        • 定义消费者
        • 定义生产者
        • 测试示例
    • Publish/Subscribe发布订阅模型
        • 定义消费者
        • 定义生产者
        • 测试示例
    • Routing路由模型
        • 定义消费者
        • 定义生产者
        • 测试示例
    • Topic 模式
        • 定义消费者
        • 定义生产者
        • 测试示例
    • 参考博文

整合SpringBoot

依赖引入及配置

  • pox.xml
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-amqpartifactId>
        dependency>
  • 配置文件
# RabbitMQ config
--- # RabbitMQ 配置
spring:
  rabbitmq:
    host: 124.222.127.157
    port: 5672
    username: test
    password: guest
    virtual-host: /

MQ五种模式

简单模式 一对一消费

一对一消费,只有一个消费者能接收到

定义消费者

/**
 * 基础队列 -- 消费者 一对一消费,只有一个消费者能接收到
 * */
@Component
@Slf4j
public class HolloWordListener {
    // @RabbitListener(queues = ("simple.queue")) // queues需手动先创建队列
    @RabbitListener(queuesToDeclare = @Queue("simple.queue"))  // queuesToDeclare 自动声明队列
    public void helloWordListener(String message) {
        log.info("监听到mq消息,消费者进行消费消息");
        log.info("message = " + message);
    }
}

定义生产者



    @Autowired
    private RabbitTemplate rabbitTemplate;
 
    /**
     * RabbitMQ 功能测试 简单模式
     *
     * 
     *     一个生产者,一个消费者
     * 
*/
@Log(title = "RabbitMQ功能测试", businessType = BusinessType.OTHER) @PostMapping("/simple") @ResponseBody public void testSimpleQueue() { String queueName = "simple.queue"; // 队列名称 String message = "heel,simple.queue"; // 要发送的消息 JSONObject jsonObject = new JSONObject(); jsonObject.set("orderCode", 20220901401L); jsonObject.set("finishDate", new Date()); jsonObject.set("workId", 111111L); log.info("向MQ队列:{}中写入消息:{}", queueName, jsonObject.toString()); rabbitTemplate.convertAndSend(queueName, jsonObject.toString()); }

测试示例

  • postman调用

Springboot整合RabbitMQ基础使用_第1张图片

  • 控制台输出
    Springboot整合RabbitMQ基础使用_第2张图片
向MQ队列:simple.queue中写入消息:{"workId":111111,"orderCode":20220901401,"finishDate":1663122121292}
监听到mq消息,消费者进行消费消息
message = {"workId":111111,"orderCode":20220901401,"finishDate":1663122121292}

Work queues工作队列(一对多)

多个消费者,你一个我一个分配消费消息,有预取机制,默认公平消费,可配置能者多劳模式,谁完成的快,谁多做一点

定义消费者


/**
 *
 * 2、Work queues工作队列
 * 多个消费者,你一个我一个分配消费消息,有预取机制,默认公平消费,可配置能者多劳模式,谁完成的快,谁多做一点
 *
 *
 * */
@Component
public class WoekWordListener {

    @RabbitListener(queuesToDeclare = @Queue("workQueue")) // queuesToDeclare 自动声明队列
    public void holloWordListener(String message) throws InterruptedException {
        Thread.sleep(200);
        System.out.println("message1 = " + message);
    }

    @RabbitListener(queuesToDeclare = @Queue("workQueue")) // queuesToDeclare 自动声明队列
    public void holloWordListener1(String message) throws InterruptedException {
        Thread.sleep(400);
        System.out.println("message2 = " + message);
    }
}

定义生产者



    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    /**
     * RabbitMQ 功能测试 WorkQueue模式
     *
     * 
     *     一个生产者,多个消费者
     * 
*/
@Log(title = "RabbitMQ功能测试 WorkQueue模式", businessType = BusinessType.OTHER) @PostMapping("/work") @ResponseBody public void testWorkQueue() { String queueName = "workQueue"; String message = "hello,work.queue__"; for (int i = 0; i < 10; i++) { log.info("向MQ队列:{}中写入消息:{}", queueName, message + i); rabbitTemplate.convertAndSend(queueName, message + i); log.info("i = " + i); } }

测试示例

  • postman调用

Springboot整合RabbitMQ基础使用_第3张图片

  • 控制台输出

1.1生产者生产消息
Springboot整合RabbitMQ基础使用_第4张图片

 向MQ队列:workQueue中写入消息:hello,work.queue__0
 向MQ队列:workQueue中写入消息:hello,work.queue__1
 向MQ队列:workQueue中写入消息:hello,work.queue__2
 向MQ队列:workQueue中写入消息:hello,work.queue__3
 向MQ队列:workQueue中写入消息:hello,work.queue__4
 向MQ队列:workQueue中写入消息:hello,work.queue__5
 向MQ队列:workQueue中写入消息:hello,work.queue__6
 向MQ队列:workQueue中写入消息:hello,work.queue__7
 向MQ队列:workQueue中写入消息:hello,work.queue__8
 向MQ队列:workQueue中写入消息:hello,work.queue__9

1.2消费者消费消息
Springboot整合RabbitMQ基础使用_第5张图片

监听到MQ消息,work1消费消息 message1 = hello,work.queue__0
监听到MQ消息,work2消费消息 message2 = hello,work.queue__1
监听到MQ消息,work1消费消息 message1 = hello,work.queue__2
监听到MQ消息,work1消费消息 message1 = hello,work.queue__4
监听到MQ消息,work2消费消息 message2 = hello,work.queue__3
监听到MQ消息,work1消费消息 message1 = hello,work.queue__6
监听到MQ消息,work1消费消息 message1 = hello,work.queue__8
监听到MQ消息,work2消费消息 message2 = hello,work.queue__5
监听到MQ消息,work2消费消息 message2 = hello,work.queue__7
监听到MQ消息,work2消费消息 message2 = hello,work.queue__9

Publish/Subscribe发布订阅模型

发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者。

实现方式是加入了exchange(交换机),
注意:交换机是不缓存消息的

定义消费者

// 消费者直接绑定交换机,指定类型为fanout
@Component
@Slf4j
public class FanoutExchangeListener {
    // 不指定队列,消息过了就没了
    //  @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "fanoutTest",type = ExchangeTypes.FANOUT))})

    /** 指定队列,可以接收缓存到队列里的消息 */
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value ="test",durable = "true" ),exchange = @Exchange(value = "fanoutTest",type = ExchangeTypes.FANOUT))})
    public void reveivel(String message){
        log.info("message1 = " + message);
    }

    @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "fanoutTest",type = ExchangeTypes.FANOUT))})
    public void reveivel2(String message){
        log.info("message2 = " + message);
    }
}


定义生产者

    /**
     * RabbitMQ 功能测试 发布-订阅模式 Publish/发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者
     * 
     *  发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者。
     *  实现方式是加入了exchange(交换机),注意:交换机是不缓存消息的
     *
     * 
*/
@Log(title = "RabbitMQ功能测试 发布-订阅模式", businessType = BusinessType.OTHER) @PostMapping("/publish") @ResponseBody public void testPublishQueue() { String exchangeName = "fanoutTest"; String routingKey = ""; String message = "hello,work.queue__"; log.info("向MQ队列 交换机名称:{} 中写入消息:{}", exchangeName, message); // 参数1:交换机名称 , 参数2routingKey,(fanout类型可不写) , 参数3,消息内容 rabbitTemplate.convertAndSend(exchangeName, routingKey, message); }

测试示例

  • postman调用
http://127.0.0.1:9091/app/mq/publish
  • 控制台输出
    Springboot整合RabbitMQ基础使用_第6张图片

Springboot整合RabbitMQ基础使用_第7张图片

Routing路由模型

routing模型也是将消息发送到交换机

使用的是Direct类型的交换机,会将接收到的消息根据规则路由到指定的Queue(队列),因此称为路由模式

定义消费者


/** 消费者直接绑定交换机,指定类型为direct,并指定key表示能消费的key */ 
@Component
public class RoutingExchangeListener {

    // 不指定队列,消息过了就没了
    //  @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "direstTest",type = ExchangeTypes.DIRECT),key = {"info","error"})})

    // 指定队列,可以接收缓存到队列里的消息
    // key = {"info","error"} 表示我能接收到routingKey为 info和error的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value ="test1",durable = "true" ),exchange = @Exchange(value = "direstTest",type = ExchangeTypes.DIRECT),key = {"info","error"})})
    public void receivel1(String message){
        System.out.println("message1 = " + message);
    }
    // key = {"error"} 表示我只能接收到routingKey为 error的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "direstTest",type = ExchangeTypes.DIRECT),key = {"error"})})
    public void receivel2(String message){
        System.out.println("message2 = " + message);
    }
}


定义生产者


	@Autowired
	private RabbitTemplate rabbitTemplate;
	
    /**
     * RabbitMQ 测试 路由模式 routing
     *
     * 
     *   routing模型也是将消息发送到交换机
     *   使用的是Direct类型的交换机,会将接收到的消息根据规则路由到指定的Queue(队列),因此称为路由模式
     * 
*/
@Log(title = "RabbitMQ功能测试 路由模式", businessType = BusinessType.OTHER) @PostMapping("/routing") @ResponseBody public void testRoutingQueue() { String exchangeName = "direstTest"; String routingInfoKey = "info"; String routingErrorKey = "error"; String messageInfo = "发送info的key的路由消息"; String messageError = "发送error的key的路由消息"; log.info("向MQ队列 routing模式 交换机名称:{} 中写入消息:{}", exchangeName, messageInfo); rabbitTemplate.convertAndSend(exchangeName, routingInfoKey, messageInfo); log.info("向MQ队列 routing模式 交换机名称:{} 中写入消息:{}", exchangeName, messageError); rabbitTemplate.convertAndSend(exchangeName, routingErrorKey, messageError); }

测试示例

  • postman调用
http://127.0.0.1:9091/app/mq/routing
  • 控制台输出

Springboot整合RabbitMQ基础使用_第8张图片

Topic 模式

topicExchange与directExchange类型,区别在于routingKey必须是多个单词的列表,并且以 . 分隔

*(代表通配符,任意一个字段)
#(号代表一个或多个字段)

定义消费者


    /**
     * RabbitMQ 测试 Topic模式
     */
    @Log(title = "RabbitMQ功能测试 Topic模式", businessType = BusinessType.OTHER)
    @PostMapping("/topic")
    @ResponseBody
    public void testTopicQueue() {
        String exchangeName = "topicList";
        String message1 = "topic路由消息,use.save";
        String message2 = "topic路由消息,order.select.getone";

        String routingKey1 = "user.save";
        String routingKey2 = "order.select.getone";

        log.info("向MQ队列 Topic模式 交换机名称:{} 中写入消息:{}", exchangeName, message1);
        rabbitTemplate.convertAndSend(exchangeName, routingKey1, message1);
        log.info("向MQ队列 Topic模式 交换机名称:{} 中写入消息:{}", exchangeName, message2);
        rabbitTemplate.convertAndSend(exchangeName, routingKey2, message2);
    }


定义生产者



@Autowired
private RabbitTemplate rabbitTemplate;

@Component
@Slf4j
public class TopicsExchangeListener {

    // 不指定队列,消息过了就没了
    //  @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(name = "topicList",type = ExchangeTypes.TOPIC),key = {"user.save","user.*"})})

    // 指定队列,可以接收缓存到队列里的消息
    // key = {"user.save","user.*"} 表示能消费 routingkey为  user.save 和 user.任意一个字符  的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value = "test2", durable = "true"), exchange = @Exchange(name = "topicList", type = ExchangeTypes.TOPIC), key = {"user.save", "user.*"})})
    public void recevicel1(String message) {
        log.info("message1 = " + message);
    }

    // key = {"order.#","user.*"} 表示能消费 routingkey为  order.一个或多个字符   和  user.任意一个字符  的消息
    @RabbitListener(bindings = {@QueueBinding(value = @Queue, exchange = @Exchange(name = "topicList", type = ExchangeTypes.TOPIC), key = {"order.#", "user.*"})})
    public void recevicel2(String message) {
        log.info("message2 = " + message);
    }
}

测试示例

  • postman调用
http://127.0.0.1:9091/app/mq/topic
  • 控制台输出
  • 生产者日志
    Springboot整合RabbitMQ基础使用_第9张图片
    消费者消费日志
    Springboot整合RabbitMQ基础使用_第10张图片

参考博文

rabbitmq详解
rabbitmq笔记(看完即入门)
消息队列作用(解耦、异步、削峰)图详解

你可能感兴趣的:(RabbitMQ,SpringBoot,Java,java,java-rabbitmq,rabbitmq)