SpringBoot整合RabbitMQ实现五种消息模型

本文详细介绍并演示了RabbitMQ中的七种消息模型:HelloWorld、Workqueues、Publish/Subscribe、Routing、Topics等,包括如何在Spring Boot项目中实现这些模型。
摘要由CSDN通过智能技术生成

一、什么是消息队列?

消息,可以理解为两个应用之间传递的数据,数据可以是基本数据类型,也可以是对象等。

消息队列,则是容器,生产者产生的消息存放在这个容器里面。

MQ的整个过程可以理解为生产者生产消息,然后放进消息队列,消费者从消息队列里面获取消息最后进行消费。

二、消息模型

目前RabbitMQ的官网上介绍共有7种模型,最后两种RPC和Publisher Confirms本篇文章暂不讲,这两种目前实际应用很少,接下来我会结合官网的解释进行介绍和整合SpringBoot。

在进行整合前需要先安装RabbitMQ,可以根据我之前的一篇文章进行安装:

RabbitMQ的安装教程

模型,即RabbitMQ提供7种不同的模式,这7种模式可以应用于不同的场景。

PS:关于RabbitMQ的作用我这里就不多讲了,相信看到我这篇文章之前也大致知道是做什么的,无非就是解耦、异步、削峰。

三、搭建SpringBoot项目

接下来就是熟悉的三部曲:导依赖、写配置、编代码

pom依赖:

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

application.yml:

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest

注意端口号5672不要写成15672,这两个端口都有不同的用处,我这里并没有写错,把host改成自己安装RabbitMQ的服务器ip。

四、Hello World! 模型

Hello World模型也称点对点模型,也是最简单的模型,从图中很明显,P为生产者,红框为消息队列,C为消费者,生产者往消息队列发送消息,消费者从消息队列取消息。

接下来我们就以controller当成生产者,调用接口之后把一条文本消息放进消息队列,消费者自动从消息队列取消息。这时候就有疑问了,为什么它能自动取消息进行消费?因为它本质上是一个监听器,一旦有消息产生,那么就会被它监听到。

生产者:

    @Autowired
    private RabbitTemplate rabbitTemplate; 

    /**
	 * Hello World模型(点对点消费)
	 * @return
	 */
	@GetMapping("/helloworld")
    public String helloworld() {
    	//第一个参数:发送的队列名称 
		//第二个参数:发送的信息内容
        rabbitTemplate.convertAndSend("hello","hello world!!");
        return "helloworld---发送消息成功";
    }

消费者HelloConsumer:

package com.chen.consumers;

import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queuesToDeclare = @Queue("hello")) // 声明队列名称为hello
public class HelloConsumer {
	
	@RabbitHandler
    public void receivel(String message) {
        System.out.println("消费消息---"+message);
    }

}

结果:

消费消息---hello world!!

五、Work queues 模型

work queues 模型,创建一个工作队列,用于在多个工作者之间分配耗时的任务。也就是说,多个消费者可以消费同一个消息队列里面的消息,并且是通过轮询的形式,比如说有1,2,3,4这四个消息,按这个模型平均分配的原则,C1和C2分别可以消费两条消息,且都是按顺序的,如:C1消费1和3,C2消费2和4。

生产者:

    /**
	 * work queues模型
	 * @return
	 */
	@GetMapping("/workqueue")
	public String workqueue() {
		for (int i = 0; i < 10; i++) {
            rabbitTemplate.convertAndSend("work", "hello world!!"+i);
        }
		return "workqueue---发送消息成功";
	}

消费者WorkConsumer:

package com.chen.consumers;

import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class WorkConsumer {

	@RabbitListener(queuesToDeclare = @Queue("work"))
	public void receivel(String message) {
		System.out.println("消费者1  :" + message);
	}

	@RabbitListener(queuesToDeclare = @Queue("work"))
	public void receivel2(String message) {
		System.out.println("消费者2  :" + message);
	}

}

结果:

消费者2  :hello world!!1
消费者1  :hello world!!0
消费者1  :hello world!!2
消费者2  :hello world!!3
消费者1  :hello world!!4
消费者2  :hello world!!5
消费者1  :hello world!!6
消费者2  :hello world!!7
消费者1  :hello world!!8
消费者2  :hello world!!9

 六、Publish/Subscribe 模型 

Publish/Subscribe 模型,也称发布-订阅模型或扇出模型,即多个消费者可以同时接收到消息并进行消费,如下图,X代表交换机,生产者只能向一个交换机发送消息,而交换机再把消息推送到消息队列。

生产者:

    /**
	 * Publish/Subscribe 模型
	 * @return
	 */
	@GetMapping("/fanout")
	public String fanout() {
		// 第一个参数代表模型类型,第二个参数代表路由键,第三个参数代表消息内容
		rabbitTemplate.convertAndSend("fanout", "","hello world!!");
		return "fanout---发送消息成功";
	}

消费者FanoutConsumer:

package com.chen.consumers;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.Exchange;

@Component
public class FanoutConsumer {

	@RabbitListener(bindings = { @QueueBinding(value = @Queue, // 声明临时队列
			exchange = @Exchange(value = "fanout", type = "fanout")) }) // value参数代表交换机名称,可以自定义命名,type参数代表模型类型
	public void receivel(String message) {
		System.out.println("C1  :" + message);
	}

	@RabbitListener(bindings = { @QueueBinding(value = @Queue, // 声明临时队列
			exchange = @Exchange(value = "fanout", type = "fanout")) })
	public void receivel2(String message) {
		System.out.println("C2  :" + message);
	}
}

结果:

C1  :hello world!!
C2  :hello world!!

七、Routing 模型

Routing 模型,也称直连模型,可以对消息指明路由键名称,消息队列绑定路由键名称,这样交换机就能根据路由键名称将消息匹配到相应的消息队列上。如下图,第一个消息队列能够接收路由键名称为“error”的消息,而第二个消息队列能够接收“info”,“error”,“warning”的消息。

生产者:

    /**
	 * Routing 模型
	 * @return
	 */
	@GetMapping("/routing")
	public String routing() {
		rabbitTemplate.convertAndSend("route", "info","hello world!!");
		return "routing---发送消息成功";
	}

消费者RoutingConsumer:

package com.chen.consumers;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.stereotype.Component;

@Component
public class RoutingConsumer {

	@RabbitListener(bindings = { @QueueBinding(value = @Queue, // 声明临时队列
			exchange = @Exchange(value = "route", type = "direct"), key = { "error" }) }) // key参数代表路由键名称
	public void receivel(String message) {
		System.out.println("C1  :" + message);
	}

	@RabbitListener(bindings = { @QueueBinding(value = @Queue, // 声明临时队列
			exchange = @Exchange(value = "route", type = "direct"), key = { "error", "info" }) })
	public void receivel2(String message) {
		System.out.println("C2  :" + message);
	}

}

结果:

C2  :hello world!!

 八、Topics 模型

Topics 模型,也称主题模型,在Routing原有模型的基础上进行了增强,可以使用通配符的形式来匹配路由键。

.* 代表可以匹配一个字符

.# 代表可以匹配多个字符

生产者:

    /**
	 * Topics 模型
	 * @return
	 */
	@GetMapping("/topic")
	public String topic() {
		rabbitTemplate.convertAndSend("topic", "order.save","hello world!!");
		return "topic---发送消息成功";
	}

 消费者TopicConsumer:

package com.chen.consumers;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.Exchange;

@Component
public class TopicConsumer {

	@RabbitListener(bindings = { @QueueBinding(value = @Queue, // 声明临时队列
			exchange = @Exchange(value = "topic", type = "topic"), key = { "order.*" }) })
	public void receivel(String message) {
		System.out.println("C1  :" + message);
	}

	@RabbitListener(bindings = { @QueueBinding(value = @Queue, // 声明临时队列
			exchange = @Exchange(value = "topic", type = "topic"), key = { "order.#" }) })
	public void receivel2(String message) {
		System.out.println("C2  :" + message);
	}

}

结果:

C2  :hello world!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

西瓜不甜柠檬不酸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值