一条消息的旅程:RabbitMQ 学习与实践(四)

专栏:RabbitMQ 进阶之路

个人主页:手握风云

目录

[一、SpringBoot 整合 RabbitMQ](#一、SpringBoot 整合 RabbitMQ)

[1.1. 环境准备](#1.1. 环境准备)

二、四大常用模式

[2.1. Work Queue 工作队列模式](#2.1. Work Queue 工作队列模式)

[2.2. Publish/Subscribe 发布‑订阅](#2.2. Publish/Subscribe 发布‑订阅)

[2.3. Routing 路由模式](#2.3. Routing 路由模式)

[2.4. Topics 通配符模式](#2.4. Topics 通配符模式)


一、SpringBoot 整合 RabbitMQ

1.1. 环境准备

核心依赖:

XML 复制代码
<dependencies>
    <!-- RabbitMQ整合核心依赖 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-amqp</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-webmvc</artifactId>
	</dependency>

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-amqp-test</artifactId>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-webmvc-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

配置文件:

XML 复制代码
# 方式1:分字段配置
spring:
  rabbitmq:
    host: 公网 IP
    port: 5672
    username: yang
    password: study
    virtual-host: test

# 方式2:地址字符串简写
spring:
  rabbitmq:
    addresses: amqp://yang:study@公网 IP:5672/test

二、四大常用模式

2.1. Work Queue 工作队列模式

特点:同一个队列,多个消费者监听;一条消息只会被其中一个消费者消费,做任务分发。

  • 配置类声明队列
java 复制代码
package com.yang.rabbitmqspringboot.config;

import com.yang.rabbitmqspringboot.constants.Constants;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {
    @Bean("workQueue")
    public Queue workQueue() {
        // 构建持久化队列
        return QueueBuilder.durable(Constants.WORK_QUEUE).build();
    }
}
  • 生产者(Controller 发送消息)
java 复制代码
package com.yang.rabbitmqspringboot.controller;

import com.yang.rabbitmqspringboot.constants.Constants;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/producer")
public class ProducerController {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @RequestMapping("/work")
    public String work() {
        // 向默认交换机发送
        for (int i = 0; i < 10; i++) {
            rabbitTemplate.convertAndSend("", Constants.WORK_QUEUE, "hello spring amqp: work..." + i);
        }

        return "发送成功";
    }
}
  • 消费者,两个方法监听同一个队列,形成竞争消费
java 复制代码
package com.yang.rabbitmqspringboot.listener;

import com.rabbitmq.client.Channel;
import com.yang.rabbitmqspringboot.constants.Constants;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class WorkListener {
    @RabbitListener(queues = Constants.WORK_QUEUE)
    public void queueListener1(Message message, Channel channel) {
        System.out.println("Listener1 [" + Constants.WORK_QUEUE + "] 接收到消息" + message + ", channel: " + channel);
    }

    @RabbitListener(queues = Constants.WORK_QUEUE)
    public void queueListener2(Message message, Channel channel) {
        System.out.println("Listener2 [" + Constants.WORK_QUEUE + "] 接收到消息" + message + ", channel: " + channel);
    }
}

2.2. Publish/Subscribe 发布‑订阅

特点:fanout 交换机,忽略 routingKey;消息复制多份,所有绑定该交换机的队列全部收到一模一样的消息。

  • Config 配置:声明 2 个队列 + Fanout 交换机 + 两个 Binding 绑定
java 复制代码
@Bean("fanoutQueue1")
public Queue fanoutQueue1() {
    return QueueBuilder.durable(Constants.FANOUT_QUEUE1).build();
}

@Bean("fanoutQueue2")
public Queue fanoutQueue2() {
    return QueueBuilder.durable(Constants.FANOUT_QUEUE2).build();
}

@Bean("fanoutExchange")
public FanoutExchange fanoutExchange() {
    return ExchangeBuilder.fanoutExchange(Constants.FANOUT_EXCHANGE).durable(true).build();
}

@Bean("fanoutQueueBinding1")
public Binding fanoutQueueBinding1(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue1") Queue queue) {
    return BindingBuilder.bind(queue).to(fanoutExchange);
}

@Bean("fanoutQueueBinding2")
public Binding fanoutQueueBinding2(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue2") Queue queue) {
    return BindingBuilder.bind(queue).to(fanoutExchange);
}
  • 生产者发送消息:routingKey 传空字符串
java 复制代码
@RequestMapping("/fanout")
public String fanout() {
    rabbitTemplate.convertAndSend(Constants.FANOUT_EXCHANGE, "", "hello spring amqp: fanout...");
    return "发送成功";
}
  • 消费者:分别监听两个队列
java 复制代码
package com.yang.rabbitmqspringboot.listener;

import com.yang.rabbitmqspringboot.constants.Constants;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class FanoutListener {
    @RabbitListener(queues = Constants.FANOUT_QUEUE1)
    public void queueListener1(String message) {
        System.out.println("队列[" + Constants.FANOUT_QUEUE1 + "] 接收到消息:" + message);
    }

    @RabbitListener(queues = Constants.FANOUT_QUEUE2)
    public void queueListener2(String message) {
        System.out.println("队列[" + Constants.FANOUT_QUEUE2 + "] 接收到消息:" + message);
    }
}

2.3. Routing 路由模式

特点:direct交换机;routingKey 必须和 Binding 绑定的 key 完全相等,队列才接收消息。适合日志分级等定向分发。

  • Config 配置
java 复制代码
@Bean("directQueue1")
public Queue directQueue1() {
    return QueueBuilder.durable(Constants.DIRECT_QUEUE1).build();
}

@Bean("directQueue2")
public Queue directQueue2() {
    return QueueBuilder.durable(Constants.DIRECT_QUEUE2).build();
}

@Bean("directExchange")
public DirectExchange directExchange() {
    return ExchangeBuilder.directExchange(Constants.DIRECT_EXCHANGE).durable(true).build();
}

@Bean("directQueueBiding1")
public Binding directQueueBiding1(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue1") Queue queue) {
    return BindingBuilder.bind(queue).to(directExchange).with("orange");
}

@Bean("directQueueBiding2")
public Binding directQueueBiding2(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue) {
    return BindingBuilder.bind(queue).to(directExchange).with("black");
}

@Bean("directQueueBiding3")
public Binding directQueueBiding3(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue) {
    return BindingBuilder.bind(queue).to(directExchange).with("orange");
}
  • 生产者,routingKey 动态传入
java 复制代码
@RequestMapping("/direct/{routingKey}")
public String direct(@PathVariable("routingKey") String routingKey) {
    rabbitTemplate.convertAndSend(Constants.DIRECT_EXCHANGE, routingKey, "hello spring amqp: direct..." + routingKey);
    return "发送成功";
}
  • 消费者监听两个队列
java 复制代码
package com.yang.rabbitmqspringboot.listener;

import com.yang.rabbitmqspringboot.constants.Constants;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class DirectListener {
    @RabbitListener(queues = Constants.DIRECT_QUEUE1)
    public void queueListener1(String message) {
        System.out.println("队列[" + Constants.DIRECT_QUEUE1 + "] 接收到消息:" + message);
    }

    @RabbitListener(queues = Constants.DIRECT_QUEUE2)
    public void queueListener2(String message) {
        System.out.println("队列[" + Constants.DIRECT_QUEUE2 + "] 接收到消息:" + message);
    }
}

2.4. Topics 通配符模式

特点:topic交换机,支持通配符匹配。*:匹配一个单词(.分割);#:匹配0 个或者多个单词。

  • Config 配置
java 复制代码
@Bean("topicQueue1")
public Queue topicQueue1() {
    return QueueBuilder.durable(Constants.TOPIC_QUEUE1).build();
}

@Bean("topicQueue2")
public Queue topicQueue2() {
    return QueueBuilder.durable(Constants.TOPIC_QUEUE2).build();
}

@Bean("topicExchange")
public TopicExchange topicExchange() {
    return ExchangeBuilder.topicExchange(Constants.TOPIC_EXCHANGE).durable(true).build();
}

@Bean("topicQueueBinding1")
public Binding topicQueueBinding1(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue1") Queue queue) {
    return BindingBuilder.bind(queue).to(topicExchange).with("*.orange.*");
}

@Bean("topicQueueBinding2")
public Binding topicQueueBinding2(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue2") Queue queue){
    return BindingBuilder.bind(queue).to(topicExchange).with("*.*.rabbit");
}

@Bean("topicQueueBinding3")
public Binding topicQueueBinding3(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue2") Queue queue){
    return BindingBuilder.bind(queue).to(topicExchange).with("lazy.#");
}
  • 生产者
java 复制代码
@RequestMapping("/topic/{routingKey}")
public String topic(@PathVariable("routingKey") String routingKey) {
    rabbitTemplate.convertAndSend(Constants.TOPIC_EXCHANGE, routingKey, "hello spring amqp: topic..." + routingKey);
    return "发送成功";
}
  • 消费者
java 复制代码
package com.yang.rabbitmqspringboot.listener;

import com.yang.rabbitmqspringboot.constants.Constants;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class TopicListener {
    @RabbitListener(queues = Constants.TOPIC_QUEUE1)
    public void queueListener1(String message) {
        System.out.println("队列[" + Constants.TOPIC_QUEUE1 + "] 接收到消息:" + message);
    }

    @RabbitListener(queues = Constants.TOPIC_QUEUE2)
    public void queueListener2(String message) {
        System.out.println("队列[" + Constants.TOPIC_QUEUE2 + "] 接收到消息:" + message);
    }
}
相关推荐
行思理7 小时前
go语言学习难度及适合学习的人群
开发语言·学习·golang
楚山之石11 小时前
【Medical Image Analysis】深度学习医学图像合成综述:伪CT、合成MRI与合成PET的架构、性能与临床边界
图像处理·人工智能·学习·mr·mri
Li_RuiQi12 小时前
DAgger方法演进_独立学习笔记
笔记·学习·计算机视觉
SteveSenna15 小时前
aubo学习:realsense手眼标定
学习·机器人·视觉检测
Li_RuiQi16 小时前
DAgger与交互式模仿学习_ACT学习笔记
笔记·学习
Canmag 兴隆磁性17 小时前
回复磁导率 μ_R:永磁体在动态磁路中的关键参数
开发语言·学习·r语言·永磁材料·充磁·磁导率
lengxuenong17 小时前
区间覆盖问题 · 简明学习手册1
java·学习·算法
悟道书生17 小时前
若依 RBAC 权限控制学习笔记
java·网络·笔记·sql·学习·vue
Be for thing18 小时前
PyTorch自动求导Autograd详解|requires_grad、backward、grad、梯度清零
pytorch·学习·1024程序员节
小嘉丶学长18 小时前
Day08 · 字符串(二)
服务器·开发语言·python·学习·1024程序员节